manually merged
Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/9c04ea00 Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/9c04ea00 Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/9c04ea00 Branch: refs/heads/ldp Commit: 9c04ea00812a0961e34f871446fdaad42cad3394 Parents: 3731c87 cfa6318 Author: Sergio Fernández <[email protected]> Authored: Mon Feb 24 16:13:16 2014 +0100 Committer: Sergio Fernández <[email protected]> Committed: Mon Feb 24 16:13:16 2014 +0100 ---------------------------------------------------------------------- .../platform/ldp/services/LdpServiceImpl.java | 2 +- .../platform/ldp/webservices/LdpWebService.java | 30 +++++++++++--------- 2 files changed, 17 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/marmotta/blob/9c04ea00/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java ---------------------------------------------------------------------- diff --cc platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java index 0cee089,a3f4095..b49f9d2 --- a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java +++ b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java @@@ -63,216 -39,4 +63,216 @@@ public class LdpServiceImpl implements @Inject private SesameService sesameService; + private URI buildURI(String resource) { + return ValueFactoryImpl.getInstance().createURI(resource); + } + + @Override + public boolean exists(String resource) throws RepositoryException { + return exists(buildURI(resource)); + } + + @Override + public boolean exists(URI resource) throws RepositoryException { + final RepositoryConnection conn = sesameService.getConnection(); + try { + conn.begin(); + final URI ldpContext = conn.getValueFactory().createURI(LDP.NAMESPACE); + return conn.hasStatement(resource, RDF.TYPE, null, true, ldpContext); + } finally { + conn.commit(); + conn.close(); + } + } + + @Override + public List<Statement> getStatements(String resource) throws RepositoryException { + return getStatements(buildURI(resource)); + } + + @Override + public List<Statement> getStatements(URI resource) throws RepositoryException { + final RepositoryConnection conn = sesameService.getConnection(); + try { + URI ldp = conn.getValueFactory().createURI(LDP.NAMESPACE); + return conn.getStatements(resource, RDF.TYPE, null, false, ldp).asList(); //FIXME + } finally { + conn.close(); + } + } + + @Override + public void exportResource(OutputStream output, String resource, RDFFormat format) throws RepositoryException, RDFHandlerException { + exportResource(output, buildURI(resource), format); + } + + @Override + public void exportResource(OutputStream output, URI resource, RDFFormat format) throws RepositoryException, RDFHandlerException { + RepositoryConnection conn = sesameService.getConnection(); + try { + conn.begin(); + URI ldpContext = conn.getValueFactory().createURI(LDP.NAMESPACE); + // TODO: this should be a little more sophisticated... + // TODO: non-membership triples flag / Prefer-header + RDFWriter writer = Rio.createWriter(format, output); + UnionIteration<Statement, RepositoryException> union = new UnionIteration<>( + conn.getStatements(null, null, null, false, resource), + conn.getStatements(resource, null, null, false, ldpContext) + ); + try { + LdpWebServiceUtils.exportIteration(writer, resource, union); + } finally { + union.close(); + } + conn.commit(); + } finally { + conn.close(); + } + } + + @Override + public boolean addResource(InputStream stream, MediaType type, String container, String resource) throws RepositoryException, IOException, RDFParseException { + return addResource(stream, type, buildURI(container), buildURI(resource)); + } + + @Override + public boolean addResource(InputStream stream, MediaType type, URI container, URI resource) throws RepositoryException, IOException, RDFParseException { + final RepositoryConnection conn = sesameService.getConnection(); + try { + final URI ldpContext = conn.getValueFactory().createURI(LDP.NAMESPACE); + conn.begin(); + + log.trace("Checking possible name clash for new resource <{}>", resource.stringValue()); + if (conn.hasStatement(resource, null, null, false, ldpContext)) { + int i = 0; + final String base = resource.stringValue(); + do { + final String candidate = base + "-" + (++i); + log.trace("<{}> already exists, trying <{}>", resource.stringValue(), candidate); + resource = conn.getValueFactory().createURI(candidate); + } while (conn.hasStatement(resource, null, null, false, ldpContext)); + log.debug("resolved name clash, new resource will be <{}>", resource.stringValue()); + } else { + log.debug("no name clash for <{}>", resource); + } + + log.debug("POST to <{}> will create new LDP-R <{}>", container, resource); + + // Add container triples (Sec. 6.4.3) + // container and meta triples! + + Literal now = conn.getValueFactory().createLiteral(new Date()); + + conn.add(container, RDF.TYPE, LDP.BasicContainer, ldpContext); + conn.add(container, LDP.contains, resource, ldpContext); + conn.remove(container, DCTERMS.modified, null, ldpContext); + conn.add(container, DCTERMS.modified, now, ldpContext); + + conn.add(resource, RDF.TYPE, LDP.Resource, ldpContext); + conn.add(resource, DCTERMS.created, now, ldpContext); + conn.add(resource, DCTERMS.modified, now, ldpContext); + + // LDP-BC for now! + conn.commit(); + + // Add the bodyContent + log.trace("Content ({}) for new resource <{}>", type, resource); - final RDFFormat rdfFormat = Rio.getParserFormatForMIMEType(type.toString()); ++ final RDFFormat rdfFormat = Rio.getParserFormatForMIMEType(type.toString(), RDFFormat.TURTLE); + if (rdfFormat == null) { + log.debug("POST creates new LDP-BR with type {}", type); + log.warn("LDP-BR not (yet) supported!"); + throw new UnsupportedRDFormatException("No available parser for " + type.toString()); + } else { + log.debug("POST creates new LDP-RR, data provided as {}", rdfFormat.getName()); + conn.begin(); + + // FIXME: We are (are we?) allowed to filter out server-managed properties here + conn.add(stream, resource.stringValue(), rdfFormat, resource); + + conn.commit(); + return true; + } + } catch (final Throwable t) { + if (conn.isActive()) { + conn.rollback(); + } + throw t; + } finally { + conn.close(); + } + } + + @Override + public EntityTag generateETag(String resource) throws RepositoryException { + return generateETag(buildURI(resource)); + } + + @Override + public EntityTag generateETag(URI uri) throws RepositoryException { + final RepositoryConnection conn = sesameService.getConnection(); + final URI ldpContext = conn.getValueFactory().createURI(LDP.NAMESPACE); + final RepositoryResult<Statement> stmts = conn.getStatements(uri, DCTERMS.modified, null, true, ldpContext); + try { + // TODO: ETag is the last-modified date (explicitly managed) thus only weak. + Date latest = null; + while (stmts.hasNext()) { + Value o = stmts.next().getObject(); + if (o instanceof Literal) { + Date d = ((Literal)o).calendarValue().toGregorianCalendar().getTime(); + if (latest == null || d.after(latest)) { + latest = d; + } + } + } + if (latest != null) { + return new EntityTag(String.valueOf(latest.getTime()), true); + } else { + return null; + } + } finally { + stmts.close(); + } + } + + @Override + public boolean deleteResource(String resource) throws RepositoryException { + return deleteResource(buildURI(resource)); + } + + @Override + public boolean deleteResource(URI resource) throws RepositoryException { + final RepositoryConnection conn = sesameService.getConnection(); + try { + conn.begin(); + + log.warn("NOT CHECKING EXISTENCE OF <{}>", resource); + + URI ldpContext = conn.getValueFactory().createURI(LDP.NAMESPACE); + Literal now = conn.getValueFactory().createLiteral(new Date()); + + // Delete corresponding containment and membership triples (Sec. 6.6.1) + RepositoryResult<Statement> stmts = conn.getStatements(null, LDP.member, resource, false, ldpContext); + try { + while (stmts.hasNext()) { + Statement st = stmts.next(); + conn.remove(st.getSubject(), DCTERMS.modified, null); + conn.add(st.getSubject(), DCTERMS.modified, now); + conn.remove(st); + } + } finally { + stmts.close(); + } + // Delete the resource meta + conn.remove(resource, null, null, ldpContext); + + // Delete the resource data + conn.clear(resource); + + conn.commit(); + return true; + } finally { + conn.close(); + } + } + } http://git-wip-us.apache.org/repos/asf/marmotta/blob/9c04ea00/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/webservices/LdpWebService.java ---------------------------------------------------------------------- diff --cc platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/webservices/LdpWebService.java index 42e6aa3,e652ec2..9fe07e6 --- a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/webservices/LdpWebService.java +++ b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/webservices/LdpWebService.java @@@ -58,8 -62,10 +58,10 @@@ import java.util.* @Path(LdpWebService.PATH + "{local:.*}") public class LdpWebService { - public static final String PATH = "ldp"; + public static final String PATH = "ldp"; //FIXME: imho this should be root '/' (jakob) + + public static final String APPLICATION_RDF_PATCH = "application/rdf-patch"; + private Logger log = org.slf4j.LoggerFactory.getLogger(this.getClass()); @Inject @@@ -74,29 -83,32 +76,27 @@@ } @GET -- public Response GET(@Context final UriInfo uriInfo, @Context Request r, @HeaderParam(HttpHeaders.ACCEPT) MediaType type) -- throws RepositoryException { ++ public Response GET(@Context final UriInfo uriInfo, @Context Request r, @HeaderParam(HttpHeaders.ACCEPT) MediaType type) throws RepositoryException { if (log.isDebugEnabled()) { - log.debug("GET to PDP-R <{}>", getResourceUri(uriInfo)); + log.debug("GET to LDPR <{}>", getResourceUri(uriInfo)); } - return doGetHead(uriInfo, r ,type).build(); + return buildResourceResponse(uriInfo, r, type).build(); } @HEAD -- public Response HEAD(@Context final UriInfo uriInfo, @Context Request r, @HeaderParam(HttpHeaders.ACCEPT) MediaType type) -- throws RepositoryException { ++ public Response HEAD(@Context final UriInfo uriInfo, @Context Request r, @HeaderParam(HttpHeaders.ACCEPT) MediaType type) throws RepositoryException { if (log.isDebugEnabled()) { - log.debug("HEAD to PDP-R <{}>", getResourceUri(uriInfo)); + log.debug("HEAD to LDPR <{}>", getResourceUri(uriInfo)); } - return doGetHead(uriInfo, r, type).entity(null).build(); + return buildResourceResponse(uriInfo, r, type).entity(null).build(); } - private Response.ResponseBuilder doGetHead(final UriInfo uriInfo, Request r, MediaType type) - throws RepositoryException { + private Response.ResponseBuilder buildResourceResponse(final UriInfo uriInfo, Request r, MediaType type) throws RepositoryException { final String subject = getResourceUri(uriInfo); - Response.ResponseBuilder rb404 = check404(subject); - if (rb404 != null) { - return createResponse(rb404, uriInfo); + if (!ldpService.exists(getResourceUri(uriInfo))) { + return Response.status(Response.Status.NOT_FOUND); } - // log.warn("NOT CHECKING EXISTENCE OF <{}>", subject); // TODO: Maybe this is a LDP-BR? // TODO: Proper content negotiation @@@ -208,18 -306,55 +204,23 @@@ */ final String resource = getResourceUri(uriInfo); log.debug("DELETE to <{}>", resource); - - final Response.ResponseBuilder rb404 = check404(resource); - if (rb404 != null) { - return rb404.build(); - } - - final RepositoryConnection con = sesameService.getConnection(); try { - con.begin(); - - URI s = con.getValueFactory().createURI(resource), - ldpContext = con.getValueFactory().createURI(LDP.NAMESPACE); - Literal now = con.getValueFactory().createLiteral(new Date()); - - // Delete corresponding containment and membership triples (Sec. 6.6.1) - RepositoryResult<Statement> stmts = con.getStatements(null, LDP.member, s, false, ldpContext); - try { - while (stmts.hasNext()) { - Statement st = stmts.next(); - con.remove(st.getSubject(), DCTERMS.modified, null); - con.add(st.getSubject(), DCTERMS.modified, now); - con.remove(st); - } - } finally { - stmts.close(); - } - // Delete the resource meta - con.remove(s, null, null, ldpContext); - - // Delete the resource data - con.clear(s); - - con.commit(); + ldpService.deleteResource(resource); return createResponse(Response.Status.NO_CONTENT, uriInfo).build(); - } finally { - con.close(); + } catch (RepositoryException e) { + log.error("Error deleting LDP-R: {}: {}", resource, e.getMessage()); + return createResponse(Response.Status.INTERNAL_SERVER_ERROR, uriInfo).entity("Error deleting LDP-R: " + e.getMessage()).build(); } - } + } @PATCH - public Response PATCH() { - public Response PATCH(@Context UriInfo uriInfo, - InputStream postBody, @HeaderParam(HttpHeaders.CONTENT_TYPE) MediaType type) { - ++ public Response PATCH(@Context UriInfo uriInfo, InputStream postBody, @HeaderParam(HttpHeaders.CONTENT_TYPE) MediaType type) { + // Check for the supported mime-type + if (!type.toString().equals(APPLICATION_RDF_PATCH)) { + return createResponse(Response.Status.BAD_REQUEST, uriInfo).entity("Unknown Content-Type: " + type + "\n").build(); + }; + return Response.status(Response.Status.NOT_IMPLEMENTED).build(); }
