view flys-client/src/main/java/de/intevation/flys/client/server/DescribeCollectionServiceImpl.java @ 548:aff225e07720

Repaired broken zoom-out control. flys-client/trunk@2058 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Mon, 06 Jun 2011 11:56:15 +0000
parents ba238f917b94
children 5277f46a63c2
line wrap: on
line source
package de.intevation.flys.client.server;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.xpath.XPathConstants;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import de.intevation.artifacts.common.ArtifactNamespaceContext;
import de.intevation.artifacts.common.utils.ClientProtocolUtils;
import de.intevation.artifacts.common.utils.XMLUtils;

import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
import de.intevation.artifacts.httpclient.http.HttpClient;
import de.intevation.artifacts.httpclient.http.HttpClientImpl;
import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler;

import de.intevation.flys.client.shared.exceptions.ServerException;
import de.intevation.flys.client.shared.model.Collection;
import de.intevation.flys.client.shared.model.CollectionItem;
import de.intevation.flys.client.shared.model.DefaultCollection;
import de.intevation.flys.client.shared.model.DefaultCollectionItem;
import de.intevation.flys.client.shared.model.DefaultFacet;
import de.intevation.flys.client.shared.model.DefaultOutputMode;
import de.intevation.flys.client.shared.model.DefaultTheme;
import de.intevation.flys.client.shared.model.ExportMode;
import de.intevation.flys.client.shared.model.Facet;
import de.intevation.flys.client.shared.model.OutputMode;
import de.intevation.flys.client.shared.model.Theme;
import de.intevation.flys.client.shared.model.ThemeList;
import de.intevation.flys.client.client.services.DescribeCollectionService;


/**
 * This service implements a method that queries the DESCRIBE document of a
 * specific collection and returns a Collection object with the information of
 * the document.
 *
 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
 */
