Package org.apache.marmotta.platform.ldpath.webservices

Source Code of org.apache.marmotta.platform.ldpath.webservices.LDPathUtilWebService

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.marmotta.platform.ldpath.webservices;

import static org.apache.marmotta.commons.sesame.repository.ExceptionUtils.handleRepositoryException;
import static org.apache.marmotta.commons.sesame.repository.ResourceUtils.listOutgoing;
import static org.apache.marmotta.commons.sesame.repository.ResourceUtils.listResourcesByPrefix;
import static org.apache.marmotta.commons.sesame.repository.ResultUtils.iterable;

import org.apache.marmotta.platform.ldpath.api.LDPathService;
import org.apache.marmotta.commons.sesame.model.Namespaces;
import org.apache.marmotta.commons.sesame.repository.ResourceUtils;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;

import org.apache.marmotta.platform.core.api.prefix.PrefixService;
import org.apache.marmotta.platform.core.api.triplestore.SesameService;
import org.apache.marmotta.platform.core.services.prefix.PrefixCC;
import org.apache.commons.lang3.StringUtils;
import org.apache.marmotta.commons.http.UriUtil;
import org.apache.marmotta.ldpath.api.functions.SelectorFunction;
import org.apache.marmotta.ldpath.backend.sesame.SesameConnectionBackend;
import org.apache.marmotta.ldpath.exception.LDPathParseException;
import org.openrdf.model.*;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;

import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;

import java.net.URISyntaxException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Path("/ldpath/util")
public class LDPathUtilWebService {

    private static final String FUNCTION_NAMESPACE = "function:ldpath#";

    private static final String FUNCTION_PREFIX = "fn";

    private static final String MODE_TRANSFORM = "transformer";

    private static final Pattern CURIE_PATTERN = Pattern.compile("(\\w+):(\\w*)");

    @Inject
    private SesameService sesameService;

    @Inject
    private LDPathService   ldPathService;

    @Inject
    private PrefixService   prefixService;

    @Inject
    private PrefixCC             prefixCC;

    @GET
    @Path("/namespaces")
    @Produces(Namespaces.MIME_TYPE_JSON)
    public Map<String, String> listKnownNamespaces(@Context UriInfo info) {
        final PrefixService prefixService = createLocalPrefixService(info);
        Map<String, String> nss = new HashMap<String, String>();

        try {
            RepositoryConnection con = sesameService.getConnection();
            try {
                con.begin();
                for (Namespace ns : iterable(con.getNamespaces())) {
                    nss.put(ns.getPrefix(), ns.getName());
                }
                // commit added
                con.commit();
            } finally {
                con.close();
            }

        } catch (RepositoryException e) {
            handleRepositoryException(e,LDPathUtilWebService.class);
        }

        for (Map.Entry<String, String> e : prefixService.getMappings().entrySet()) {
            nss.put(e.getKey(), e.getValue());
        }
        nss.put(FUNCTION_PREFIX, FUNCTION_NAMESPACE);
        return nss;
    }

    @GET
    @Path("/prefix")
    @Produces(Namespaces.MIME_TYPE_JSON)
    public Map<String, String> resolvePrefix(@QueryParam("prefix") String prefix, @Context UriInfo info) {
        final PrefixService prefixService = createLocalPrefixService(info);
        if (prefixService.containsPrefix(prefix))
            return Collections.singletonMap(prefix, prefixService.getNamespace(prefix));

        // As a fallback, try prefix.cc
        if (prefix != null) {
            final String namespace = prefixCC.getNamespace(prefix);
            if (namespace != null)
                return Collections.singletonMap(prefix, namespace);
        }
        return Collections.emptyMap();
    }

