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; sascha@262: gernotbelger@9520: import java.util.Iterator; gernotbelger@9520: import java.util.List; sascha@262: ingo@1367: import org.apache.log4j.Logger; teichmann@5835: import org.dive4elements.artifacts.common.ArtifactNamespaceContext; teichmann@5835: import org.dive4elements.artifacts.common.utils.XMLUtils; teichmann@5835: import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException; teichmann@5835: import org.dive4elements.artifacts.httpclient.http.HttpClient; teichmann@5835: import org.dive4elements.artifacts.httpclient.http.HttpClientImpl; gernotbelger@9520: import org.dive4elements.river.client.client.services.MetaDataService; gernotbelger@9520: import org.dive4elements.river.client.server.auth.User; gernotbelger@9520: import org.dive4elements.river.client.server.meta.Converter; gernotbelger@9520: import org.dive4elements.river.client.shared.exceptions.ServerException; teichmann@7465: import org.dive4elements.river.client.shared.model.AttrList; teichmann@7465: import org.dive4elements.river.client.shared.model.DataCageNode; teichmann@5835: import org.dive4elements.river.client.shared.model.DataCageTree; gernotbelger@9520: import org.w3c.dom.Document; gernotbelger@9520: import org.w3c.dom.Element; sascha@286: felix@3346: /** felix@3346: * Service that returns certain meta-data from the backends data, polished to felix@3346: * inclusion into current project. felix@3346: */ gernotbelger@9520: public class MetaDataServiceImpl extends RemoteServiceServlet implements MetaDataService { ingo@1367: gernotbelger@9520: private static final long serialVersionUID = 1L; felix@3346: gernotbelger@9520: /** Our very own log. */ gernotbelger@9520: private static final Logger log = Logger.getLogger(MetaDataServiceImpl.class); gernotbelger@9520: gernotbelger@9520: private static final String ERROR_NO_META_DATA_FOUND = "error_no_meta_data_found"; gernotbelger@9520: gernotbelger@9520: private static final class Prune { gernotbelger@9520: private final User user; gernotbelger@9520: gernotbelger@9520: public Prune(final User user) { gernotbelger@9520: this.user = user; gernotbelger@9520: } gernotbelger@9520: gernotbelger@9520: void execute(final DataCageTree tree) { gernotbelger@9520: gernotbelger@9520: final DataCageNode root = tree.getRoot(); gernotbelger@9520: gernotbelger@9520: if (root == null || !root.hasChildren()) gernotbelger@9520: return; gernotbelger@9520: gernotbelger@9520: recursivePrune(root); gernotbelger@9520: } gernotbelger@9520: gernotbelger@9520: private boolean recursivePrune(final DataCageNode node) { gernotbelger@9520: gernotbelger@9520: /* filter by user - features */ gernotbelger@9520: if (!acceptUserFeatures(node)) gernotbelger@9520: return false; gernotbelger@9520: gernotbelger@9520: /* recursively check all leafs, we only accepts real ones that have a factory */ gernotbelger@9520: if (!node.hasChildren()) gernotbelger@9520: return acceptLeaf(node); gernotbelger@9520: gernotbelger@9520: final List children = node.getChildren(); gernotbelger@9520: gernotbelger@9520: for (final Iterator iterator = children.iterator(); iterator.hasNext();) { gernotbelger@9520: final DataCageNode dataCageNode = iterator.next(); gernotbelger@9520: gernotbelger@9520: if (!recursivePrune(dataCageNode)) gernotbelger@9520: iterator.remove(); gernotbelger@9520: } gernotbelger@9520: gernotbelger@9520: return !children.isEmpty(); gernotbelger@9520: } gernotbelger@9520: gernotbelger@9520: private boolean acceptUserFeatures(final DataCageNode node) { gernotbelger@9520: final AttrList al = node.getAttributes(); gernotbelger@9520: if (al == null) gernotbelger@9520: return true; gernotbelger@9520: gernotbelger@9520: final String module = al.getValue("module"); gernotbelger@9520: if (module == null) gernotbelger@9520: return true; gernotbelger@9520: gernotbelger@9520: if (this.user == null || this.user.canUseFeature("module:" + module)) gernotbelger@9520: return true; gernotbelger@9520: gernotbelger@9520: return false; gernotbelger@9520: } gernotbelger@9520: gernotbelger@9520: private boolean acceptLeaf(final DataCageNode node) { gernotbelger@9520: final AttrList al = node.getAttributes(); gernotbelger@9520: if (al == null) gernotbelger@9520: return false; gernotbelger@9520: gernotbelger@9520: return al.hasAttribute("factory"); gernotbelger@9520: } teichmann@7465: } teichmann@7465: felix@3346: /** gernotbelger@9520: * @param locale gernotbelger@9520: * needed for i18n. gernotbelger@9520: * @param artifactId gernotbelger@9520: * ID of masterartifact (can be null) gernotbelger@9520: * @param userId gernotbelger@9520: * can be null gernotbelger@9520: * @param outs gernotbelger@9520: * can be null gernotbelger@9520: * @param parameters gernotbelger@9520: * can be null or parameters like gernotbelger@9520: * "load-system:true;key:value" felix@3346: */ sascha@827: @Override gernotbelger@9520: public DataCageTree getMetaData(final String locale, final String artifactId, final String userId, final String outs, final String parameters) gernotbelger@9520: throws ServerException { teichmann@8203: log.info("MetaDataService.getMetaData"); sascha@276: felix@1442: // Create the query document. gernotbelger@9520: final String url = getServletContext().getInitParameter("server-url"); sascha@276: gernotbelger@9520: final Document doc = XMLUtils.newDocument(); sascha@276: gernotbelger@9520: final XMLUtils.ElementCreator ec = new XMLUtils.ElementCreator(doc, ArtifactNamespaceContext.NAMESPACE_URI, ArtifactNamespaceContext.NAMESPACE_PREFIX); gernotbelger@9520: gernotbelger@9520: final Element meta = ec.create("meta"); sascha@276: sascha@811: if (artifactId != null) { gernotbelger@9520: final Element artifactEl = ec.create("artifact-id"); sascha@811: artifactEl.setAttribute("value", artifactId); sascha@812: meta.appendChild(artifactEl); sascha@811: } sascha@276: sascha@811: if (userId != null) { gernotbelger@9520: final Element userEl = ec.create("user-id"); sascha@811: userEl.setAttribute("value", userId); sascha@812: meta.appendChild(userEl); sascha@811: } sascha@276: sascha@827: if (outs != null) { gernotbelger@9520: final Element outsEl = ec.create("outs"); sascha@827: outsEl.setAttribute("value", outs); sascha@827: meta.appendChild(outsEl); sascha@827: } sascha@827: ingo@916: if (parameters != null) { gernotbelger@9520: final Element paramsEl = ec.create("parameters"); ingo@916: paramsEl.setAttribute("value", parameters); ingo@916: meta.appendChild(paramsEl); ingo@916: } ingo@916: sascha@812: doc.appendChild(meta); sascha@812: felix@1442: // Fire. gernotbelger@9520: final HttpClient client = new HttpClientImpl(url, locale); sascha@276: sascha@276: try { gernotbelger@9520: final User user = getUser(); gernotbelger@9520: gernotbelger@9520: final Converter converter = new Converter(); gernotbelger@9520: final DataCageTree tree = converter.convert(client.callService(url, "metadata", doc)); gernotbelger@9520: gernotbelger@9520: new Prune(user).execute(tree); gernotbelger@9520: teichmann@7465: return tree; sascha@276: } gernotbelger@9520: catch (final ConnectionException ce) { sascha@812: ce.printStackTrace(); sascha@276: } sascha@276: sascha@276: throw new ServerException(ERROR_NO_META_DATA_FOUND); sascha@262: } gernotbelger@9520: }