package de.unikiel.inf.comsys.neo4j.http; /* * #%L * neo4j-sparql-extension * %% * Copyright (C) 2014 Niclas Hoyer * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import java.nio.charset.Charset; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.openrdf.query.MalformedQueryException; import org.openrdf.query.QueryLanguage; import org.openrdf.query.Update; import org.openrdf.query.UpdateExecutionException; import org.openrdf.repository.RepositoryException; import org.openrdf.repository.sail.SailRepository; import org.openrdf.repository.sail.SailRepositoryConnection; /** * Implementation of the "update operation" part of the SPARQL 1.1 Protocol * standard. * * @see <a href="http://www.w3.org/TR/sparql11-protocol/#update-operation"> * SPARQL 1.1 Protocol * </a> */ public class SPARQLUpdate extends AbstractSailResource { private static final Logger logger = Logger.getLogger(SPARQLUpdate.class.getName()); /** * Create a new SPARQL 1.1 update resource based on a repository. * * @param rep the repository this resources operates on */ public SPARQLUpdate(SailRepository rep) { super(rep); } /** * Update via URL-encoded POST. * * @see <a href="http://www.w3.org/TR/sparql11-protocol/#update-operation"> * SPARQL 1.1 Protocol * </a> * @param query the "update" form encoded parameter * @param defgraphs the "using-graph-uri" form encoded parameter * @param namedgraphs the "using-named-graph-uri" form encoded parameter * @return "204 No Content", if the operation was successful */ @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response updatePOSTEncoded( @FormParam("update") String query, @FormParam("using-graph-uri") List<String> defgraphs, @FormParam("using-named-graph-uri") List<String> namedgraphs) { return handleUpdate(query, defgraphs, namedgraphs); } /** * Update via POST directly. * * @see <a href="http://www.w3.org/TR/sparql11-protocol/#update-operation"> * SPARQL 1.1 Protocol * </a> * @param defgraphs the "using-graph-uri" query parameter * @param namedgraphs the "using-named-graph-uri" query parameter * @param query query as string * @return "204 No Content", if the operation was successful */ @POST @Consumes(RDFMediaType.SPARQL_UPDATE) public Response updatePOSTDirect( @QueryParam("using-graph-uri") List<String> defgraphs, @QueryParam("using-named-graph-uri") List<String> namedgraphs, String query) { return handleUpdate(query, defgraphs, namedgraphs); } /** * Executes a SPARQL 1.1 update operation on a graph in the repository. * @param query the update query * @param defgraphs graph URI list for RDF dataset * @param namedgraphs named graph URI list for RDF dataset * @return "204 No Content", if the operation was successful */ private Response handleUpdate( String query, List<String> defgraphs, List<String> namedgraphs) { SailRepositoryConnection conn; try { conn = getConnection(); } catch (RepositoryException ex) { throw new WebApplicationException(ex); } try { // check if query is empty if (query == null || query.length() == 0) { throw new MalformedQueryException("empty query"); } // execute update query Update update = conn.prepareUpdate(QueryLanguage.SPARQL, query); logger.log(Level.FINER, "[BEGIN] Update transaction begin"); conn.begin(); logger.log(Level.FINER, "[EXEC] Update execution"); update.execute(); logger.log(Level.FINER, "[COMMIT] Update transaction commit"); conn.commit(); close(conn); return Response.ok().build(); } catch (MalformedQueryException ex) { // syntax error String str = ex.getMessage(); close(conn, ex); return Response.status(Response.Status.BAD_REQUEST).entity( str.getBytes(Charset.forName("UTF-8"))).build(); } catch (RepositoryException | UpdateExecutionException ex) { // server error close(conn, ex); throw new WebApplicationException(ex); } } }