public class DescribeCollectionServiceImpl
extends      RemoteServiceServlet
implements   DescribeCollectionService
{
    /** The error message key that is thrown if an error occured while
     * describe() a Collection.*/
    public static final String ERROR_DESCRIBE_COLLECTION =
        "error_describe_collection";

    public static final String XPATH_FACETS = "art:facets/art:facet";


    public Collection describe(String uuid, String serverUrl, String locale)
    throws ServerException
    {
        System.out.println("DescribeCollectionServiceImpl.describe");

        Document describe = ClientProtocolUtils.newDescribeCollectionDocument(
            uuid);

        HttpClient client = new HttpClientImpl(serverUrl, locale);

        try {
            Document response = (Document) client.doCollectionAction(
                describe, uuid, new DocumentResponseHandler());

            Collection c = parseCollection(response);

            if (c == null) {
                throw new ServerException(ERROR_DESCRIBE_COLLECTION);
            }

            System.out.println("Collection successfully parsed.");

            return c;
        }
        catch (ConnectionException ce) {
            System.err.println(ce.getLocalizedMessage());
        }

        throw new ServerException(ERROR_DESCRIBE_COLLECTION);
    }


    /**
     * This method takes the DESCRIBE document of the Collections describe()
     * operation and extracts the information about the collection itself and
     * the collection items.
     *
     * @param description The DESCRIBE document of the Collections describe()
     * operation.
     *
     * @return a Collection with CollectionItems.
     */
    protected Collection parseCollection(Document description) {
        System.out.println("AddArtifactServiceImpl.parseCollection");

        if (description == null) {
            System.err.println("The DESCRIBE of the Collection is null!");
            return null;
        }

        String uuid = XMLUtils.xpathString(
            description,
            "art:artifact-collection/@art:uuid",
            ArtifactNamespaceContext.INSTANCE);

        if (uuid == null || uuid.equals("")) {
            System.err.println("Found an invalid Collection!");
            return null;
        }

        Map<String, ThemeList> themeList = parseThemeLists(description);

        Collection c = null;

        if (themeList != null) {
            c = new DefaultCollection(uuid, themeList);
            //c = new DefaultCollection(uuid);
        }
        else {
            c = new DefaultCollection(uuid);
        }

        NodeList items = (NodeList) XMLUtils.xpath(
            description,
            "art:artifact-collection/art:artifacts/art:artifact",
            XPathConstants.NODESET,
            ArtifactNamespaceContext.INSTANCE);

        if (items == null || items.getLength() == 0) {
            System.out.println("No collection item found for this collection.");

            return c;
        }

        int size = items.getLength();

        for (int i = 0; i < size; i++) {
            CollectionItem item = parseCollectionItem(items.item(i));

            if (item != null) {
                c.addItem(item);
            }
        }

        System.out.println(
            "Found " + c.getItemLength() + " collection items " +
            "for the Collection '" + c.identifier() + "'.");

        return c;
    }


    protected Map<String, ThemeList> parseThemeLists(Document description) {
        System.out.println("DescribeCollectionServiceImpl.parseThemeLists");

        NodeList lists = (NodeList) XMLUtils.xpath(
            description,
            "/art:artifact-collection/art:attribute/art:outputs/art:output",
            XPathConstants.NODESET,
            ArtifactNamespaceContext.INSTANCE);

        int num = lists != null ? lists.getLength() : 0;

        Map<String, ThemeList> themeList = new HashMap<String, ThemeList>(num);

        for (int i = 0; i < num; i++) {
            Node node = lists.item(i);

            String outName = XMLUtils.xpathString(
                node, "@name", ArtifactNamespaceContext.INSTANCE);

            ThemeList list = parseThemeList(node);

            if (list != null) {
                themeList.put(outName, list);
            }
        }

        return themeList;
    }


    protected ThemeList parseThemeList(Node node) {
        System.out.println("DescribeCollectionServiceImpl.parseThemeList");

        NodeList themes = (NodeList) XMLUtils.xpath(
            node,
            "art:theme",
            XPathConstants.NODESET,
            ArtifactNamespaceContext.INSTANCE);

        int num = themes != null ? themes.getLength() : 0;

        List<Theme> themeList = new ArrayList<Theme>(num);

        for (int i = 0; i < num; i++) {
            Theme theme = parseTheme(themes.item(i));

            if (theme != null) {
                themeList.add(theme);
            }
        }

        return new ThemeList(themeList);
    }


    protected Theme parseTheme(Node node) {
        System.out.println("DescribeCollectionServiceImpl.parseTheme");

        String strAct = XMLUtils.xpathString(
            node, "@art:active", ArtifactNamespaceContext.INSTANCE);

        String art = XMLUtils.xpathString(
            node, "@art:artifact", ArtifactNamespaceContext.INSTANCE);

        String fac = XMLUtils.xpathString(
            node, "@art:facet", ArtifactNamespaceContext.INSTANCE);

        String strPos = XMLUtils.xpathString(
            node, "@art:pos", ArtifactNamespaceContext.INSTANCE);

        if (strAct != null && art != null && fac != null && strPos != null) {
            try {
                int pos    = Integer.valueOf(strPos);
                int active = Integer.valueOf(strAct);

                return new DefaultTheme(pos, active > 0, art, fac);
            }
            catch (NumberFormatException nfe) {
                nfe.printStackTrace();
            }
        }

        return null;
    }


    /**
     * This method extracts the CollectionItem from <i>node</i> with its output
     * modes. The output modes are parsed using the parseOutputModes() method.
     *
     * @param node A node that contains information about a CollectionItem.
     *
     * @return a CollectionItem.
     */
    protected CollectionItem parseCollectionItem(Node node) {
        System.out.println("AddArtifactServiceImpl.parseCollectionItem");

        if (node == null) {
            System.err.println("The node for parsing CollectionItem is null!");
            return null;
        }

        String uuid = XMLUtils.xpathString(
            node, "@art:uuid", ArtifactNamespaceContext.INSTANCE);

        String hash = XMLUtils.xpathString(
            node, "@art:hash", ArtifactNamespaceContext.INSTANCE);

        if (uuid == null || uuid.equals("")) {
            System.err.println("Found an invalid CollectionItem!");
        }

        Node outputmodes = (Node) XMLUtils.xpath(
            node,
            "art:outputmodes",
            XPathConstants.NODE,
            ArtifactNamespaceContext.INSTANCE);

        List<OutputMode> modes = parseOutputModes(outputmodes);

        return new DefaultCollectionItem(uuid, hash, modes);
    }


    /**
     * This method extracts the OutputModes available for a specific
     * CollectionItem and returns them as list.
     *
     * @param node The root node of the outputmodes list.
     *
     * @return a list of OutputModes.
     */
    protected List<OutputMode> parseOutputModes(Node node) {
        System.out.println("AddArtifactServiceImpl.parseOutputModes");

        if (node == null) {
            System.err.println("The node for parsing OutputModes is null!");
            return null;
        }

        NodeList list = (NodeList) XMLUtils.xpath(
            node,
            "art:output",
            XPathConstants.NODESET,
            ArtifactNamespaceContext.INSTANCE);

        if (list == null || list.getLength() == 0) {
            System.err.println("No outputmode nodes found!");
            return null;
        }

        int size = list.getLength();

        List<OutputMode> modes = new ArrayList<OutputMode>(size);

        for (int i = 0; i < size; i++) {
            Node   tmp  = list.item(i);
            String name = XMLUtils.xpathString(
                tmp, "@art:name", ArtifactNamespaceContext.INSTANCE);
            String desc = XMLUtils.xpathString(
                tmp, "@art:description", ArtifactNamespaceContext.INSTANCE);
            String mime = XMLUtils.xpathString(
                tmp, "@art:mime-type", ArtifactNamespaceContext.INSTANCE);

            if (name == null || name.equals("")) {
                System.err.println("Found an invalid output mode.");

                continue;
            }

            OutputMode outmode = null;
            List<Facet> fs     = extractFacets(tmp);

            if (name.indexOf("export") > -1) {
                outmode = new ExportMode(name, desc, mime, fs);
            }
            else {
                outmode = new DefaultOutputMode(name, desc, mime, fs);
            }

            modes.add(outmode);
        }

        return modes;
    }


    protected static List<Facet> extractFacets(Node outmode) {
        System.out.println("ArtifactDescriptionFactory - extractFacets()");

        NodeList facetList = (NodeList) XMLUtils.xpath(
            outmode,
            XPATH_FACETS,
            XPathConstants.NODESET,
            ArtifactNamespaceContext.INSTANCE);

        int num = facetList != null ? facetList.getLength() : 0;

        List<Facet> facets = new ArrayList<Facet>(num);

        for (int i = 0; i < num; i++) {
            Node facetNode = facetList.item(i);

            String name = XMLUtils.xpathString(
                facetNode, "@art:name", ArtifactNamespaceContext.INSTANCE);

            if (name != null && name.length() > 0) {
                facets.add(new DefaultFacet(name));
            }
        }

        return facets;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org