org.entcore.common.neo4j.Neo4jUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.entcore.common.neo4j.Neo4jUtils.java

Source

/* Copyright  "Open Digital Education", 2014
 *
 * This program is published by "Open Digital Education".
 * You must indicate the name of the software and the company in any production /contribution
 * using the software and indicate on the home page of the software industry in question,
 * "powered by Open Digital Education" with a reference to the website: https://opendigitaleducation.com/.
 *
 * This program is free software, licensed under the terms of the GNU Affero General Public License
 * as published by the Free Software Foundation, version 3 of the License.
 *
 * You can redistribute this application and/or modify it since you respect the terms of the GNU Affero General Public License.
 * If you modify the source code and then use this modified source code in your creation, you must make available the source code of your modifications.
 *
 * You should have received a copy of the GNU Affero General Public License along with the software.
 * If not, please see : <http://www.gnu.org/licenses/>. Full compliance requires reading the terms of this license and following its directives.
    
 *
 */

package org.entcore.common.neo4j;

import io.vertx.core.AsyncResult;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.eventbus.Message;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;

import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class Neo4jUtils {

    private static final Logger log = LoggerFactory.getLogger(Neo4jUtils.class);
    private static final String UPDATE_SCRIPTS = "MERGE (n:System {name : {appName}}) SET n.scripts = coalesce(n.scripts, []) + {newFiles} ";

    public static String nodeSetPropertiesFromJson(String nodeAlias, JsonObject json, String... ignore) {
        StringBuilder sb = new StringBuilder();
        List<String> i;
        if (ignore != null) {
            i = Arrays.asList(ignore);
        } else {
            i = Collections.emptyList();
        }
        for (String a : json.fieldNames()) {
            String attr = a.replaceAll("\\W+", "");
            if (i.contains(attr))
                continue;
            sb.append(", ").append(nodeAlias).append(".").append(attr).append(" = {").append(attr).append("}");
        }
        if (sb.length() > 2) {
            return sb.append(" ").substring(2);
        }
        return " ";
    }

    public static void loadScripts(final String appName, final Vertx vertx, final String path) {
        String query = "MATCH (n:System) WHERE n.name = {appName} RETURN n.scripts as scripts";
        Neo4j.getInstance().execute(query, new JsonObject().put("appName", appName),
                new Handler<Message<JsonObject>>() {
                    @Override
                    public void handle(Message<JsonObject> event) {
                        JsonArray res = event.body().getJsonArray("result");
                        JsonArray scripts;
                        if ("ok".equals(event.body().getString("status")) && res != null && res.size() > 0) {
                            scripts = res.getJsonObject(0).getJsonArray("scripts",
                                    new fr.wseduc.webutils.collections.JsonArray());
                        } else {
                            scripts = new fr.wseduc.webutils.collections.JsonArray();
                        }
                        loadAndExecute(appName, vertx, path, true, scripts);
                        loadAndExecute(appName, vertx, path, false, scripts);
                    }
                });
    }

    private static void loadAndExecute(final String schema, final Vertx vertx, final String path,
            final boolean index, final JsonArray excludeFileNames) {
        final String pattern = index ? ".*?-index\\.cypher$" : "^(?!.*-index).*?\\.cypher$";
        vertx.fileSystem().readDir(path, pattern, new Handler<AsyncResult<List<String>>>() {
            @Override
            public void handle(AsyncResult<List<String>> asyncResult) {
                if (asyncResult.succeeded()) {
                    final List<String> files = asyncResult.result();
                    Collections.sort(files);
                    final StatementsBuilder s = new StatementsBuilder();
                    final JsonArray newFiles = new fr.wseduc.webutils.collections.JsonArray();
                    final AtomicInteger count = new AtomicInteger(files.size());
                    for (final String f : files) {
                        final String filename = f.substring(f.lastIndexOf(File.separatorChar) + 1);
                        if (!excludeFileNames.contains(filename)) {
                            vertx.fileSystem().readFile(f, new Handler<AsyncResult<Buffer>>() {
                                @Override
                                public void handle(AsyncResult<Buffer> bufferAsyncResult) {
                                    if (bufferAsyncResult.succeeded()) {
                                        String script = bufferAsyncResult.result().toString();
                                        for (String q : script.replaceAll("(\r|\n)", " ").split(";")) {
                                            s.add(q);
                                        }
                                        newFiles.add(filename);
                                    } else {
                                        log.error("Error reading file : " + f, bufferAsyncResult.cause());
                                    }
                                    if (count.decrementAndGet() == 0) {
                                        commit(schema, s, newFiles, index);
                                    }
                                }
                            });
                        } else if (count.decrementAndGet() == 0 && newFiles.size() > 0) {
                            commit(schema, s, newFiles, index);
                        }
                    }
                } else if (log.isDebugEnabled()) {
                    log.debug("Error reading neo4j directory : " + path, asyncResult.cause());
                }
            }

            private void commit(final String schema, StatementsBuilder s, final JsonArray newFiles,
                    final boolean index) {
                final JsonObject params = new JsonObject().put("appName", schema).put("newFiles", newFiles);
                if (!index) {
                    s.add(UPDATE_SCRIPTS, params);
                }
                Neo4j.getInstance().executeTransaction(s.build(), null, true, new Handler<Message<JsonObject>>() {
                    @Override
                    public void handle(Message<JsonObject> message) {
                        if ("ok".equals(message.body().getString("status"))) {
                            if (index) {
                                Neo4j.getInstance().execute(UPDATE_SCRIPTS, params,
                                        new Handler<Message<JsonObject>>() {
                                            @Override
                                            public void handle(Message<JsonObject> event) {
                                                if (!"ok".equals(event.body().getString("status"))) {
                                                    log.error("Error update scripts : "
                                                            + event.body().getString("message"));
                                                }
                                            }
                                        });
                            }
                            log.info("Scripts added : " + newFiles.encode());
                        } else {
                            log.error("Error when commit transaction : " + message.body().getString("message"));
                        }
                    }
                });
            }
        });
    }

}