All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
apoc.trigger.TriggerExtended Maven / Gradle / Ivy
package apoc.trigger;
import apoc.Description;
import apoc.Extended;
import apoc.coll.SetBackedList;
import apoc.result.VirtualNode;
import apoc.result.VirtualRelationship;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.procedure.*;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author mh
* @since 20.09.16
*/
@Extended
public class
TriggerExtended {
public static class TriggerInfo {
public String name;
public String query;
public Map selector;
public Map params;
public boolean installed;
public boolean paused;
public TriggerInfo(String name, String query, Map selector, boolean installed, boolean paused) {
this.name = name;
this.query = query;
this.selector = selector;
this.installed = installed;
this.paused = paused;
}
public TriggerInfo( String name, String query, Map selector, Map params, boolean installed, boolean paused )
{
this.name = name;
this.query = query;
this.selector = selector;
this.params = params;
this.installed = installed;
this.paused = paused;
}
}
@Context public GraphDatabaseService db;
@UserFunction
@Description("function to filter labelEntries by label, to be used within a trigger kernelTransaction with {assignedLabels}, {removedLabels}, {assigned/removedNodeProperties}")
public List nodesByLabel(@Name("labelEntries") Object entries, @Name("label") String labelString) {
if (!(entries instanceof Map)) return Collections.emptyList();
Map map = (Map) entries;
if (map.isEmpty()) return Collections.emptyList();
Object result = ((Map) entries).get(labelString);
if (result instanceof List) return (List) result;
Object anEntry = map.values().iterator().next();
if (anEntry instanceof List) {
List list = (List) anEntry;
if (!list.isEmpty()) {
if (list.get(0) instanceof Map) {
Set nodeSet = new HashSet<>(100);
Label label = labelString == null ? null : Label.label(labelString);
for (List> entry : (Collection>>) map.values()) {
for (Map propertyEntry : entry) {
Object node = propertyEntry.get("node");
if (node instanceof Node && (label == null || ((Node)node).hasLabel(label))) {
nodeSet.add((Node)node);
}
}
}
if (!nodeSet.isEmpty()) return new SetBackedList<>(nodeSet);
} else if (list.get(0) instanceof Node) {
if (labelString==null) {
Set nodeSet = new HashSet<>(map.size()*list.size());
map.values().forEach((l) -> nodeSet.addAll((Collection)l));
return new SetBackedList<>(nodeSet);
}
}
}
}
return Collections.emptyList();
}
@UserFunction
@Description("function to filter propertyEntries by property-key, to be used within a trigger kernelTransaction with {assignedNode/RelationshipProperties} and {removedNode/RelationshipProperties}. Returns [{old,new,key,node,relationship}]")
public List> propertiesByKey(@Name("propertyEntries") Map>> propertyEntries, @Name("key") String key) {
return propertyEntries.getOrDefault(key,Collections.emptyList());
}
public TriggerInfo toTriggerInfo(Map.Entry e) {
String name = e.getKey();
if (e.getValue() instanceof Map) {
try {
Map value = (Map) e.getValue();
return new TriggerInfo(name, (String) value.get("statement"), (Map) value.get("selector"), (Map) value.get("params"), false, false);
} catch(Exception ex) {
return new TriggerInfo(name, ex.getMessage(), null, false, false);
}
}
return new TriggerInfo(name, null, null, false, false);
}
@UserFunction
@Description("apoc.trigger.toNode(node, $removedLabels, $removedNodeProperties) | function to rebuild a node as a virtual, to be used in triggers with a not 'afterAsync' phase")
public Node toNode(@Name("id") Node node, @Name("removedLabels") Map> removedLabels, @Name("removedNodeProperties") Map> removedNodeProperties) {
final long id = node.getId();
final Label[] labels = removedLabels.entrySet().stream()
.filter(i -> i.getValue().stream().anyMatch(l -> l.getId() == id))
.map(e -> Label.label(e.getKey()))
.toArray(Label[]::new);
final Map props = removedNodeProperties.entrySet().stream()
.map(i -> i.getValue().stream()
.filter(l -> ((Node) l.get("node")).getId() == id)
.findAny()
.map(v -> new AbstractMap.SimpleEntry<>(i.getKey(), v.get("old"))))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
return new VirtualNode(labels, props);
}
@UserFunction
@Description("apoc.trigger.toRelationship(rel, $removedRelationshipProperties) | function to rebuild a relationship as a virtual, to be used in triggers with a not 'afterAsync' phase")
public Relationship toRelationship(@Name("id") Relationship rel, @Name("removedRelationshipProperties") Map> removedRelationshipProperties) {
final Map props = removedRelationshipProperties.entrySet().stream()
.map(i -> i.getValue().stream()
.filter(l -> ((Relationship) l.get("relationship")).getId() == rel.getId())
.findAny()
.map(v -> new AbstractMap.SimpleEntry<>(i.getKey(), v.get("old"))))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
return new VirtualRelationship(rel.getStartNode(), rel.getEndNode(), rel.getType(), props);
}
}