view flys-client/src/main/java/de/intevation/flys/client/server/CollectionItemAttributeServiceImpl.java @ 5779:ebec12def170

Datacage: Add a pool of builders to make it multi threadable. XML DOM is not thread safe. Therefore the old implementation only allowed one thread to use the builder at a time. As the complexity of the configuration has increased over time this has become a bottleneck of the whole application because it took quiet some time to build a result. Furthermore the builder code path is visited very frequent. So many concurrent requests were piled up resulting in long waits for the users. To mitigate this problem a round robin pool of builders is used now. Each of the pooled builders has an independent copy of the XML template and can be run in parallel. The number of builders is determined by the system property 'flys.datacage.pool.size'. It defaults to 4.
author Sascha L. Teichmann <teichmann@intevation.de>
date Sun, 21 Apr 2013 12:48:09 +0200
parents b296d435fc69
children
line wrap: on
line source
package de.intevation.flys.client.server;

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

import org.apache.log4j.Logger;

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

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.artifacts.common.ArtifactNamespaceContext;
import de.intevation.artifacts.common.utils.XMLUtils;

import de.intevation.flys.client.shared.exceptions.ServerException;
import de.intevation.flys.client.client.services.CollectionItemAttributeService;

import de.intevation.flys.client.shared.model.Collection;
import de.intevation.flys.client.shared.model.CollectionItemAttribute;
import de.intevation.flys.client.shared.model.Style;
import de.intevation.flys.client.shared.model.StyleSetting;


/**
 * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
 */
public class CollectionItemAttributeServiceImpl
extends      RemoteServiceServlet
implements   CollectionItemAttributeService
{
    private static final Logger logger =
        Logger.getLogger(CollectionItemAttributeServiceImpl.class);


    public static final String XPATH_RESULT = "/art:result/text()";

    public static final String OPERATION_FAILURE = "FAILED";

    public static final String ERROR_NO_STYLES_FOUND =
        "error_no_theme_styles_found";


    public CollectionItemAttribute getCollectionItemAttribute(
        Collection collection,
        String artifact,
        String locale)
    throws ServerException
    {
        logger.info(
            "CollectionItemAttributeServiceImpl.getCollectionItemAttribute");

        String url  = getServletContext().getInitParameter("server-url");

        Document requestDoc = XMLUtils.newDocument();

        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
            requestDoc,
            ArtifactNamespaceContext.NAMESPACE_URI,
            ArtifactNamespaceContext.NAMESPACE_PREFIX);

        Element action = ec.create("action");

        Element type = ec.create("type");
        ec.addAttr(type, "name", "getitemattribute", false);

        Element art = ec.create("artifact");
        ec.addAttr(art, "uuid", artifact, false);

        type.appendChild(art);
        action.appendChild(type);
        requestDoc.appendChild (action);

        try {
            HttpClient client = new HttpClientImpl(url, locale);
            Document res = (Document) client.doCollectionAction(
                requestDoc,
                collection.identifier(),
                new DocumentResponseHandler());
            return readXML (res, artifact);
        }
        catch (ConnectionException ce) {
            logger.error(ce, ce);
        }

        throw new ServerException(ERROR_NO_STYLES_FOUND);
    }


    public void setCollectionItemAttribute(
        Collection collection,
        String artifact,
        String locale,
        CollectionItemAttribute attributes)
    throws ServerException
    {
        logger.info(
            "CollectionItemAttributeServiceImpl.setCollectionItemAttribute");

        String url  = getServletContext().getInitParameter("server-url");

        Document doc = writeXML(attributes, artifact);

        try {
            HttpClient client = new HttpClientImpl(url, locale);
            Document res = (Document) client.doCollectionAction(
                doc,
                collection.identifier(),
                new DocumentResponseHandler());

            return;
        }
        catch (ConnectionException ce) {
            logger.error(ce, ce);
            throw new ServerException(ce.getLocalizedMessage());
        }
    }

    protected CollectionItemAttribute readXML(Document doc, String artifact)
    throws    ServerException
    {
        CollectionItemAttribute cia = new CollectionItemAttribute();
        cia.setArtifact(artifact);

        Element root = doc.getDocumentElement();
        NodeList themes = root.getElementsByTagName("art:themes");

        if (themes == null || themes.getLength() == 0) {
            throw new ServerException(ERROR_NO_STYLES_FOUND);
        }

        Element e = (Element) themes.item(0);
        NodeList items = e.getElementsByTagName("theme");

        for (int i = 0; i < items.getLength(); i++) {
            Style s = StyleHelper.getStyle ((Element) items.item(i));
            if(s == null) {
                throw new ServerException(ERROR_NO_STYLES_FOUND);
            }
            else {
                cia.appendStyle(s);
            }
        }

        return cia;
    }


    protected Document writeXML (
        CollectionItemAttribute attributes,
        String artifact)
    {
        Document styles = XMLUtils.newDocument();

        XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(
                styles,
                ArtifactNamespaceContext.NAMESPACE_URI,
                ArtifactNamespaceContext.NAMESPACE_PREFIX);
        Element action = ec.create("action");
        Element type = ec.create("type");
        type.setAttribute("name", "setitemattribute");
        Element art = ec.create("artifact");
        art.setAttribute("uuid", artifact);
        Element attr = ec.create("attribute");
        Element themes = ec.create("themes");
        action.appendChild(type);
        type.appendChild(art);
        art.appendChild(attr);
        attr.appendChild(themes);

        XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
                styles,
                "",
                "");

        for (int i = 0; i < attributes.getNumStyles(); i++) {
            Style s = attributes.getStyle(i);
            Element theme = creator.create("theme");
            theme.setAttribute("name", s.getName());
            theme.setAttribute("facet", s.getFacet());
            theme.setAttribute("index", String.valueOf(s.getIndex()));
            for (int j = 0; j < s.getNumSettings(); j++) {
                StyleSetting set = s.getSetting(j);
                Element field = creator.create("field");
                field.setAttribute("name", set.getName());
                field.setAttribute("display", set.getDisplayName());
                field.setAttribute("default", set.getDefaultValue());
                field.setAttribute("hints", set.getHints());
                field.setAttribute("type", set.getType());
                field.setAttribute("hidden", String.valueOf(set.isHidden()));
                theme.appendChild(field);
            }
            themes.appendChild(theme);
        }
        styles.appendChild(action);
        return styles;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org