apoc.graph.util.GraphsConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apoc-common Show documentation
Show all versions of apoc-common Show documentation
Data types package for Neo4j Procedures
package apoc.graph.util;
import org.apache.commons.collections4.MapUtils;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static apoc.util.Util.toBoolean;
public class GraphsConfig {
private static final Pattern MAPPING_PATTERN = Pattern.compile("^(\\w+\\s*(?::\\s*(?:\\w+)\\s*)*)\\s*(?:\\{\\s*(-?[\\*\\w!@\\.]+\\s*(?:,\\s*-?[!@\\w\\*\\.]+\\s*)*)\\})?$");
public static class GraphMapping {
private static final String IDS = "ids";
private static final String VALUE_OBJECTS = "valueObjects";
private static final String PROPERTIES = "properties";
private static final String WILDCARD = "*";
private List valueObjects = new ArrayList<>();
private List ids = new ArrayList<>();
private List properties = new ArrayList<>();
private List labels = new ArrayList<>();
private boolean allProps = true;
static final GraphMapping EMPTY = new GraphMapping();
GraphMapping(List valueObjects, List ids, List properties, List labels, boolean allProps) {
this.allProps = allProps;
if (valueObjects != null) this.valueObjects.addAll(valueObjects);
if (ids != null) this.ids.addAll(ids);
if (labels != null) this.labels.addAll(labels);
if (!this.allProps) {
if (properties != null) this.properties.addAll(properties);
this.properties.addAll(this.ids);
this.properties.addAll(this.valueObjects);
}
}
GraphMapping() {}
public List getValueObjects() {
return valueObjects;
}
public List getIds() {
return ids;
}
public List getProperties() {
return properties;
}
public List getLabels() {
return labels;
}
public boolean isAllProps() {
return allProps;
}
public static GraphMapping from(String pattern) {
Matcher matcher = MAPPING_PATTERN.matcher(pattern);
if (!matcher.matches()) {
throw new RuntimeException("The provided pattern " + pattern + " does not match the requirements");
}
List labels = Arrays.asList(matcher.group(1).split(":"));
AtomicBoolean allProps = new AtomicBoolean(false);
Map> map = Stream.of(matcher.group(2).split(","))
.map(s -> {
String value = s.trim();
String key;
if (value.startsWith("@")) {
key = VALUE_OBJECTS;
value = value.substring(1);
} else if (value.startsWith("!")) {
key = IDS;
value = value.substring(1);
} else {
key = PROPERTIES;
}
if (WILDCARD.equals(value) && key.equals(PROPERTIES)) {
allProps.set(true);
return null;
} else {
return new AbstractMap.SimpleEntry<>(key, value);
}
})
.filter(e -> e != null)
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
return new GraphMapping(map.get(VALUE_OBJECTS), map.get(IDS), map.get(PROPERTIES), labels, allProps.get());
}
}
private boolean write;
private String labelField;
private String idField;
private boolean generateId;
private Map mappings;
private Map relMapping;
private boolean skipValidation;
public GraphsConfig(Map config) {
if (config == null) {
config = Collections.emptyMap();
}
write = toBoolean(config.getOrDefault("write", false));
generateId = toBoolean(config.getOrDefault("generateId", true));
idField = config.getOrDefault("idField", "id").toString();
labelField = config.getOrDefault("labelField", "type").toString();
mappings = toMappings((Map) config.getOrDefault("mappings", Collections.emptyMap()));
skipValidation = toBoolean(config.getOrDefault("skipValidation", false));
relMapping = MapUtils.emptyIfNull((Map) config.get("relMapping"));
}
private Map toMappings(Map mappings) {
return mappings.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), GraphMapping.from(e.getValue())))
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
}
public boolean isWrite() {
return write;
}
public String getLabelField() {
return labelField;
}
public String getIdField() {
return idField;
}
public boolean isGenerateId() {
return generateId;
}
public Map getRelMapping() {
return relMapping;
}
public boolean isSkipValidation() {
return skipValidation;
}
public List valueObjectForPath(String path) {
return mappings.getOrDefault(path, GraphMapping.EMPTY).getValueObjects();
}
public List idsForPath(String path) {
return mappings.getOrDefault(path, GraphMapping.EMPTY).getIds();
}
public List labelsForPath(String path) {
return mappings.getOrDefault(path, GraphMapping.EMPTY).getLabels();
}
public List propertiesForPath(String path) {
if (allPropertiesForPath(path)) {
return Collections.emptyList();
}
// We also need to consider the properties defined in the mapping fields
final List pathProperties = mappings.keySet()
.stream()
.filter(key -> key.startsWith(path))
.map(key -> path.length() >= key.length() ? "" : key.substring(path.length() + 1))
.map(key -> key.split("\\.")[0])
.filter(key -> !key.isEmpty())
.collect(Collectors.toList());
List properties = mappings.getOrDefault(path, GraphMapping.EMPTY).getProperties();
properties.addAll(pathProperties);
return properties;
}
public boolean allPropertiesForPath(String path) {
return mappings.getOrDefault(path, GraphMapping.EMPTY).isAllProps();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy