You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@marmotta.apache.org by ss...@apache.org on 2013/02/22 16:21:36 UTC
[27/37] MARMOTTA-105: refactoring of packages in ldpath, ldcache,
reasoner
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5c0255c8/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/services/LDPathServiceImpl.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/services/LDPathServiceImpl.java b/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/services/LDPathServiceImpl.java
deleted file mode 100644
index 2185f8b..0000000
--- a/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/services/LDPathServiceImpl.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/**
- * Copyright (C) 2013 Salzburg Research.
- *
- * Licensed 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 at.newmedialab.lmf.ldpath.services;
-
-import at.newmedialab.lmf.ldpath.api.LDPathService;
-import at.newmedialab.lmf.ldpath.api.LMFLDPathFunction;
-import org.apache.marmotta.platform.core.api.triplestore.SesameService;
-
-import org.apache.marmotta.ldpath.LDPath;
-import org.apache.marmotta.ldpath.api.functions.SelectorFunction;
-import org.apache.marmotta.ldpath.api.transformers.NodeTransformer;
-import org.apache.marmotta.ldpath.backend.sesame.SesameConnectionBackend;
-import org.apache.marmotta.ldpath.exception.LDPathParseException;
-import org.apache.marmotta.ldpath.model.Constants;
-import org.apache.marmotta.ldpath.parser.Configuration;
-import org.apache.marmotta.ldpath.parser.DefaultConfiguration;
-import org.openrdf.model.Value;
-import org.openrdf.repository.RepositoryConnection;
-import org.openrdf.repository.RepositoryException;
-import org.slf4j.Logger;
-
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.inject.Any;
-import javax.enterprise.inject.Instance;
-import javax.inject.Inject;
-
-import java.io.StringReader;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Add file description here!
- * <p/>
- * Author: Sebastian Schaffert
- */
-@ApplicationScoped
-public class LDPathServiceImpl implements LDPathService {
-
- @Inject
- private Logger log;
-
- @Inject
- private SesameService sesameService;
-
- private Configuration<Value> config;
-
- @Inject @Any
- private Instance<LMFLDPathFunction> functions;
-
- @PostConstruct
- public void initialise() {
- log.info("initialising LDPath service ...");
-
- config = new DefaultConfiguration<Value>();
-
- for(LMFLDPathFunction function : functions) {
- config.addFunction(Constants.NS_LMF_FUNCS + function.getLocalName(), function);
- }
- }
-
-
- /**
- * Register an LDPath function in this LDPath service. Can be used by other modules to plug in their own LDPath
- * functions as needed.
- *
- * @param function
- */
- @Override
- public void registerFunction(SelectorFunction<Value> function) {
- if (function instanceof LMFLDPathFunction) {
- config.addFunction(((LMFLDPathFunction) function).getLocalName(), function);
- } else {
- try {
- RepositoryConnection conn = sesameService.getConnection();
- try {
- conn.begin();
- SesameConnectionBackend backend = SesameConnectionBackend.withConnection(conn);
- config.addFunction(Constants.NS_LMF_FUNCS + function.getPathExpression(backend), function);
- } finally {
- conn.commit();
- conn.close();
- }
- } catch (RepositoryException e) {
- log.warn("Could not add function:" + function.getSignature(), e);
- }
- }
- }
-
- @Override
- public void registerTransformer(String typeUri, NodeTransformer<?, Value> transformer) {
- config.addTransformer(typeUri, transformer);
- }
-
-
- /**
- * List all selector functions that are currently registered with LDPath.
- *
- * @return
- */
- @Override
- public Set<SelectorFunction<Value>> getFunctions() {
- Set<SelectorFunction<Value>> result = new HashSet<SelectorFunction<Value>>();
- result.addAll(config.getFunctions().values());
-
- return result;
- }
-
- @Override
- public Set<String> getTransformableTypes() {
- Set<String> t = new HashSet<String>();
- t.addAll(config.getTransformers().keySet());
-
- return t;
- }
-
- /**
- * Run a path query starting from the given context node and return the result as a collection of KiWiNodes. The
- * namespaces argument is optional and contains a map from prefixes to namespace URIs that can be used in the
- * path expression.
- *
- * @param context the context node where to start with the path query
- * @param path the path query to evaluate starting from the context node
- * @param namespaces optional map from namespace prefixes to namespace URIs
- * @return a collection of KiWiNodes
- * @throws LDPathParseException when the path passed as argument could not be parsed
- */
- @Override
- public Collection<Value> pathQuery(Value context, String path, Map<String, String> namespaces) throws LDPathParseException {
- try {
- RepositoryConnection conn = sesameService.getConnection();
- try {
- conn.begin();
- SesameConnectionBackend backend = SesameConnectionBackend.withConnection(conn);
- LDPath<Value> ldpath = new LDPath<Value>(backend, config);
-
- return ldpath.pathQuery(context, path, namespaces);
- } finally {
- conn.commit();
- conn.close();
- }
- } catch (RepositoryException e) {
- throw new LDPathParseException("LDPath evaluation failed", e);
- }
- }
-
-
- /**
- * Run a path program starting from the given context node and return the result as a collection of KiWiNodes for
- * each field occurring in the path progrm.
- *
- * @param context the context node where to start with the path query
- * @param program the path program to evaluate starting from the context node
- * @return a map mapping from field names to the resulting collection of KiWiNodes for the field
- * @throws LDPathParseException when the path passed as argument could not be parsed
- */
- @Override
- public Map<String, Collection<?>> programQuery(Value context, String program) throws LDPathParseException {
- try {
- RepositoryConnection conn = sesameService.getConnection();
- try {
- conn.begin();
- SesameConnectionBackend backend = SesameConnectionBackend.withConnection(conn);
- LDPath<Value> ldpath = new LDPath<Value>(backend, config);
-
- return ldpath.programQuery(context, new StringReader(program));
- } finally {
- conn.commit();
- conn.close();
- }
- } catch (RepositoryException e) {
- throw new LDPathParseException("LDPath evaluation failed", e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5c0255c8/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/webservices/LDPathUtilWebService.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/webservices/LDPathUtilWebService.java b/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/webservices/LDPathUtilWebService.java
deleted file mode 100644
index cbc8ca2..0000000
--- a/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/webservices/LDPathUtilWebService.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/**
- * Copyright (C) 2013 Salzburg Research.
- *
- * Licensed 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 at.newmedialab.lmf.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 at.newmedialab.lmf.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.lang.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 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();
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5c0255c8/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/webservices/LDPathWebService.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/webservices/LDPathWebService.java b/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/webservices/LDPathWebService.java
deleted file mode 100644
index f8b2960..0000000
--- a/platform/marmotta-ldpath/src/main/java/at/newmedialab/lmf/ldpath/webservices/LDPathWebService.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/**
- * Copyright (C) 2013 Salzburg Research.
- *
- * Licensed 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 at.newmedialab.lmf.ldpath.webservices;
-
-import static org.apache.marmotta.commons.sesame.repository.ResultUtils.iterable;
-import static org.apache.marmotta.commons.sesame.repository.ExceptionUtils.handleRepositoryException;
-
-import at.newmedialab.lmf.ldpath.api.LDPathService;
-import org.apache.marmotta.commons.sesame.repository.ResourceUtils;
-import org.apache.marmotta.commons.util.JSONUtils;
-
-import org.apache.marmotta.platform.core.api.triplestore.SesameService;
-import org.apache.marmotta.kiwi.model.rdf.KiWiNode;
-import org.apache.marmotta.kiwi.model.rdf.KiWiStringLiteral;
-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.Namespace;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.repository.RepositoryConnection;
-import org.openrdf.repository.RepositoryException;
-import org.slf4j.Logger;
-
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.ws.rs.*;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-
-import java.text.Collator;
-import java.util.*;
-
-/**
- * Execute LDPath queries against the LMF backend. Depending on the LMF configuration, this might trigger retrieval
- * of external Linked Data resources before returning results.
- *
- * <p/>
- * Author: Sebastian Schaffert
- */
-@ApplicationScoped
-@Path("/ldpath")
-public class LDPathWebService {
-
-
- @Inject
- private Logger log;
-
- @Inject
- private LDPathService ldPathService;
-
- @Inject
- private SesameService sesameService;
-
- /**
- * Evaluate a single LDPath selection using the path passed as argument and starting at the resource identified
- * by the uri. Returns a list of RDF Nodes using the same syntax as RDF/JSON, i.e.
- * <ul>
- * <li> <code>{ "type": "uri", "value": "..." }</code> for resources</li>
- * <li><code>{ "type": "literal", "value": "...", "language": "...", "datatype": "..."}</code> for literals (datatype and language optional)</li>
- * </ul>
- *
- * @param path the LDPath expression to evaluate
- * @param resourceUri the URI of the resource from which to start the resource
- *
- * @return a list of RDF Nodes using the same syntax as RDF/JSON
- * @HTTP 404 in case the resource with the given URI does not exist
- * @HTTP 400 in case the path could not be parsed or the resource is not a valid URI
- * @HTTP 200 in case the query was evaluated successfully
- */
- @GET
- @Path("/path")
- @Produces("application/json")
- public Response evaluatePathQuery(@QueryParam("path") String path, @QueryParam("uri") String resourceUri) {
- //Preconditions.checkArgument(urlValidator.isValid(resourceUri));
-
- try {
- RepositoryConnection con = sesameService.getConnection();
- try {
- con.begin();
- if (ResourceUtils.isSubject(con, resourceUri)) {
- URI resource = con.getValueFactory().createURI(resourceUri);
- // get list of configured namespaces; we make them available for the path language
- Map<String,String> namespaces = new HashMap<String, String>();
- for(Namespace ns : iterable(con.getNamespaces())) {
- namespaces.put(ns.getPrefix(),ns.getName());
- }
-
- List<Map<String,String>> result = new ArrayList<Map<String, String>>();
-
- try {
- for(Value node : ldPathService.pathQuery(resource,path,namespaces)) {
- result.add(JSONUtils.serializeNodeAsJson(node));
- }
- return Response.ok().entity(result).build();
- } catch (LDPathParseException e) {
- log.warn("parse error while evaluating path {}: {}",path,e.getMessage());
- return Response.status(Response.Status.BAD_REQUEST).entity("parse error while evaluating path '"+path+"': "+e.getMessage()).build();
- }
-
- } else
- return Response.status(Response.Status.NOT_FOUND).entity("resource "+resourceUri+" does not exist").build();
- } finally {
- con.commit();
- con.close();
- }
- } catch (RepositoryException ex) {
- handleRepositoryException(ex,LDPathWebService.class);
- return Response.serverError().entity("error accessing RDF repository: "+ex.getMessage()).build();
- }
-
- }
-
- /**
- * Evaluate a LDPath program using the program string passed as argument and starting at the resource identified
- * by the uri. Returns a map from field names to lists of RDF nodes using the same syntax as RDF/JSON, i.e.
- * <ul>
- * <li> <code>{ "type": "uri", "value": "..." }</code> for resources</li>
- * <li><code>{ "type": "literal", "value": "...", "language": "...", "datatype": "..."}</code> for literals (datatype and language optional)</li>
- * </ul>
- *
- * @param program the program to evaluate
- * @param resourceUri the URI of the resource where to start
- * @return a map from field names to lists of rdf nodes in rdf/json format
- * @HTTP 404 in case the resource with the given URI does not exist
- * @HTTP 400 in case the path could not be parsed or the resource is not a valid URI
- * @HTTP 200 in case the query was evaluated successfully
- */
- @GET
- @Path("/program")
- @Produces("application/json")
- public Response evaluateProgramQuery(@QueryParam("program") String program, @QueryParam("uri") String resourceUri) {
- //Preconditions.checkArgument(urlValidator.isValid(resourceUri));
-
- try {
- RepositoryConnection con = sesameService.getConnection();
- try {
- con.begin();
- if (ResourceUtils.isSubject(con, resourceUri)) {
- URI resource = con.getValueFactory().createURI(resourceUri);
- // get list of configured namespaces; we make them available for the path language
- Map<String,String> namespaces = new HashMap<String, String>();
- for(Namespace ns : iterable(con.getNamespaces())) {
- namespaces.put(ns.getPrefix(),ns.getName());
- }
-
-
- Map<String,List<Map<String,String>>> result = new HashMap<String, List<Map<String, String>>>();
-
- try {
- for(Map.Entry<String,Collection<?>> row : ldPathService.programQuery(resource,program).entrySet()) {
- List<Map<String,String>> rowList = new ArrayList<Map<String, String>>();
- for(Object o : row.getValue()) {
- if(o instanceof KiWiNode) {
- rowList.add(JSONUtils.serializeNodeAsJson((Value) o));
- } else {
- // we convert always to a literal
- rowList.add(JSONUtils.serializeNodeAsJson(new KiWiStringLiteral(o.toString())));
- }
- }
- result.put(row.getKey(),rowList);
- }
- return Response.ok().entity(result).build();
- } catch (LDPathParseException e) {
- log.warn("parse error while evaluating program {}: {}", program, e.getMessage());
- return Response.status(Response.Status.BAD_REQUEST).entity("parse error while evaluating program: "+e.getMessage()).build();
- }
-
-
- } else
- return Response.status(Response.Status.NOT_FOUND).entity("resource "+resourceUri+" does not exist").build();
- } finally {
- con.commit();
- con.close();
- }
- } catch (RepositoryException ex) {
- handleRepositoryException(ex,LDPathWebService.class);
- return Response.serverError().entity("error accessing RDF repository: "+ex.getMessage()).build();
- }
- }
-
-
- /**
- * Return a list of all LDPath functions that have been registered in the LDPath installation.
- *
- * @return
- */
- @GET
- @Path("/functions")
- @Produces("application/json")
- public Response listFunctions() {
- List<Map<String,String>> results = new ArrayList<Map<String, String>>();
-
- try {
- RepositoryConnection con = sesameService.getConnection();
- try {
- con.begin();
- SesameConnectionBackend backend = SesameConnectionBackend.withConnection(con);
- for(SelectorFunction<Value> function : ldPathService.getFunctions()) {
- Map<String,String> fmap = new HashMap<String, String>();
- fmap.put("name", function.getPathExpression(backend));
- fmap.put("signature",function.getSignature());
- fmap.put("description",function.getDescription());
- results.add(fmap);
- }
- } finally {
- con.commit();
- con.close();
- }
- } catch (RepositoryException e) {
- return Response.serverError().entity(e).build();
- }
- Collections.sort(results, new Comparator<Map<String, String>>() {
- @Override
- public int compare(Map<String, String> o1, Map<String, String> o2) {
- return Collator.getInstance().compare(o1.get("name"),o2.get("name"));
- }
- });
-
- return Response.ok().entity(results).build();
- }
-
- /**
- * Return a list of all LDPath functions that have been registered in the LDPath installation.
- *
- * @return
- */
- @GET
- @Path("/functions/{name}")
- @Produces("application/json")
- public Response getFunction(@PathParam("name") String name) {
- try {
- RepositoryConnection con = sesameService.getConnection();
- try {
- con.begin();
- SesameConnectionBackend backend = SesameConnectionBackend.withConnection(con);
-
- for (SelectorFunction<Value> function : ldPathService.getFunctions()) {
- final String fName = function.getPathExpression(backend);
- if (name.equals(fName)) {
- Map<String, String> fmap = new HashMap<String, String>();
- fmap.put("name", fName);
- fmap.put("signature", function.getSignature());
- fmap.put("description", function.getDescription());
- return Response.ok(fmap).build();
- }
- }
- return Response.status(Status.NOT_FOUND).entity("LDPath function with name " + name + " does not exist").build();
- } finally {
- con.commit();
- con.close();
- }
- } catch (RepositoryException e) {
- return Response.serverError().entity(e).build();
- }
- }
-
- @GET
- @Path("/play/test/program")
- @Produces("application/json")
- public Response testProgram(@QueryParam("program") String program, @QueryParam("uri") String[] resourceUri) {
- if (resourceUri != null && resourceUri.length > 0)
- return evaluateProgramQuery(program, resourceUri[0]);
- return Response.status(Status.BAD_REQUEST).build();
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5c0255c8/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/api/LDPathService.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/api/LDPathService.java b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/api/LDPathService.java
new file mode 100644
index 0000000..3b224d4
--- /dev/null
+++ b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/api/LDPathService.java
@@ -0,0 +1,87 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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.api;
+
+
+import org.apache.marmotta.ldpath.api.functions.SelectorFunction;
+import org.apache.marmotta.ldpath.api.transformers.NodeTransformer;
+import org.apache.marmotta.ldpath.exception.LDPathParseException;
+import org.openrdf.model.Value;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public interface LDPathService {
+
+ /**
+ * Register an LDPath function in this LDPath service. Can be used by other modules to plug in
+ * their own LDPath functions as needed.
+ *
+ * @param function {@link SelectorFunction} to register.
+ */
+ public void registerFunction(SelectorFunction<Value> function);
+
+
+ /**
+ * List all selector functions that are currently registered with LDPath.
+ */
+ public Set<SelectorFunction<Value>> getFunctions();
+
+ /**
+ * Run a path query starting from the given context node and return the result as a collection of KiWiNodes. The
+ * namespaces argument is optional and contains a map from prefixes to namespace URIs that can be used in the
+ * path expression.
+ *
+ * @param context the context node where to start with the path query
+ * @param path the path query to evaluate starting from the context node
+ * @param namespaces optional map from namespace prefixes to namespace URIs
+ * @return a collection of KiWiNodes
+ * @throws LDPathParseException when the path passed as argument could not be parsed
+ */
+ public Collection<Value> pathQuery(Value context, String path, Map<String, String> namespaces) throws LDPathParseException;
+
+ /**
+ * Run a path program starting from the given context node and return the result as a collection of KiWiNodes for
+ * each field occurring in the path progrm.
+ *
+ * @param context the context node where to start with the path query
+ * @param program the path program to evaluate starting from the context node
+ * @return a map mapping from field names to the resulting collection of KiWiNodes for the field
+ * @throws org.apache.marmotta.ldpath.exception.LDPathParseException when the path passed as argument could not be parsed
+ */
+ public Map<String, Collection<?>> programQuery(Value context, String program) throws LDPathParseException;
+
+ /**
+ * Register a result transformer for a type URI. Use this method in your own projects
+ * to register custom result transformers.
+ *
+ * @param typeUri a URI identifying the type for which to use this transformer; can be specified
+ * in path programs
+ * @param transformer instance of a node transformer
+ */
+ public void registerTransformer(String typeUri, NodeTransformer<?, Value> transformer);
+
+ /**
+ * List all types that have a transformer registered.
+ */
+ public Set<String> getTransformableTypes();
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5c0255c8/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/api/LMFLDPathFunction.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/api/LMFLDPathFunction.java b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/api/LMFLDPathFunction.java
new file mode 100644
index 0000000..ce99ad5
--- /dev/null
+++ b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/api/LMFLDPathFunction.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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.api;
+
+import org.apache.marmotta.ldpath.api.functions.SelectorFunction;
+import org.openrdf.model.Value;
+
+/**
+ * Superclass of all LMF LDPath functions, used for auto-registry of functions provided by modules using
+ * injection.
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+public abstract class LMFLDPathFunction extends SelectorFunction<Value> {
+
+ @Override
+ public abstract String getLocalName();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5c0255c8/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/backend/LMFBackend.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/backend/LMFBackend.java b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/backend/LMFBackend.java
new file mode 100644
index 0000000..7c1abbd
--- /dev/null
+++ b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/backend/LMFBackend.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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.backend;
+
+import org.apache.marmotta.platform.core.api.triplestore.SesameService;
+
+import org.apache.marmotta.ldpath.backend.sesame.SesameRepositoryBackend;
+import org.slf4j.Logger;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+/**
+ * Implementation of the LDPath RDFBackend<KiWiNode>, making use of the LMF internal triple store
+ * implementation.
+ * <p/>
+ * Author: Sebastian Schaffert
+ *
+ * @deprecated Use a {@link org.apache.marmotta.ldpath.backend.sesame.SesameConnectionBackend} instead
+ * and handle transactions manually.
+ */
+@ApplicationScoped
+@Deprecated
+public class LMFBackend extends SesameRepositoryBackend {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private SesameService sesameService;
+
+ @PostConstruct
+ public void initialize() {
+ log.info("LMF LDPath backend starting up ...");
+
+ setRepository(sesameService.getRepository());
+ log.warn("LMFBackend is deprecated. Use a SesameConnectionBackend instead.", new Throwable("Deprecated Usage of LMFBackend"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5c0255c8/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/model/functions/ContentFunction.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/model/functions/ContentFunction.java b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/model/functions/ContentFunction.java
new file mode 100644
index 0000000..fb2a63c
--- /dev/null
+++ b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/model/functions/ContentFunction.java
@@ -0,0 +1,131 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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.model.functions;
+
+import org.apache.marmotta.platform.ldpath.api.LMFLDPathFunction;
+import org.apache.marmotta.platform.core.api.content.ContentService;
+import org.apache.marmotta.kiwi.model.rdf.KiWiResource;
+import org.apache.marmotta.kiwi.model.rdf.KiWiStringLiteral;
+import org.apache.marmotta.ldpath.api.backend.RDFBackend;
+import org.openrdf.model.Resource;
+import org.openrdf.model.Value;
+import org.slf4j.Logger;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+@ApplicationScoped
+public class ContentFunction extends LMFLDPathFunction {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private ContentService contentService;
+
+ private String[] allowedTypes = new String[] {
+ "text/.*", "application/([a-z]+\\+)?xml", "application/([a-z]+\\+)?json"
+ };
+
+ public ContentFunction() {
+ }
+
+
+ @PostConstruct
+ public void initialise() {
+ log.info("initialising LMF LDPath fn:content(...) function ...");
+ }
+
+
+ /**
+ * Apply the function to the list of nodes passed as arguments and return the result as type T.
+ * Throws IllegalArgumentException if the function cannot be applied to the nodes passed as argument
+ * or the number of arguments is not correct.
+ *
+ * @param context the context of the execution. Same as using the
+ * {@link org.apache.marmotta.ldpath.api.selectors.NodeSelector} '.' as parameter.
+ * @param args a nested list of KiWiNodes
+ * @return
+ */
+ @Override
+ public Collection<Value> apply(RDFBackend<Value> kiWiNodeRDFBackend, Value context, Collection<Value>... args) throws IllegalArgumentException {
+ List<Value> result = new LinkedList<Value>();
+
+ for(Collection<? extends Value> nodes : args) {
+ for(Value n : nodes) {
+ if(n instanceof KiWiResource) {
+ Resource r = (Resource)n;
+
+ String type = contentService.getContentType(r);
+
+ if(type != null) {
+ for(String allowedType : allowedTypes) {
+ if(type.matches(allowedType)) {
+ byte[] data = contentService.getContentData(r,type);
+ String content = new String(data);
+ result.add(new KiWiStringLiteral(content));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return the representation of the NodeFunction or NodeSelector in the RDF Path Language
+ *
+ * @param backend
+ * @return
+ */
+ @Override
+ public String getLocalName() {
+ return "content";
+ }
+
+ /**
+ * A string describing the signature of this node function, e.g. "fn:content(uris : Nodes) : Nodes". The
+ * syntax for representing the signature can be chosen by the implementer. This method is for informational
+ * purposes only.
+ *
+ * @return
+ */
+ @Override
+ public String getSignature() {
+ return "fn:content(nodes : URIResourceList) : LiteralList";
+ }
+
+ /**
+ * A short human-readable description of what the node function does.
+ *
+ * @return
+ */
+ @Override
+ public String getDescription() {
+ return "Resolve the URIs passed as argument and retrieve their content using the content reader applicable for the resource.";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5c0255c8/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/model/functions/JsoupFunction.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/model/functions/JsoupFunction.java b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/model/functions/JsoupFunction.java
new file mode 100644
index 0000000..3ef6930
--- /dev/null
+++ b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/model/functions/JsoupFunction.java
@@ -0,0 +1,143 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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.model.functions;
+
+import org.apache.marmotta.platform.ldpath.api.LMFLDPathFunction;
+
+import org.apache.marmotta.ldpath.api.backend.RDFBackend;
+import org.apache.marmotta.ldpath.model.transformers.StringTransformer;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Selector.SelectorParseException;
+import org.openrdf.model.Value;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+public class JsoupFunction extends LMFLDPathFunction {
+
+ private static final Logger log = LoggerFactory.getLogger(JsoupFunction.class);
+
+ private final StringTransformer<Value> transformer = new StringTransformer<Value>();
+
+ /**
+ * Apply the function to the list of nodes passed as arguments and return the result as type T.
+ * Throws IllegalArgumentException if the function cannot be applied to the nodes passed as
+ * argument
+ * or the number of arguments is not correct.
+ *
+ * @param args a nested list of KiWiNodes
+ * @return
+ */
+ @Override
+ public Collection<Value> apply(RDFBackend<Value> rdfBackend, Value context, Collection<Value>... args)
+ throws IllegalArgumentException {
+ if (args.length < 1) throw new IllegalArgumentException("CSS-Selector is required as first argument.");
+ Set<String> jsoupSelectors = new HashSet<String>();
+ for (Value xpath : args[0]) {
+ try {
+ jsoupSelectors.add(transformer.transform(rdfBackend, xpath));
+ } catch (IllegalArgumentException iae) {
+ throw new IllegalArgumentException("First argument must not contain anything else than String-Literals!");
+ }
+ }
+ Iterator<Value> it;
+ if (args.length < 2) {
+ log.debug("Use context {} to apply css-selector {}", context, jsoupSelectors);
+ it = Collections.singleton(context).iterator();
+ } else {
+ log.debug("apply css-selector {} on parsed parameters", jsoupSelectors);
+ it = org.apache.marmotta.ldpath.util.Collections.iterator(1, args);
+ }
+ List<Value> result = new ArrayList<Value>();
+ while (it.hasNext()) {
+ Value n = it.next();
+ try {
+ final String string = transformer.transform(rdfBackend, n);
+ final Document jsoup = Jsoup.parse(string);
+ if (rdfBackend.isURI(context)) {
+ jsoup.setBaseUri(rdfBackend.stringValue(context));
+ }
+ for (String r : doFilter(jsoup, jsoupSelectors)) {
+ result.add(rdfBackend.createLiteral(r));
+ }
+ } catch (IOException e) {
+ // This should never happen, since validation is turned off.
+ }
+ }
+
+ return result;
+ }
+
+ private LinkedList<String> doFilter(Document jsoup, Set<String> jsoupSelectors) throws IOException {
+ LinkedList<String> result = new LinkedList<String>();
+ for (String jsoupSel : jsoupSelectors) {
+ try {
+ for (Element e : jsoup.select(jsoupSel)) {
+ result.add(e.outerHtml());
+ }
+ } catch (SelectorParseException xpe) {
+ throw new IllegalArgumentException("error while processing jsoup selector: '" + jsoupSel + "'", xpe);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Return the name of the NodeFunction for registration in the function registry
+ *
+ * @return
+ * @param backend
+ */
+ @Override
+ public String getLocalName() {
+ return "jsoup";
+ }
+
+ /**
+ * A string describing the signature of this node function, e.g.
+ * "fn:content(uris : Nodes) : Nodes". The
+ * syntax for representing the signature can be chosen by the implementer. This method is for
+ * informational
+ * purposes only.
+ *
+ * @return
+ */
+ @Override
+ public String getSignature() {
+ return "fn:jsoup(jsoup: String [, nodes: XMLLiteralList]) : LiteralList";
+ }
+
+ /**
+ * A short human-readable description of what the node function does.
+ *
+ * @return
+ */
+ @Override
+ public String getDescription() {
+ return "Evaluate an JSoup CSS selector on either the value of the context node or the values of the nodes passed as arguments.";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5c0255c8/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/services/LDPathServiceImpl.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/services/LDPathServiceImpl.java b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/services/LDPathServiceImpl.java
new file mode 100644
index 0000000..71ae020
--- /dev/null
+++ b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/services/LDPathServiceImpl.java
@@ -0,0 +1,190 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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.services;
+
+import org.apache.marmotta.platform.ldpath.api.LDPathService;
+import org.apache.marmotta.platform.ldpath.api.LMFLDPathFunction;
+import org.apache.marmotta.platform.core.api.triplestore.SesameService;
+
+import org.apache.marmotta.ldpath.LDPath;
+import org.apache.marmotta.ldpath.api.functions.SelectorFunction;
+import org.apache.marmotta.ldpath.api.transformers.NodeTransformer;
+import org.apache.marmotta.ldpath.backend.sesame.SesameConnectionBackend;
+import org.apache.marmotta.ldpath.exception.LDPathParseException;
+import org.apache.marmotta.ldpath.model.Constants;
+import org.apache.marmotta.ldpath.parser.Configuration;
+import org.apache.marmotta.ldpath.parser.DefaultConfiguration;
+import org.openrdf.model.Value;
+import org.openrdf.repository.RepositoryConnection;
+import org.openrdf.repository.RepositoryException;
+import org.slf4j.Logger;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+
+import java.io.StringReader;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Add file description here!
+ * <p/>
+ * Author: Sebastian Schaffert
+ */
+@ApplicationScoped
+public class LDPathServiceImpl implements LDPathService {
+
+ @Inject
+ private Logger log;
+
+ @Inject
+ private SesameService sesameService;
+
+ private Configuration<Value> config;
+
+ @Inject @Any
+ private Instance<LMFLDPathFunction> functions;
+
+ @PostConstruct
+ public void initialise() {
+ log.info("initialising LDPath service ...");
+
+ config = new DefaultConfiguration<Value>();
+
+ for(LMFLDPathFunction function : functions) {
+ config.addFunction(Constants.NS_LMF_FUNCS + function.getLocalName(), function);
+ }
+ }
+
+
+ /**
+ * Register an LDPath function in this LDPath service. Can be used by other modules to plug in their own LDPath
+ * functions as needed.
+ *
+ * @param function
+ */
+ @Override
+ public void registerFunction(SelectorFunction<Value> function) {
+ if (function instanceof LMFLDPathFunction) {
+ config.addFunction(((LMFLDPathFunction) function).getLocalName(), function);
+ } else {
+ try {
+ RepositoryConnection conn = sesameService.getConnection();
+ try {
+ conn.begin();
+ SesameConnectionBackend backend = SesameConnectionBackend.withConnection(conn);
+ config.addFunction(Constants.NS_LMF_FUNCS + function.getPathExpression(backend), function);
+ } finally {
+ conn.commit();
+ conn.close();
+ }
+ } catch (RepositoryException e) {
+ log.warn("Could not add function:" + function.getSignature(), e);
+ }
+ }
+ }
+
+ @Override
+ public void registerTransformer(String typeUri, NodeTransformer<?, Value> transformer) {
+ config.addTransformer(typeUri, transformer);
+ }
+
+
+ /**
+ * List all selector functions that are currently registered with LDPath.
+ *
+ * @return
+ */
+ @Override
+ public Set<SelectorFunction<Value>> getFunctions() {
+ Set<SelectorFunction<Value>> result = new HashSet<SelectorFunction<Value>>();
+ result.addAll(config.getFunctions().values());
+
+ return result;
+ }
+
+ @Override
+ public Set<String> getTransformableTypes() {
+ Set<String> t = new HashSet<String>();
+ t.addAll(config.getTransformers().keySet());
+
+ return t;
+ }
+
+ /**
+ * Run a path query starting from the given context node and return the result as a collection of KiWiNodes. The
+ * namespaces argument is optional and contains a map from prefixes to namespace URIs that can be used in the
+ * path expression.
+ *
+ * @param context the context node where to start with the path query
+ * @param path the path query to evaluate starting from the context node
+ * @param namespaces optional map from namespace prefixes to namespace URIs
+ * @return a collection of KiWiNodes
+ * @throws LDPathParseException when the path passed as argument could not be parsed
+ */
+ @Override
+ public Collection<Value> pathQuery(Value context, String path, Map<String, String> namespaces) throws LDPathParseException {
+ try {
+ RepositoryConnection conn = sesameService.getConnection();
+ try {
+ conn.begin();
+ SesameConnectionBackend backend = SesameConnectionBackend.withConnection(conn);
+ LDPath<Value> ldpath = new LDPath<Value>(backend, config);
+
+ return ldpath.pathQuery(context, path, namespaces);
+ } finally {
+ conn.commit();
+ conn.close();
+ }
+ } catch (RepositoryException e) {
+ throw new LDPathParseException("LDPath evaluation failed", e);
+ }
+ }
+
+
+ /**
+ * Run a path program starting from the given context node and return the result as a collection of KiWiNodes for
+ * each field occurring in the path progrm.
+ *
+ * @param context the context node where to start with the path query
+ * @param program the path program to evaluate starting from the context node
+ * @return a map mapping from field names to the resulting collection of KiWiNodes for the field
+ * @throws LDPathParseException when the path passed as argument could not be parsed
+ */
+ @Override
+ public Map<String, Collection<?>> programQuery(Value context, String program) throws LDPathParseException {
+ try {
+ RepositoryConnection conn = sesameService.getConnection();
+ try {
+ conn.begin();
+ SesameConnectionBackend backend = SesameConnectionBackend.withConnection(conn);
+ LDPath<Value> ldpath = new LDPath<Value>(backend, config);
+
+ return ldpath.programQuery(context, new StringReader(program));
+ } finally {
+ conn.commit();
+ conn.close();
+ }
+ } catch (RepositoryException e) {
+ throw new LDPathParseException("LDPath evaluation failed", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-marmotta/blob/5c0255c8/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/webservices/LDPathUtilWebService.java
----------------------------------------------------------------------
diff --git a/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/webservices/LDPathUtilWebService.java b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/webservices/LDPathUtilWebService.java
new file mode 100644
index 0000000..b77ef7f
--- /dev/null
+++ b/platform/marmotta-ldpath/src/main/java/org/apache/marmotta/platform/ldpath/webservices/LDPathUtilWebService.java
@@ -0,0 +1,392 @@
+/**
+ * Copyright (C) 2013 Salzburg Research.
+ *
+ * Licensed 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.lang.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 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();
+ }
+
+ }
+
+}