    @GET
    @Path("/complete")
    @Produces(Namespaces.MIME_TYPE_JSON)
    public List<String> complete(@QueryParam("prefix") String prefix, @QueryParam("uri") String uri,
            @QueryParam("mode") @DefaultValue("path") String mode, @Context UriInfo info) {
        final int limit = 20;
        final PrefixService prefixService = createLocalPrefixService(info);
        if (uri != null) {
            // Complete <URI>
            final List<String> suggestions = new ArrayList<String>();
            for (String sug : getCompletions(uri, limit, mode)) {
                final String curie = prefixService.getCurie(sug);
                suggestions.add(curie != null ? curie : sug);
            }
            return suggestions;
        } else if (prefix != null) {
            Matcher m = CURIE_PATTERN.matcher(prefix);
            if (m.matches()) {
                String px = m.group(1);
                String local = m.group(2);

                if (px.equals(FUNCTION_PREFIX)) {
                    try {
                        final RepositoryConnection conn = sesameService.getConnection();
                        try {
                            conn.begin();
                            SesameConnectionBackend backend = SesameConnectionBackend.withConnection(conn);

                            final Set<SelectorFunction<Value>> functions = ldPathService.getFunctions();
                            List<String> suggestions = new ArrayList<String>();
                            for (SelectorFunction<Value> fn : functions) {
                                final String fName = fn.getPathExpression(backend);
                                if (fName.startsWith(local)) {
                                    suggestions.add(FUNCTION_PREFIX + ":" + fName + "()");
                                }
                            }
                            return suggestions;
                        } finally {
                            conn.commit();
                            conn.close();
                        }
                    } catch (RepositoryException e) {
                        return Collections.emptyList();
                    }
                } else if (prefixService.containsPrefix(px)) {
                    String resolved = prefixService.getNamespace(px) + (local != null ? local : "");
                    List<String> suggestions = new ArrayList<String>();
                    for (String c : getCompletions(resolved, limit, mode)) {
                        // CURIE urs MUST have a local part
                        if (c.length() <= resolved.length()) {
                            continue;
                        }
                        final String curie = prefixService.getCurie(c);
                        suggestions.add(curie != null ? curie : c);
                    }
                    return suggestions;
                }

            } else {
                List<String> suggestions = new ArrayList<String>();
                if (mode.equals(MODE_TRANSFORM)) {
                    for (String s : ldPathService.getTransformableTypes()) {
                        String px = prefixService.getPrefix(UriUtil.getNamespace(s));
                        if (px != null && px.startsWith(prefix) && !suggestions.contains(px)) {
                            suggestions.add(px);
                        }
                    }
                } else {
                    if (FUNCTION_PREFIX.startsWith(prefix)) {
                        suggestions.add(FUNCTION_PREFIX);
                    }
                    for (String px : prefixService.getMappings().keySet()) {
                        if (px.startsWith(prefix)) {
                            suggestions.add(px);
                        }
                    }
                }
                return suggestions;
            }

        }

        return Collections.emptyList();
    }

    private LDPathPrefixService createLocalPrefixService(UriInfo info) {
        HashMap<String, String> ns = new HashMap<String, String>();
        final MultivaluedMap<String, String> queryParameters = info.getQueryParameters();
        for (String key : queryParameters.keySet()) {
            if (key.startsWith("ns_")) {
                ns.put(key.substring(3), queryParameters.getFirst(key));
            }
        }
        return new LDPathPrefixService(ns);
    }

    private List<String> getCompletions(String uri, final int limit, String mode) {
        List<String> result = new ArrayList<String>();
        if (!mode.equals(MODE_TRANSFORM)) {
            try {
                RepositoryConnection con = sesameService.getConnection();
                try {
                    for (URI r : listResourcesByPrefix(con,uri, 0, limit)) {
                        result.add(r.stringValue());
                    }
                } finally {
                    con.commit();
                    con.close();
                }
            } catch (RepositoryException e) {
                handleRepositoryException(e,LDPathUtilWebService.class);
            }
        }
        for (String s : ldPathService.getTransformableTypes()) {
            if (s.startsWith(uri)) {
                result.add(s);
            }
        }
        return result;
    }

