package eu.lod2.rsine.service; import eu.lod2.util.ItemNotFoundException; import org.openrdf.model.Model; import org.openrdf.model.Statement; import org.openrdf.rio.RDFHandlerException; import org.openrdf.rio.RDFParseException; import org.openrdf.rio.RDFParser; import org.openrdf.rio.helpers.RDFHandlerBase; import org.openrdf.rio.turtle.TurtleParserFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; import java.io.StringReader; import java.util.Arrays; import java.util.List; import java.util.Properties; @Service public class ChangeTripleService { private final Logger logger = LoggerFactory.getLogger(ChangeTripleService.class); public static String POST_BODY_AFFECTEDTRIPLE = "affectedTriple"; public static String POST_BODY_SECONDARYTRIPLE = "secondaryTriple"; public static String POST_BODY_CHANGETYPE = "changeType"; public static String CHANGETYPE_ADD = "add"; public static String CHANGETYPE_REMOVE = "remove"; public static String CHANGETYPE_UPDATE = "update"; @Autowired private ChangeSetCreator changeSetCreator; @Autowired private PersistAndNotifyProvider persistAndNotifyProvider; void handleAnnouncedTriple(String announceTriple) throws IOException, RDFParseException, RDFHandlerException { logger.debug("Incoming triple change announcement: " +announceTriple); Properties properties = new Properties(); properties.load(new StringReader(announceTriple)); String changeType = getValueForName(POST_BODY_CHANGETYPE, properties); List<Statement> triples = extractStatements(properties, changeType); Model changeSet = changeSetCreator.assembleChangeset(triples.get(0), triples.get(1), changeType); persistAndNotifyProvider.persistAndNotify(changeSet, false); } private String getValueForName(String key, Properties properties) { String value = properties.getProperty(key); if (value == null) { throw new ItemNotFoundException("Key '" +key+ "' not found in request properties"); } return value; } private List<Statement> extractStatements(Properties properties, String changeType) throws RDFParseException, IOException, RDFHandlerException { Statement secondaryTriple = null; Statement affectedTriple = createStatement(getValueForName(POST_BODY_AFFECTEDTRIPLE, properties)); try { secondaryTriple = createStatement(getValueForName(POST_BODY_SECONDARYTRIPLE, properties)); } catch (ItemNotFoundException e) { if (changeType.equals(CHANGETYPE_UPDATE)) { throw e; } } return Arrays.asList(affectedTriple, secondaryTriple); } private Statement createStatement(String triple) throws RDFParseException, IOException, RDFHandlerException { RDFParser parser = new TurtleParserFactory().getParser(); SingleStatementHandler singleStatementHandler = new SingleStatementHandler(); parser.setRDFHandler(singleStatementHandler); parser.parse(new StringReader(triple.trim()), "http://some.base.uri/"); return singleStatementHandler.getStatement(); } private class SingleStatementHandler extends RDFHandlerBase { private Statement statement; @Override public void handleStatement(Statement st) throws RDFHandlerException { statement = st; } Statement getStatement() { if (statement == null) throw new ItemNotFoundException("No statement parsed"); return statement; } } }