package io.lumify.core.model.termMention;
import com.google.inject.Inject;
import io.lumify.core.model.PropertyJustificationMetadata;
import io.lumify.core.model.SourceInfo;
import io.lumify.core.model.properties.LumifyProperties;
import io.lumify.core.model.user.AuthorizationRepository;
import io.lumify.core.security.LumifyVisibility;
import io.lumify.core.util.LumifyLogger;
import io.lumify.core.util.LumifyLoggerFactory;
import org.securegraph.*;
import org.securegraph.mutation.ExistingElementMutation;
import org.securegraph.util.FilterIterable;
import org.securegraph.util.JoinIterable;
import static org.securegraph.util.IterableUtils.single;
import static org.securegraph.util.IterableUtils.singleOrDefault;
public class TermMentionRepository {
private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(TermMentionRepository.class);
public static final String VISIBILITY_STRING = "termMention";
public static final String OWL_IRI = "http://lumify.io/termMention";
private final Graph graph;
private final AuthorizationRepository authorizationRepository;
@Inject
public TermMentionRepository(Graph graph, AuthorizationRepository authorizationRepository) {
this.graph = graph;
this.authorizationRepository = authorizationRepository;
authorizationRepository.addAuthorizationToGraph(VISIBILITY_STRING);
}
public Iterable<Vertex> findBySourceGraphVertexAndPropertyKey(String sourceVertexId, final String propertyKey, Authorizations authorizations) {
authorizations = getAuthorizations(authorizations);
return new FilterIterable<Vertex>(findBySourceGraphVertex(sourceVertexId, authorizations)) {
@Override
protected boolean isIncluded(Vertex v) {
String vertexPropertyKey = LumifyProperties.TERM_MENTION_PROPERTY_KEY.getPropertyValue(v);
return propertyKey.equals(vertexPropertyKey);
}
};
}
public Iterable<Vertex> findBySourceGraphVertex(String sourceVertexId, Authorizations authorizations) {
Authorizations authorizationsWithTermMention = getAuthorizations(authorizations);
Vertex sourceVertex = graph.getVertex(sourceVertexId, authorizationsWithTermMention);
return sourceVertex.getVertices(Direction.OUT, LumifyProperties.TERM_MENTION_LABEL_HAS_TERM_MENTION, authorizationsWithTermMention);
}
/**
* Find all term mentions connected to the vertex.
*/
public Iterable<Vertex> findByVertexId(String vertexId, Authorizations authorizations) {
Authorizations authorizationsWithTermMention = getAuthorizations(authorizations);
Vertex vertex = graph.getVertex(vertexId, authorizationsWithTermMention);
String[] labels = new String[]{
LumifyProperties.TERM_MENTION_LABEL_HAS_TERM_MENTION,
LumifyProperties.TERM_MENTION_LABEL_RESOLVED_TO
};
return vertex.getVertices(Direction.BOTH, labels, authorizationsWithTermMention);
}
/**
* Find all term mentions connected to either side of the edge.
*/
public Iterable<Vertex> findByEdge(Edge edge, Authorizations authorizations) {
return new JoinIterable<>(
findByVertexId(edge.getVertexId(Direction.IN), authorizations),
findByVertexId(edge.getVertexId(Direction.OUT), authorizations)
);
}
/**
* Finds term mention vertices that were created for the justification of a new vertex.
*
* @param vertexId The vertex id of the vertex with the justification.
* @return term mention vertices matching the criteria.
*/
public Iterable<Vertex> findByVertexIdForVertex(final String vertexId, Authorizations authorizations) {
return new FilterIterable<Vertex>(findByVertexId(vertexId, authorizations)) {
@Override
protected boolean isIncluded(Vertex termMention) {
String forElementId = LumifyProperties.TERM_MENTION_FOR_ELEMENT_ID.getPropertyValue(termMention);
if (forElementId == null || !forElementId.equals(vertexId)) {
return false;
}
TermMentionFor forType = LumifyProperties.TERM_MENTION_FOR_TYPE.getPropertyValue(termMention);
if (forType == null || forType != TermMentionFor.VERTEX) {
return false;
}
return true;
}
};
}
/**
* Finds term mention vertices that were created for the justification of a new edge.
*
* @param edge The edge id of the edge with the justification.
* @return term mention vertices matching the criteria.
*/
public Iterable<Vertex> findByEdgeForEdge(final Edge edge, Authorizations authorizations) {
return new FilterIterable<Vertex>(findByEdge(edge, authorizations)) {
@Override
protected boolean isIncluded(Vertex termMention) {
String forElementId = LumifyProperties.TERM_MENTION_FOR_ELEMENT_ID.getPropertyValue(termMention);
if (forElementId == null || !forElementId.equals(edge.getId())) {
return false;
}
TermMentionFor forType = LumifyProperties.TERM_MENTION_FOR_TYPE.getPropertyValue(termMention);
if (forType == null || forType != TermMentionFor.EDGE) {
return false;
}
return true;
}
};
}
/**
* Finds all term mentions connected to a vertex that match propertyKey, propertyName, and propertyVisibility.
*/
public Iterable<Vertex> findByVertexIdAndProperty(final String vertexId, final String propertyKey, final String propertyName, final Visibility propertyVisibility, Authorizations authorizations) {
return new FilterIterable<Vertex>(findByVertexId(vertexId, authorizations)) {
@Override
protected boolean isIncluded(Vertex termMention) {
String forElementId = LumifyProperties.TERM_MENTION_FOR_ELEMENT_ID.getPropertyValue(termMention);
if (forElementId == null || !forElementId.equals(vertexId)) {
return false;
}
return isTermMentionForProperty(termMention, propertyKey, propertyName, propertyVisibility);
}
};
}
/**
* Finds all term mentions connected to either side of an edge that match propertyKey, propertyName, and propertyVisibility.
*/
public Iterable<Vertex> findByEdgeIdAndProperty(final Edge edge, final String propertyKey, final String propertyName, final Visibility propertyVisibility, Authorizations authorizations) {
return new FilterIterable<Vertex>(findByEdge(edge, authorizations)) {
@Override
protected boolean isIncluded(Vertex termMention) {
String forElementId = LumifyProperties.TERM_MENTION_FOR_ELEMENT_ID.getPropertyValue(termMention);
if (forElementId == null || !forElementId.equals(edge.getId())) {
return false;
}
return isTermMentionForProperty(termMention, propertyKey, propertyName, propertyVisibility);
}
};
}
private boolean isTermMentionForProperty(Vertex termMention, String propertyKey, String propertyName, Visibility propertyVisibility) {
TermMentionFor forType = LumifyProperties.TERM_MENTION_FOR_TYPE.getPropertyValue(termMention);
if (forType == null || forType != TermMentionFor.PROPERTY) {
return false;
}
String refPropertyKey = LumifyProperties.TERM_MENTION_REF_PROPERTY_KEY.getPropertyValue(termMention);
if (refPropertyKey == null || !refPropertyKey.equals(propertyKey)) {
return false;
}
String refPropertyName = LumifyProperties.TERM_MENTION_REF_PROPERTY_NAME.getPropertyValue(termMention);
if (refPropertyName == null || !refPropertyName.equals(propertyName)) {
return false;
}
String refPropertyVisibilityString = LumifyProperties.TERM_MENTION_REF_PROPERTY_VISIBILITY.getPropertyValue(termMention);
if (refPropertyVisibilityString == null || !refPropertyVisibilityString.equals(propertyVisibility.getVisibilityString())) {
return false;
}
return true;
}
public Vertex findById(String termMentionId, Authorizations authorizations) {
Authorizations authorizationsWithTermMention = getAuthorizations(authorizations);
return graph.getVertex(termMentionId, authorizationsWithTermMention);
}
public void updateVisibility(Vertex termMention, Visibility newVisibility, Authorizations authorizations) {
Authorizations authorizationsWithTermMention = getAuthorizations(authorizations);
Visibility newVisibilityWithTermMention = LumifyVisibility.and(newVisibility, VISIBILITY_STRING);
ExistingElementMutation<Vertex> m = termMention.prepareMutation();
m.alterElementVisibility(newVisibilityWithTermMention);
for (Property property : termMention.getProperties()) {
m.alterPropertyVisibility(property, newVisibilityWithTermMention);
}
Property refPropertyVisibility = LumifyProperties.TERM_MENTION_REF_PROPERTY_VISIBILITY.getProperty(termMention);
if (refPropertyVisibility != null) {
LumifyProperties.TERM_MENTION_REF_PROPERTY_VISIBILITY.setProperty(m, newVisibility.getVisibilityString(), refPropertyVisibility.getMetadata(), newVisibilityWithTermMention);
}
m.save(authorizationsWithTermMention);
for (Edge edge : termMention.getEdges(Direction.BOTH, authorizationsWithTermMention)) {
ExistingElementMutation<Edge> edgeMutation = edge.prepareMutation();
edgeMutation.alterElementVisibility(newVisibilityWithTermMention);
for (Property property : edge.getProperties()) {
edgeMutation.alterPropertyVisibility(property, newVisibilityWithTermMention);
}
edgeMutation.save(authorizationsWithTermMention);
}
}
public Iterable<Vertex> findResolvedTo(String destVertexId, Authorizations authorizations) {
Authorizations authorizationsWithTermMention = getAuthorizations(authorizations);
Vertex destVertex = graph.getVertex(destVertexId, authorizationsWithTermMention);
return destVertex.getVertices(Direction.IN, LumifyProperties.TERM_MENTION_LABEL_RESOLVED_TO, authorizationsWithTermMention);
}
public void delete(Vertex termMention, Authorizations authorizations) {
Authorizations authorizationsWithTermMention = getAuthorizations(authorizations);
graph.removeVertex(termMention, authorizationsWithTermMention);
}
public void markHidden(Vertex termMention, Visibility hiddenVisibility, Authorizations authorizations) {
Authorizations authorizationsWithTermMention = getAuthorizations(authorizations);
graph.markVertexHidden(termMention, hiddenVisibility, authorizationsWithTermMention);
}
public Iterable<Vertex> findByEdgeId(String sourceVertexId, final String edgeId, Authorizations authorizations) {
Authorizations authorizationsWithTermMention = getAuthorizations(authorizations);
Vertex sourceVertex = graph.getVertex(sourceVertexId, authorizationsWithTermMention);
return new FilterIterable<Vertex>(sourceVertex.getVertices(Direction.OUT, LumifyProperties.TERM_MENTION_LABEL_HAS_TERM_MENTION, authorizationsWithTermMention)) {
@Override
protected boolean isIncluded(Vertex v) {
String vertexEdgeId = LumifyProperties.TERM_MENTION_RESOLVED_EDGE_ID.getPropertyValue(v);
return edgeId.equals(vertexEdgeId);
}
};
}
public Vertex findSourceVertex(Vertex termMention, Authorizations authorizations) {
Authorizations authorizationsWithTermMention = getAuthorizations(authorizations);
return singleOrDefault(termMention.getVertices(Direction.IN, LumifyProperties.TERM_MENTION_LABEL_HAS_TERM_MENTION, authorizationsWithTermMention), null);
}
public Authorizations getAuthorizations(Authorizations authorizations) {
return authorizationRepository.createAuthorizations(authorizations, VISIBILITY_STRING);
}
public void addJustification(
Vertex vertex,
String justificationText,
SourceInfo sourceInfo,
LumifyVisibility lumifyVisibility,
Authorizations authorizations
) {
if (justificationText != null) {
PropertyJustificationMetadata propertyJustificationMetadata = new PropertyJustificationMetadata(justificationText);
removeSourceInfoEdgeFromVertex(vertex.getId(), vertex.getId(), null, null, lumifyVisibility, authorizations);
LumifyProperties.JUSTIFICATION.setProperty(vertex, propertyJustificationMetadata, lumifyVisibility.getVisibility(), authorizations);
} else if (sourceInfo != null) {
Vertex sourceVertex = graph.getVertex(sourceInfo.getVertexId(), authorizations);
LumifyProperties.JUSTIFICATION.removeProperty(vertex, authorizations);
addSourceInfoToVertex(
vertex,
sourceInfo.getVertexId(),
TermMentionFor.VERTEX,
null,
null,
null,
sourceInfo.getSnippet(),
sourceInfo.getTextPropertyKey(),
sourceInfo.getStartOffset(),
sourceInfo.getEndOffset(),
sourceVertex,
lumifyVisibility.getVisibility(),
authorizations
);
}
}
public <T extends Element> void addSourceInfo(
T element,
String forElementId,
TermMentionFor forType,
String propertyKey,
String propertyName,
Visibility propertyVisibility,
String snippet,
String textPropertyKey,
long startOffset,
long endOffset,
Vertex sourceVertex,
Visibility visibility,
Authorizations authorizations
) {
if (element instanceof Vertex) {
addSourceInfoToVertex(
(Vertex) element,
forElementId,
forType,
propertyKey,
propertyName,
propertyVisibility,
snippet,
textPropertyKey,
startOffset,
endOffset,
sourceVertex,
visibility,
authorizations
);
} else {
addSourceInfoEdgeToEdge(
(Edge) element,
forElementId,
forType,
propertyKey,
propertyName,
propertyVisibility,
snippet,
textPropertyKey,
startOffset,
endOffset,
sourceVertex,
visibility,
authorizations
);
}
}
public void addSourceInfoToVertex(
Vertex vertex,
String forElementId,
TermMentionFor forType,
String propertyKey,
String propertyName,
Visibility propertyVisibility,
String snippet,
String textPropertyKey,
long startOffset,
long endOffset,
Vertex sourceVertex,
Visibility visibility,
Authorizations authorizations
) {
visibility = LumifyVisibility.and(visibility, VISIBILITY_STRING);
String termMentionVertexId = vertex.getId() + "hasSource" + sourceVertex.getId();
if (propertyKey != null) {
termMentionVertexId += ":" + propertyKey;
}
if (propertyName != null) {
termMentionVertexId += ":" + propertyName;
}
if (propertyVisibility != null) {
termMentionVertexId += ":" + propertyVisibility;
}
VertexBuilder m = graph.prepareVertex(termMentionVertexId, visibility);
LumifyProperties.TERM_MENTION_FOR_ELEMENT_ID.setProperty(m, forElementId, visibility);
LumifyProperties.TERM_MENTION_FOR_TYPE.setProperty(m, forType, visibility);
if (propertyKey != null) {
LumifyProperties.TERM_MENTION_REF_PROPERTY_KEY.setProperty(m, propertyKey, visibility);
}
if (propertyName != null) {
LumifyProperties.TERM_MENTION_REF_PROPERTY_NAME.setProperty(m, propertyName, visibility);
}
if (propertyVisibility != null) {
LumifyProperties.TERM_MENTION_REF_PROPERTY_VISIBILITY.setProperty(m, propertyVisibility.getVisibilityString(), visibility);
}
LumifyProperties.TERM_MENTION_SNIPPET.setProperty(m, snippet, visibility);
LumifyProperties.TERM_MENTION_PROPERTY_KEY.setProperty(m, textPropertyKey, visibility);
LumifyProperties.TERM_MENTION_START_OFFSET.setProperty(m, startOffset, visibility);
LumifyProperties.TERM_MENTION_END_OFFSET.setProperty(m, endOffset, visibility);
Vertex termMention = m.save(authorizations);
graph.addEdge(LumifyProperties.TERM_MENTION_LABEL_HAS_TERM_MENTION + termMentionVertexId, sourceVertex, termMention, LumifyProperties.TERM_MENTION_LABEL_HAS_TERM_MENTION, visibility, authorizations);
graph.addEdge(LumifyProperties.TERM_MENTION_LABEL_RESOLVED_TO + termMentionVertexId, termMention, vertex, LumifyProperties.TERM_MENTION_LABEL_RESOLVED_TO, visibility, authorizations);
graph.flush();
LOGGER.debug("added source info: %s", termMention.getId());
}
public void addSourceInfoEdgeToEdge(
Edge edge,
String forElementId,
TermMentionFor forType,
String propertyKey,
String propertyName,
Visibility propertyVisibility,
String snippet,
String textPropertyKey,
long startOffset,
long endOffset,
Vertex sourceVertex,
Visibility visibility,
Authorizations authorizations
) {
Vertex inVertex = edge.getVertex(Direction.IN, authorizations);
Vertex outVertex = edge.getVertex(Direction.OUT, authorizations);
addSourceInfoToVertex(
inVertex,
forElementId,
forType,
propertyKey,
propertyName,
propertyVisibility,
snippet,
textPropertyKey,
startOffset,
endOffset,
sourceVertex,
visibility,
authorizations
);
addSourceInfoToVertex(
outVertex,
forElementId,
forType,
propertyKey,
propertyName,
propertyVisibility,
snippet,
textPropertyKey,
startOffset,
endOffset,
sourceVertex,
visibility,
authorizations
);
}
public void removeSourceInfoEdge(Element element, String propertyKey, String propertyName, LumifyVisibility lumifyVisibility, Authorizations authorizations) {
if (element instanceof Vertex) {
removeSourceInfoEdgeFromVertex(element.getId(), element.getId(), propertyKey, propertyName, lumifyVisibility, authorizations);
} else {
removeSourceInfoEdgeFromEdge((Edge) element, propertyKey, propertyName, lumifyVisibility, authorizations);
}
}
public void removeSourceInfoEdgeFromVertex(String vertexId, String sourceInfoElementId, String propertyKey, String propertyName, LumifyVisibility lumifyVisibility, Authorizations authorizations) {
Vertex termMention = findTermMention(vertexId, sourceInfoElementId, propertyKey, propertyName, lumifyVisibility.getVisibility(), authorizations);
if (termMention != null) {
graph.removeVertex(termMention, authorizations);
}
}
public void removeSourceInfoEdgeFromEdge(Edge edge, String propertyKey, String propertyName, LumifyVisibility lumifyVisibility, Authorizations authorizations) {
String inVertexId = edge.getVertexId(Direction.IN);
String outVertexId = edge.getVertexId(Direction.OUT);
removeSourceInfoEdgeFromVertex(inVertexId, edge.getId(), propertyKey, propertyName, lumifyVisibility, authorizations);
removeSourceInfoEdgeFromVertex(outVertexId, edge.getId(), propertyKey, propertyName, lumifyVisibility, authorizations);
}
private Vertex findTermMention(String vertexId, String forElementId, String propertyKey, String propertyName, Visibility propertyVisibility, Authorizations authorizations) {
Authorizations authorizationsWithTermMentions = getAuthorizations(authorizations);
Vertex vertex = graph.getVertex(vertexId, authorizationsWithTermMentions);
Iterable<Vertex> termMentions = vertex.getVertices(Direction.IN, LumifyProperties.TERM_MENTION_LABEL_RESOLVED_TO, authorizationsWithTermMentions);
for (Vertex termMention : termMentions) {
if (forElementId != null && !forElementId.equals(LumifyProperties.TERM_MENTION_FOR_ELEMENT_ID.getPropertyValue(termMention))) {
continue;
}
if (propertyKey != null && !propertyKey.equals(LumifyProperties.TERM_MENTION_REF_PROPERTY_KEY.getPropertyValue(termMention))) {
continue;
}
if (propertyName != null && !propertyName.equals(LumifyProperties.TERM_MENTION_REF_PROPERTY_NAME.getPropertyValue(termMention))) {
continue;
}
if (propertyVisibility != null && !propertyVisibility.toString().equals(LumifyProperties.TERM_MENTION_REF_PROPERTY_VISIBILITY.getPropertyValue(termMention))) {
continue;
}
return termMention;
}
return null;
}
public SourceInfo getSourceInfoForEdge(Edge edge, Authorizations authorizations) {
String inVertexId = edge.getVertexId(Direction.IN);
Vertex termMention = findTermMention(inVertexId, edge.getId(), null, null, null, authorizations);
return getSourceInfoFromTermMention(termMention, authorizations);
}
public SourceInfo getSourceInfoForVertex(Vertex vertex, Authorizations authorizations) {
Vertex termMention = findTermMention(vertex.getId(), vertex.getId(), null, null, null, authorizations);
return getSourceInfoFromTermMention(termMention, authorizations);
}
public SourceInfo getSourceInfoForEdgeProperty(Edge edge, String propertyKey, String propertyName, Visibility visibility, Authorizations authorizations) {
String inVertexId = edge.getVertexId(Direction.IN);
Vertex termMention = findTermMention(inVertexId, edge.getId(), propertyKey, propertyName, visibility, authorizations);
return getSourceInfoFromTermMention(termMention, authorizations);
}
public SourceInfo getSourceInfoForVertexProperty(String vertexId, Property property, Authorizations authorizations) {
Vertex termMention = findTermMention(vertexId, vertexId, property.getKey(), property.getName(), property.getVisibility(), authorizations);
return getSourceInfoFromTermMention(termMention, authorizations);
}
private SourceInfo getSourceInfoFromTermMention(Vertex termMention, Authorizations authorizations) {
if (termMention == null) {
return null;
}
String vertexId = single(termMention.getVertexIds(Direction.IN, LumifyProperties.TERM_MENTION_LABEL_HAS_TERM_MENTION, authorizations));
String textPropertyKey = LumifyProperties.TERM_MENTION_PROPERTY_KEY.getPropertyValue(termMention);
long startOffset = LumifyProperties.TERM_MENTION_START_OFFSET.getPropertyValue(termMention);
long endOffset = LumifyProperties.TERM_MENTION_END_OFFSET.getPropertyValue(termMention);
String snippet = LumifyProperties.TERM_MENTION_SNIPPET.getPropertyValue(termMention);
return new SourceInfo(vertexId, textPropertyKey, startOffset, endOffset, snippet);
}
}