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.util.Util Maven / Gradle / Ivy
package apoc.util;
import apoc.ApocConfiguration;
import apoc.Pools;
import apoc.path.RelationshipTypeAndDirections;
import org.neo4j.collection.primitive.PrimitiveLongIterator;
import org.neo4j.graphdb.*;
import org.neo4j.helpers.collection.Iterables;
import org.neo4j.helpers.collection.Pair;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.internal.GraphDatabaseAPI;
import org.neo4j.logging.Log;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.*;
import java.util.stream.*;
import java.util.zip.DeflaterInputStream;
import java.util.zip.GZIPInputStream;
import static java.lang.String.format;
/**
* @author mh
* @since 24.04.16
*/
public class Util {
public static final Label[] NO_LABELS = new Label[0];
public static final String NODE_COUNT = "MATCH (n) RETURN count(*) as result";
public static final String REL_COUNT = "MATCH ()-->() RETURN count(*) as result";
public static final String COMPILED = "compiledExperimentalFeatureNotSupportedForProductionUse";
public static String labelString(Node n) {
return StreamSupport.stream(n.getLabels().spliterator(),false).map(Label::name).sorted().collect(Collectors.joining(":"));
}
public static List labelStrings(Node n) {
return StreamSupport.stream(n.getLabels().spliterator(),false).map(Label::name).sorted().collect(Collectors.toList());
}
public static Label[] labels(Object labelNames) {
if (labelNames==null) return NO_LABELS;
if (labelNames instanceof List) {
List names = (List) labelNames;
Label[] labels = new Label[names.size()];
int i = 0;
for (Object l : names) {
if (l==null) continue;
labels[i++] = Label.label(l.toString());
}
if (i <= labels.length) return Arrays.copyOf(labels,i);
return labels;
}
return new Label[]{Label.label(labelNames.toString())};
}
public static RelationshipType type(Object type) {
if (type == null) throw new RuntimeException("No relationship-type provided");
return RelationshipType.withName(type.toString());
}
@SuppressWarnings("unchecked")
public static LongStream ids(Object ids) {
if (ids == null) return LongStream.empty();
if (ids instanceof Number) return LongStream.of(((Number)ids).longValue());
if (ids instanceof Node) return LongStream.of(((Node)ids).getId());
if (ids instanceof Relationship) return LongStream.of(((Relationship)ids).getId());
if (ids instanceof Collection) {
Collection coll = (Collection) ids;
return coll.stream().mapToLong( (o) -> ((Number)o).longValue());
}
if (ids instanceof Iterable) {
Spliterator spliterator = ((Iterable) ids).spliterator();
return StreamSupport.stream(spliterator,false).mapToLong( (o) -> ((Number)o).longValue());
}
throw new RuntimeException("Can't convert "+ids.getClass()+" to a stream of long ids");
}
public static Stream stream(Object values) {
if (values == null) return Stream.empty();
if (values instanceof Collection) return ((Collection)values).stream();
if (values instanceof Object[]) return Stream.of(((Object[])values));
if (values instanceof Iterable) {
Spliterator spliterator = ((Iterable) values).spliterator();
return StreamSupport.stream(spliterator,false);
}
return Stream.of(values);
}
public static Stream nodeStream(GraphDatabaseService db, Object ids) {
return stream(ids).map(id -> node(db, id));
}
public static Node node(GraphDatabaseService db, Object id) {
if (id instanceof Node) return (Node)id;
if (id instanceof Number) return db.getNodeById(((Number)id).longValue());
throw new RuntimeException("Can't convert "+id.getClass()+" to a Node");
}
public static Stream relsStream(GraphDatabaseService db, Object ids) {
return stream(ids).map(id -> relationship(db, id));
}
public static Relationship relationship(GraphDatabaseService db, Object id) {
if (id instanceof Relationship) return (Relationship)id;
if (id instanceof Number) return db.getRelationshipById(((Number)id).longValue());
throw new RuntimeException("Can't convert "+id.getClass()+" to a Relationship");
}
public static double doubleValue(PropertyContainer pc, String prop, Number defaultValue) {
return toDouble(pc.getProperty(prop, defaultValue));
}
public static double doubleValue(PropertyContainer pc, String prop) {
return doubleValue(pc, prop, 0);
}
public static Direction parseDirection(String direction) {
if (null == direction) {
return Direction.BOTH;
}
try {
return Direction.valueOf(direction.toUpperCase());
} catch (Exception e) {
throw new RuntimeException(format("Cannot convert value '%s' to Direction. Legal values are '%s'",
direction, Arrays.toString(Direction.values())));
}
}
public static RelationshipType[] toRelTypes(List relTypeStrings) {
RelationshipType[] relTypes = new RelationshipType[relTypeStrings.size()];
for (int i = 0; i < relTypes.length; i++) {
relTypes[i] = RelationshipType.withName(relTypeStrings.get(i));
}
return relTypes;
}
public static RelationshipType[] allRelationshipTypes(GraphDatabaseService db) {
return Iterables.asArray(RelationshipType.class, db.getAllRelationshipTypes());
}
public static RelationshipType[] typesAndDirectionsToTypesArray(String typesAndDirections) {
List relationshipTypes = new ArrayList<>();
for (Pair pair : RelationshipTypeAndDirections.parse(typesAndDirections)) {
if (null != pair.first()) {
relationshipTypes.add(pair.first());
}
}
return relationshipTypes.toArray(new RelationshipType[relationshipTypes.size()]);
}
public static Future inTxFuture(ExecutorService pool, GraphDatabaseAPI db, Callable callable) {
try {
return pool.submit(() -> {
try (Transaction tx = db.beginTx()) {
T result = callable.call();
tx.success();
return result;
}
});
} catch (Exception e) {
throw new RuntimeException("Error executing in separate transaction", e);
}
}
public static T inTx(GraphDatabaseAPI db, Callable callable) {
try {
return inTxFuture(Pools.DEFAULT, db, callable).get();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException("Error executing in separate transaction: "+e.getMessage(), e);
}
}
public static T inThread(Callable callable) {
try {
return inFuture(callable).get();
} catch (Exception e) {
throw new RuntimeException("Error executing in separate thread: "+e.getMessage(), e);
}
}
public static Future inFuture(Callable callable) {
return Pools.DEFAULT.submit(callable);
}
public static Double toDouble(Object value) {
if (value == null) return null;
if (value instanceof Number) return ((Number) value).doubleValue();
return Double.parseDouble(value.toString());
}
public static Map subMap(Map params, String prefix) {
Map config = new HashMap<>(10);
int len = prefix.length() + (prefix.isEmpty() || prefix.endsWith(".") ? 0 : 1);
for (Map.Entry entry : params.entrySet()) {
String key = entry.getKey();
if (key.startsWith(prefix)) {
config.put(key.substring(len), entry.getValue());
}
}
return config;
}
public static long toLong(Object value) {
if (value instanceof Number) return ((Number)value).longValue();
return Long.parseLong(value.toString());
}
public static URLConnection openUrlConnection(String url, Map headers) throws IOException {
URL src = new URL(url);
URLConnection con = src.openConnection();
con.setRequestProperty("User-Agent", "APOC Procedures for Neo4j");
if (headers != null) {
Object method = headers.get("method");
if (method != null && con instanceof HttpURLConnection) {
HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod(method.toString());
http.setChunkedStreamingMode(1024*1024);
http.setInstanceFollowRedirects(true);
}
headers.forEach((k,v) -> con.setRequestProperty(k, v == null ? "" : v.toString()));
}
con.setDoInput(true);
con.setConnectTimeout((int)toLong(ApocConfiguration.get("http.timeout.connect",10_000)));
con.setReadTimeout((int)toLong(ApocConfiguration.get("http.timeout.read",60_000)));
return con;
}
public static InputStream openInputStream(String url, Map headers, String payload) throws IOException {
URLConnection con = openUrlConnection(url, headers);
if (payload != null) {
con.setDoOutput(true);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(con.getOutputStream(),"UTF-8"));
writer.write(payload);
writer.close();
}
InputStream stream = con.getInputStream();
String encoding = con.getContentEncoding();
if ("gzip".equals(encoding) || url.endsWith(".gz")) {
stream = new GZIPInputStream(stream);
}
if ("deflate".equals(encoding)) {
stream = new DeflaterInputStream(stream);
}
return stream;
}
public static boolean toBoolean(Object value) {
if ((value == null || value instanceof Number && (((Number) value).longValue()) == 0L || value instanceof String && (value.equals("") || ((String) value).equalsIgnoreCase("false") || ((String) value).equalsIgnoreCase("no")|| ((String) value).equalsIgnoreCase("0"))|| value instanceof Boolean && value.equals(false))) {
return false;
}
return true;
}
public static String encodeUrlComponent(String value) {
try {
return URLEncoder.encode(value,"UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unsupported character set utf-8");
}
}
public static String toJson(Object value) {
try {
return JsonUtil.OBJECT_MAPPER.writeValueAsString(value);
} catch (IOException e) {
throw new RuntimeException("Can't convert "+value+" to JSON");
}
}
public static T fromJson(String value, Class type) {
try {
return JsonUtil.OBJECT_MAPPER.readValue(value,type);
} catch (IOException e) {
throw new RuntimeException("Can't convert "+value+" from JSON");
}
}
public static Stream> partitionSubList(List data, int partitions) {
return partitionSubList(data,partitions,null);
}
public static Stream> partitionSubList(List data, int partitions, List tombstone) {
if (partitions==0) partitions=1;
List list = new ArrayList<>(data);
int total = list.size();
int batchSize = Math.max((int)Math.ceil((double)total / partitions),1);
Stream> stream = IntStream.range(0, partitions).parallel()
.mapToObj((part) -> list.subList(Math.min(part * batchSize, total), Math.min((part + 1) * batchSize, total)))
.filter(partition -> !partition.isEmpty());
return tombstone == null ? stream : Stream.concat(stream,Stream.of(tombstone));
}
public static Long runNumericQuery(GraphDatabaseService db, String query, Map params) {
if (params == null) params = Collections.emptyMap();
try (ResourceIterator it = db.execute(query,params).columnAs("result")) {
return it.next();
}
}
public static long nodeCount(GraphDatabaseService db) {
return runNumericQuery(db,NODE_COUNT,null);
}
public static long relCount(GraphDatabaseService db) {
return runNumericQuery(db,REL_COUNT,null);
}
public static LongStream toLongStream(PrimitiveLongIterator it) {
PrimitiveIterator.OfLong iterator = new PrimitiveIterator.OfLong() {
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public long nextLong() {
return it.next();
}
};
return StreamSupport.longStream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
}
public static String readResourceFile(String name) {
InputStream is = Util.class.getClassLoader().getResourceAsStream(name);
return new Scanner(is).useDelimiter("\\Z").next();
}
@SuppressWarnings("unchecked")
public static Map readMap(String value) {
try {
return JsonUtil.OBJECT_MAPPER.readValue(value, Map.class);
} catch (IOException e) {
throw new RuntimeException("Couldn't read as JSON "+value);
}
}
public static List take(Iterator iterator, int batchsize) {
ArrayList result = new ArrayList<>(batchsize);
while (iterator.hasNext() && batchsize-- > 0) {
result.add(iterator.next());
}
return result;
}
public static Map merge(Map first, Map second) {
if (second == null || second.isEmpty()) return first;
if (first == null || first.isEmpty()) return second;
Map combined = new HashMap<>(first);
combined.putAll(second);
return combined;
}
public static Map map(Object ... values) {
Map map = new LinkedHashMap<>();
for (int i = 0; i < values.length; i+=2) {
if (values[i] == null) continue;
map.put(values[i].toString(),values[i+1]);
}
return map;
}
public static Map map(List pairs) {
Map res = new LinkedHashMap<>(pairs.size() / 2);
Iterator it = pairs.iterator();
while (it.hasNext()) {
Object key = it.next();
Object value = it.next();
if (key != null) res.put(key.toString(), value);
}
return res;
}
public static Map mapFromLists(List keys, List values) {
if (keys == null || values == null || keys.size() != values.size())
throw new RuntimeException("keys and values lists have to be not null and of same size");
if (keys.isEmpty()) return Collections.emptyMap();
if (keys.size()==1) return Collections.singletonMap(keys.get(0),values.get(0));
ListIterator it = values.listIterator();
Map res = new LinkedHashMap<>(keys.size());
for (String key : keys) {
res.put(key,it.next());
}
return res;
}
public static Map mapFromPairs(List> pairs) {
if (pairs.isEmpty()) return Collections.emptyMap();
Map map = new LinkedHashMap<>(pairs.size());
for (List pair : pairs) {
if (pair.isEmpty()) continue;
Object key = pair.get(0);
if (key==null) continue;
Object value = pair.size() >= 2 ? pair.get(1) : null;
map.put(key.toString(),value);
}
return map;
}
public static String cleanUrl(String url) {
try {
URL source = new URL(url);
String file = source.getFile();
if (source.getRef() != null) file += "#"+source.getRef();
return new URL(source.getProtocol(),source.getHost(),source.getPort(),file).toString();
} catch (MalformedURLException mfu) {
return "invalid URL";
}
}
public static T getFuture(Future f, Map errorMessages, AtomicInteger errors, T errorValue) {
try {
return f.get();
} catch (InterruptedException | ExecutionException e) {
errors.incrementAndGet();
errorMessages.compute(e.getMessage(),(s, i) -> i == null ? 1 : i + 1);
return errorValue;
}
}
public static void logErrors(String message, Map errors, Log log) {
if (!errors.isEmpty()) {
log.bulk(l -> {
l.warn(message);
errors.forEach((k, v) -> l.warn("%d times: %s",v,k));
});
}
}
public static void checkAdmin(KernelTransaction tx, String procedureName) {
if (!tx.securityContext().isAdmin()) throw new RuntimeException("This procedure "+ procedureName +" is only available to admin users");
}
}