    @GET
    @Path("/path")
    @Produces(Namespaces.MIME_TYPE_JSON)
    public List<String> pathSuggestions(@QueryParam("path") String partialPath, @QueryParam("ctx") String[] ctx,
            @QueryParam("ctx[]") String[] ctx2, @Context UriInfo info) {
        final PrefixService prefixService = createLocalPrefixService(info);

        // Merge the contexts
        HashSet<String> context = new HashSet<String>();
        for (String c : ctx) {
            context.add(c);
        }
        for (String c : ctx2) {
            context.add(c);
        }

        // Clean the path
        String path = partialPath.replaceAll("/.*", "").trim();
        if (path.equals("")) {
            path = ".";
        }
        try {
            HashSet<URI> pathCandidates = new HashSet<URI>();
            try {
                RepositoryConnection con = sesameService.getConnection();
                try {
                    con.begin();
                    for (String rsc_uri : context) {
                        if (!ResourceUtils.isSubject(con, rsc_uri)) {
                            continue;
                        }

                        URI rsc = con.getValueFactory().createURI(rsc_uri);
                        Collection<Value> cPos = ldPathService.pathQuery(rsc, path, prefixService.getMappings());
                        for (Value cP : cPos) {
                            if (cP instanceof URI || cP instanceof BNode) {
                                for (Statement t : listOutgoing(con, (Resource) cP)) {
                                    pathCandidates.add(t.getPredicate());
                                }
                            }
                        }
                    }
                } finally {
                    con.commit();
                    con.close();
                }
            } catch (RepositoryException e) {
                handleRepositoryException(e,LDPathUtilWebService.class);
            }
            List<String> suggest = new ArrayList<String>();
            for (URI r : pathCandidates) {
                suggest.add(r.stringValue());
            }
            return suggest;
        } catch (LDPathParseException e) {
            // Silently fail.
        }
        return Collections.emptyList();
    }

    protected class LDPathPrefixService implements PrefixService {

        private final BiMap<String, String> localNS;

        public LDPathPrefixService(Map<String, String> local) {
            if (local != null) {
                this.localNS = HashBiMap.create(local);
            } else {
                this.localNS = HashBiMap.create();
            }
        }

        @Override
        public boolean containsPrefix(String prefix) {
            return localNS.containsKey(prefix) || prefixService.containsPrefix(prefix);
        }

        @Override
        public boolean containsNamespace(String namespace) {
            return localNS.containsValue(namespace) || prefixService.containsNamespace(namespace);
        }

        @Override
        public String getNamespace(String prefix) {
            if (localNS.containsKey(prefix))
                return localNS.get(prefix);
            else
                return prefixService.getNamespace(prefix);
        }

        @Override
        public String getPrefix(String namespace) {
            if (localNS.containsValue(namespace))
                return localNS.inverse().get(namespace);
            else
                return prefixService.getPrefix(namespace);
        }

        @Override
        public Map<String, String> getMappings() {
            Map<String, String> mappings = new HashMap<String, String>();
            mappings.putAll(prefixService.getMappings());
            mappings.putAll(localNS);
            return Collections.unmodifiableMap(mappings);
        }

        @Override
        public String getCurie(String uri) {
            if (UriUtil.validate(uri)) {
                String ns = UriUtil.getNamespace(uri);
                String ref = UriUtil.getReference(uri);
                if (StringUtils.isNotBlank(ns) && StringUtils.isNotBlank(ref) && containsNamespace(ns))
                    return getPrefix(ns) + ":" + ref;
                else
                    return null;
            } else
                return null;
        }

        @Override
        public void add(String prefix, String namespace) throws IllegalArgumentException, URISyntaxException {
            // nop;
        }

        @Override
        public void forceAdd(String prefix, String namespace) {
            // nop;
        }
       
    @Override
    public boolean remove(String prefix) {
      return false; // nop;
    }

        @Override
        public String serializePrefixMapping() {
            StringBuffer sb = new StringBuffer();
            for (Map.Entry<String, String> mapping : getMappings().entrySet()) {
                sb.append("\n").append(mapping.getKey()).append(": ").append(mapping.getValue()).append(" ");
            }
            return sb.toString();
        }

        @Override
        public String serializePrefixesSparqlDeclaration() {
            StringBuffer sb = new StringBuffer();
            for (Map.Entry<String, String> mapping : getMappings().entrySet()) {
                sb.append("PREFIX ").append(mapping.getKey()).append(": <").append(mapping.getValue()).append("> \n");
            }
            return sb.toString();
        }

    }

}
TOP

Related Classes of org.apache.marmotta.platform.ldpath.webservices.LDPathUtilWebService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.