/** * This file is part of d:swarm graph extension. * * d:swarm graph extension 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. * * d:swarm graph extension 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 d:swarm graph extension. If not, see <http://www.gnu.org/licenses/>. */ package org.dswarm.graph.delta.util; import java.util.HashSet; import java.util.Set; import org.dswarm.graph.DMPGraphException; import org.dswarm.graph.delta.DeltaState; import org.dswarm.graph.delta.DeltaStatics; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.Transaction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Sets; /** * @author tgaengler */ public final class GraphDBMarkUtil { private static final Logger LOG = LoggerFactory.getLogger(GraphDBMarkUtil.class); public static void markPaths(final DeltaState deltaState, final GraphDatabaseService graphDB, final String prefixedResourceURI, final Set<Long> pathEndNodeIds) throws DMPGraphException { try(final Transaction tx = graphDB.beginTx()) { final Iterable<Path> paths = GraphDBUtil.getResourcePaths(graphDB, prefixedResourceURI); markPaths(deltaState, pathEndNodeIds, paths); tx.success(); } catch (final Exception e) { final String message = "couldn't mark paths successfully"; GraphDBMarkUtil.LOG.error(message, e); throw new DMPGraphException(message, e); } } public static void markPaths(final DeltaState deltaState, final GraphDatabaseService graphDB, final long nodeId, final Set<Long> pathEndNodeIds) throws DMPGraphException { try(final Transaction tx = graphDB.beginTx()) { final Iterable<Path> paths = GraphDBUtil.getEntityPaths(graphDB, nodeId); markPaths(deltaState, pathEndNodeIds, paths); tx.success(); } catch (final Exception e) { final String message = "couldn't mark paths successfully"; GraphDBMarkUtil.LOG.error(message, e); throw new DMPGraphException(message); } } private static void markPaths(final DeltaState deltaState, final Set<Long> pathEndNodeIds, final Iterable<Path> paths) throws DMPGraphException { final Set<Long> markedPathEndNodeIds = Sets.newHashSet(); for (final Path path : paths) { final long pathEndNodeId = path.endNode().getId(); if (pathEndNodeIds.contains(pathEndNodeId)) { markedPathEndNodeIds.add(pathEndNodeId); // mark path for (final Relationship rel : path.relationships()) { if (!rel.hasProperty(DeltaStatics.DELTA_STATE_PROPERTY)) { rel.setProperty(DeltaStatics.DELTA_STATE_PROPERTY, deltaState.toString()); } // TODO: remove this later, it'S just for debugging purpose right now // http://www.w3.org/1999/02/22-rdf-syntax-ns#type if (rel.getType().name().equals("rdf:type")) { GraphDBMarkUtil.LOG.debug("mark rel: {}", GraphDBPrintUtil.printDeltaRelationship(rel)); } rel.setProperty(DeltaStatics.MATCHED_PROPERTY, true); } for (final Node node : path.nodes()) { if (!node.hasProperty(DeltaStatics.DELTA_STATE_PROPERTY)) { node.setProperty(DeltaStatics.DELTA_STATE_PROPERTY, deltaState.toString()); } else if (deltaState.equals(DeltaState.ExactMatch)) { final String deltaStateString = (String) node.getProperty(DeltaStatics.DELTA_STATE_PROPERTY); final DeltaState currentDeltaState = DeltaState.getByName(deltaStateString); switch (currentDeltaState) { case ADDITION: case DELETION: case MODIFICATION: // modify delta state if a "higher" delta state was determined node.setProperty(DeltaStatics.DELTA_STATE_PROPERTY, deltaState.toString()); break; } } node.setProperty(DeltaStatics.MATCHED_PROPERTY, true); } } } if (pathEndNodeIds.size() != markedPathEndNodeIds.size()) { GraphDBMarkUtil.LOG.error("couldn't mark all paths; path end node ids size = '{}' :: marked path end node ids size = '{}'", pathEndNodeIds.size(), markedPathEndNodeIds.size()); for (final Long pathEndNodeId : pathEndNodeIds) { if (!markedPathEndNodeIds.contains(pathEndNodeId)) { GraphDBMarkUtil.LOG.error("couldn't mark path with end node id = '{}'", pathEndNodeId); } } } } /** * note: we may need to find a better way to handle those statements * * @param graphDB * @param nodeId */ private static void markEntityTypeNodes(final GraphDatabaseService graphDB, final DeltaState deltaState, final long nodeId) throws DMPGraphException { final Set<Long> pathEndNodeIds = new HashSet<>(); GraphDBUtil.fetchEntityTypeNodes(graphDB, pathEndNodeIds, nodeId); markPaths(deltaState, graphDB, nodeId, pathEndNodeIds); } }