Example usage for io.vertx.core.json JsonObject getJsonArray

List of usage examples for io.vertx.core.json JsonObject getJsonArray

Introduction

In this page you can find the example usage for io.vertx.core.json JsonObject getJsonArray.

Prototype

public JsonArray getJsonArray(String key) 

Source Link

Document

Get the JsonArray value with the specified key

Usage

From source file:org.entcore.feeder.csv.CsvValidator.java

License:Open Source License

private void validateFile(final String path, final String profile, final List<String> columns,
        final JsonArray existExternalId, final String charset, final Handler<JsonObject> handler) {
    addProfile(profile);//from w ww  .  j  a va 2 s.  c o  m
    final Validator validator = profiles.get(profile);
    getStructure(path.substring(0, path.lastIndexOf(File.separator)), new Handler<Structure>() {
        @Override
        public void handle(final Structure structure) {
            if (structure == null) {
                addError(profile, "invalid.structure");
                handler.handle(result);
                return;
            }
            final JsonObject checkChildExists = new JsonObject();
            try {
                CSVReader csvParser = getCsvReader(path, charset, 1);
                final int nbColumns = columns.size();
                String[] strings;
                int i = 1;
                csvParserWhile: while ((strings = csvParser.readNext()) != null) {
                    if (emptyLine(strings)) {
                        i++;
                        continue;
                    }
                    if (strings.length > nbColumns) {
                        strings = Arrays.asList(strings).subList(0, nbColumns).toArray(new String[nbColumns]);
                    }
                    //                  if (strings.length != nbColumns) {
                    //                     addErrorByFile(profile, "bad.columns.number", "" + ++i);
                    //                     continue;
                    //                  }
                    final JsonArray classesNames = new fr.wseduc.webutils.collections.JsonArray();
                    JsonObject user = new JsonObject();
                    user.put("structures",
                            new fr.wseduc.webutils.collections.JsonArray().add(structure.getExternalId()));
                    user.put("profiles", new fr.wseduc.webutils.collections.JsonArray().add(profile));
                    List<String[]> classes = new ArrayList<>();
                    for (int j = 0; j < strings.length; j++) {
                        if (j >= columns.size()) {
                            addErrorByFile(profile, "out.columns", "" + i);
                            return;
                        }
                        final String c = columns.get(j);
                        final String v = strings[j].trim();
                        if (v.isEmpty() && !c.startsWith("child"))
                            continue;
                        switch (validator.getType(c)) {
                        case "string":
                            if ("birthDate".equals(c)) {
                                Matcher m = frenchDatePatter.matcher(v);
                                if (m.find()) {
                                    user.put(c, m.group(3) + "-" + m.group(2) + "-" + m.group(1));
                                } else {
                                    user.put(c, v);
                                }
                            } else {
                                user.put(c, v);
                            }
                            break;
                        case "array-string":
                            JsonArray a = user.getJsonArray(c);
                            if (a == null) {
                                a = new fr.wseduc.webutils.collections.JsonArray();
                                user.put(c, a);
                            }
                            if (("classes".equals(c) || "subjectTaught".equals(c) || "functions".equals(c))
                                    && !v.startsWith(structure.getExternalId() + "$")) {
                                a.add(structure.getExternalId() + "$" + v);
                            } else {
                                a.add(v);
                            }
                            break;
                        case "boolean":
                            user.put(c, "true".equals(v.toLowerCase()));
                            break;
                        default:
                            Object o = user.getValue(c);
                            final String v2;
                            if ("childClasses".equals(c) && !v.startsWith(structure.getExternalId() + "$")) {
                                v2 = structure.getExternalId() + "$" + v;
                            } else {
                                v2 = v;
                            }
                            if (o != null) {
                                if (o instanceof JsonArray) {
                                    ((JsonArray) o).add(v2);
                                } else {
                                    JsonArray array = new fr.wseduc.webutils.collections.JsonArray();
                                    array.add(o).add(v2);
                                    user.put(c, array);
                                }
                            } else {
                                user.put(c, v2);
                            }
                        }
                        if ("classes".equals(c)) {
                            String eId = structure.getExternalId() + '$' + v;
                            String[] classId = new String[2];
                            classId[0] = structure.getExternalId();
                            classId[1] = eId;
                            classes.add(classId);
                            classesNames.add(v);
                        }
                    }
                    String ca;
                    long seed;
                    JsonArray classesA;
                    Object co = user.getValue("classes");
                    if (co != null && co instanceof JsonArray) {
                        classesA = (JsonArray) co;
                    } else if (co instanceof String) {
                        classesA = new fr.wseduc.webutils.collections.JsonArray().add(co);
                    } else {
                        classesA = null;
                    }
                    if ("Student".equals(profile) && classesA != null && classesA.size() == 1) {
                        seed = defaultStudentSeed;
                        ca = classesA.getString(0);
                    } else {
                        ca = String.valueOf(i);
                        seed = System.currentTimeMillis();
                    }
                    final State state;
                    final String externalId = user.getString("externalId");
                    if (externalId == null || externalId.trim().isEmpty()) {
                        generateUserExternalId(user, ca, structure, seed);
                        state = State.NEW;
                    } else {
                        if (existExternalId.contains(externalId)) {
                            state = State.UPDATED;
                            studentExternalIdMapping.put(getHashMapping(user, ca, structure, seed), externalId);
                        } else {
                            state = State.NEW;
                        }
                    }
                    switch (profile) {
                    case "Relative":
                        boolean checkChildMapping = true;
                        JsonArray linkStudents = new fr.wseduc.webutils.collections.JsonArray();
                        if ("Intitul".equals(strings[0]) && "Adresse Organisme".equals(strings[1])) {
                            break csvParserWhile;
                        }
                        user.put("linkStudents", linkStudents);
                        for (String attr : user.fieldNames()) {
                            if ("childExternalId".equals(attr)) {
                                if (checkChildMapping) {
                                    checkChildMapping = false;
                                }
                                Object o = user.getValue(attr);
                                if (o instanceof JsonArray) {
                                    for (Object c : (JsonArray) o) {
                                        linkStudents.add(c);
                                    }
                                } else {
                                    linkStudents.add(o);
                                }
                            } else if ("childUsername".equals(attr)) {
                                Object childUsername = user.getValue(attr);
                                Object childLastName = user.getValue("childLastName");
                                Object childFirstName = user.getValue("childFirstName");
                                Object childClasses;
                                if (isNotEmpty(structure.getOverrideClass())) {
                                    childClasses = structure.getOverrideClass();
                                } else {
                                    childClasses = user.getValue("childClasses");
                                }
                                if (childUsername instanceof JsonArray && childLastName instanceof JsonArray
                                        && childFirstName instanceof JsonArray
                                        && childClasses instanceof JsonArray
                                        && ((JsonArray) childClasses).size() == ((JsonArray) childLastName)
                                                .size()
                                        && ((JsonArray) childFirstName).size() == ((JsonArray) childLastName)
                                                .size()) {
                                    for (int j = 0; j < ((JsonArray) childUsername).size(); j++) {
                                        String mapping = structure.getExternalId()
                                                + ((JsonArray) childUsername).getString(j).trim()
                                                + ((JsonArray) childLastName).getString(j).trim()
                                                + ((JsonArray) childFirstName).getString(j).trim()
                                                + ((JsonArray) childClasses).getString(j).trim()
                                                + defaultStudentSeed;
                                        relativeStudentMapping(linkStudents, mapping);
                                    }
                                } else if (childUsername instanceof String && childLastName instanceof String
                                        && childFirstName instanceof String && childClasses instanceof String) {
                                    String mapping = structure.getExternalId() + childLastName.toString().trim()
                                            + childFirstName.toString().trim() + childClasses.toString().trim()
                                            + defaultStudentSeed;
                                    relativeStudentMapping(linkStudents, mapping);
                                } else {
                                    addErrorByFile(profile, "invalid.child.mapping", "" + (i + 1),
                                            "childLUsername");
                                    handler.handle(result);
                                    return;
                                }
                            } else if ("childLastName".equals(attr)
                                    && !user.fieldNames().contains("childUsername")) {
                                Object childLastName = user.getValue(attr);
                                Object childFirstName = user.getValue("childFirstName");
                                Object childClasses;
                                if (isNotEmpty(structure.getOverrideClass())) {
                                    childClasses = structure.getOverrideClass();
                                } else {
                                    childClasses = user.getValue("childClasses");
                                }
                                if (childLastName instanceof JsonArray && childFirstName instanceof JsonArray
                                        && childClasses instanceof JsonArray
                                        && ((JsonArray) childClasses).size() == ((JsonArray) childLastName)
                                                .size()
                                        && ((JsonArray) childFirstName).size() == ((JsonArray) childLastName)
                                                .size()) {
                                    for (int j = 0; j < ((JsonArray) childLastName).size(); j++) {
                                        String mapping = structure.getExternalId()
                                                + ((JsonArray) childLastName).getString(j)
                                                + ((JsonArray) childFirstName).getString(j)
                                                + ((JsonArray) childClasses).getString(j) + defaultStudentSeed;
                                        relativeStudentMapping(linkStudents, mapping);
                                    }
                                } else if (childLastName instanceof String && childFirstName instanceof String
                                        && childClasses instanceof String) {
                                    String mapping = structure.getExternalId() + childLastName.toString().trim()
                                            + childFirstName.toString().trim() + childClasses.toString().trim()
                                            + defaultStudentSeed;
                                    relativeStudentMapping(linkStudents, mapping);
                                } else {
                                    addErrorByFile(profile, "invalid.child.mapping", "" + (i + 1),
                                            "childLastName & childFirstName");
                                    handler.handle(result);
                                    return;
                                }
                            }
                        }
                        if (checkChildMapping || classesNamesMapping.size() > 0) {
                            for (Object o : linkStudents) {
                                if (!(o instanceof String))
                                    continue;
                                if (classesNamesMapping.get(o) != null) {
                                    classesNames.add(classesNamesMapping.get(o));
                                }
                            }
                            if (classesNames.size() == 0) {
                                addSoftErrorByFile(profile, "missing.student.soft", "" + (i + 1),
                                        user.getString("firstName"), user.getString("lastName"));
                            }
                        } else {
                            Object c = user.getValue("childExternalId");
                            JsonObject u = new JsonObject().put("lastName", user.getString("lastName"))
                                    .put("firstName", user.getString("firstName")).put("line", i);
                            if (c instanceof String) {
                                c = new JsonArray().add(c);
                            }
                            if (c instanceof JsonArray) {
                                for (Object ceId : ((JsonArray) c)) {
                                    if (isEmpty((String) ceId))
                                        continue;
                                    JsonArray jr = checkChildExists.getJsonArray((String) ceId);
                                    if (jr == null) {
                                        jr = new JsonArray();
                                        checkChildExists.put((String) ceId, jr);
                                    }
                                    jr.add(u);
                                }
                            }
                        }
                        break;
                    }
                    String error = validator.validate(user, acceptLanguage);
                    if (error != null) {
                        log.warn(error);
                        addErrorByFile(profile, "validator.errorWithLine", "" + (i + 1), error); // Note that 'error' is already translated
                    } else {
                        final String classesStr = Joiner.on(", ").join(classesNames);
                        if (!"Relative".equals(profile)) {
                            classesNamesMapping.put(user.getString("externalId"), classesStr);
                        }
                        addUser(profile, user.put("state", translate(state.name()))
                                .put("translatedProfile", translate(profile)).put("classesStr", classesStr));
                    }
                    i++;
                }
            } catch (Exception e) {
                addError(profile, "csv.exception");
                log.error("csv.exception", e);
            }
            if (!checkChildExists.isEmpty()) {
                final String query = "MATCH (u:User) " + "WHERE u.externalId IN {childExternalIds} "
                        + "RETURN COLLECT(u.externalId) as childExternalIds ";
                final JsonObject params = new JsonObject().put("childExternalIds",
                        new JsonArray(new ArrayList<>(checkChildExists.fieldNames())));
                Neo4j.getInstance().execute(query, params, new Handler<Message<JsonObject>>() {
                    @Override
                    public void handle(Message<JsonObject> event) {
                        if ("ok".equals(event.body().getString("status"))) {
                            JsonArray existsChilds = getOrElse(
                                    getOrElse(getOrElse(event.body().getJsonArray("result"), new JsonArray())
                                            .getJsonObject(0), new JsonObject())
                                                    .getJsonArray("childExternalIds"),
                                    new JsonArray());
                            for (String cexternalId : checkChildExists.fieldNames()) {
                                if (!existsChilds.contains(cexternalId)) {
                                    for (Object o : checkChildExists.getJsonArray(cexternalId)) {
                                        if (!(o instanceof JsonObject))
                                            continue;
                                        JsonObject user = (JsonObject) o;
                                        addSoftErrorByFile(profile, "missing.student.soft",
                                                "" + (user.getInteger("line") + 1), user.getString("firstName"),
                                                user.getString("lastName"));
                                    }
                                }
                            }
                        }
                        handler.handle(result);
                    }
                });
            } else {
                handler.handle(result);
            }
        }
    });

}

From source file:org.entcore.feeder.dictionary.structures.DuplicateUsers.java

License:Open Source License

public void autoMergeDuplicatesInStructure(final Handler<AsyncResult<JsonArray>> handler) {
    final Handler<JsonObject> duplicatesHandler = new Handler<JsonObject>() {
        @Override//from www  .  jav  a  2 s.  com
        public void handle(JsonObject duplicatesRes) {
            JsonArray res = duplicatesRes.getJsonArray("result");
            if ("ok".equals(duplicatesRes.getString("status")) && res != null && res.size() > 0) {
                try {
                    final TransactionHelper tx = TransactionManager.getTransaction();
                    final AtomicInteger count = new AtomicInteger(res.size());
                    final Handler<JsonObject> mergeHandler = new Handler<JsonObject>() {
                        @Override
                        public void handle(JsonObject event) {
                            decrementCount(count, tx);
                        }
                    };
                    for (Object o : res) {
                        if (!(o instanceof JsonObject)) {
                            decrementCount(count, tx);
                            continue;
                        }
                        JsonObject j = (JsonObject) o;
                        JsonObject u1 = j.getJsonObject("user1");
                        JsonObject u2 = j.getJsonObject("user2");
                        if (u1 != null && u2 != null) {
                            mergeDuplicate(new ResultMessage(mergeHandler).put("userId1", u1.getString("id"))
                                    .put("userId2", u2.getString("id")), tx);
                            log.info("AutoMerge duplicates - u1 : " + u1.encode() + ", u2 : " + u2.encode());
                        } else {
                            decrementCount(count, tx);
                        }
                    }
                } catch (TransactionException e) {
                    log.error("Error in automerge transaction", e);
                    handler.handle(new DefaultAsyncResult<JsonArray>(e));
                }
            } else {
                log.info("No duplicates automatically mergeable.");
                handler.handle(new DefaultAsyncResult<>(new fr.wseduc.webutils.collections.JsonArray()));
            }
        }

        private void decrementCount(AtomicInteger count, TransactionHelper tx) {
            if (count.decrementAndGet() == 0) {
                tx.commit(new Handler<Message<JsonObject>>() {
                    @Override
                    public void handle(Message<JsonObject> event) {
                        if ("ok".equals(event.body().getString("status"))) {
                            if (updateCourses) {
                                AbstractTimetableImporter
                                        .updateMergedUsers(event.body().getJsonArray("results"));
                            }
                            handler.handle(new DefaultAsyncResult<>(event.body().getJsonArray("results")));
                        } else {
                            log.error("Error in automerge duplicates transaction : "
                                    + event.body().getString("message"));
                            handler.handle(new DefaultAsyncResult<JsonArray>(
                                    new TransactionException(event.body().getString("message"))));
                        }
                    }
                });
            }
        }
    };
    listDuplicates(new ResultMessage(duplicatesHandler).put("minScore", 5)
            .put("inSameStructure", autoMergeOnlyInSameStructure).put("inherit", false));
}

From source file:org.entcore.feeder.dictionary.structures.GraphData.java

License:Open Source License

static void loadData(final Neo4j neo4j, final Handler<Message<JsonObject>> handler) {
    String query = "MATCH (s:Structure) " + "OPTIONAL MATCH s<-[:DEPENDS]-(g:Group) "
            + "OPTIONAL MATCH s<-[:BELONGS]-(c:Class) "
            + "return s, collect(distinct g.externalId) as groups, collect(distinct c.externalId) as classes ";
    neo4j.execute(query, new JsonObject(), new Handler<Message<JsonObject>>() {
        @Override/*from   ww w . j a v  a 2 s .  co m*/
        public void handle(Message<JsonObject> message) {
            String query = "MATCH (p:Profile) " + "OPTIONAL MATCH p<-[:COMPOSE]-(f:Function) "
                    + "return p, collect(distinct f.externalId) as functions ";
            final AtomicInteger count = new AtomicInteger(2);
            neo4j.execute(query, new JsonObject(), new Handler<Message<JsonObject>>() {
                @Override
                public void handle(Message<JsonObject> message) {
                    JsonArray res = message.body().getJsonArray("result");
                    if ("ok".equals(message.body().getString("status")) && res != null) {
                        for (Object o : res) {
                            if (!(o instanceof JsonObject))
                                continue;
                            JsonObject r = (JsonObject) o;
                            JsonObject p = r.getJsonObject("p", new JsonObject()).getJsonObject("data");
                            profiles.putIfAbsent(p.getString("externalId"),
                                    new Profile(p, r.getJsonArray("functions")));
                        }
                    }
                    if (handler != null && count.decrementAndGet() == 0) {
                        handler.handle(message);
                    }
                }
            });
            JsonArray res = message.body().getJsonArray("result");
            if ("ok".equals(message.body().getString("status")) && res != null) {
                for (Object o : res) {
                    if (!(o instanceof JsonObject))
                        continue;
                    JsonObject r = (JsonObject) o;
                    JsonObject s = r.getJsonObject("s", new JsonObject()).getJsonObject("data");
                    Structure structure = new Structure(s, r.getJsonArray("groups"), r.getJsonArray("classes"));
                    String externalId = s.getString("externalId");
                    structures.putIfAbsent(externalId, structure);
                    String UAI = s.getString("UAI");
                    if (UAI != null && !UAI.trim().isEmpty()) {
                        structuresByUAI.putIfAbsent(UAI, structure);
                    }
                    JsonArray joinKeys = s.getJsonArray("joinKey");
                    if (joinKeys != null && joinKeys.size() > 0) {
                        for (Object key : joinKeys) {
                            externalIdMapping.putIfAbsent(key.toString(), externalId);
                        }
                    }
                }
            }
            if (handler != null && count.decrementAndGet() == 0) {
                handler.handle(message);
            }
        }
    });
}

From source file:org.entcore.feeder.dictionary.structures.Importer.java

License:Open Source License

public Structure createOrUpdateStructure(JsonObject struct) {
    JsonArray groups = null;//from ww  w .  ja v a2s  .  co m
    if (struct != null) {
        groups = struct.getJsonArray("groups");
    }
    final String error = structureValidator.validate(struct);
    Structure s = null;
    if (error != null) {
        report.addIgnored("Structure", error, struct);
        log.warn(error);
    } else {
        struct.put("source", currentSource);
        final String externalId = struct.getString("externalId");
        if (groups != null) {
            for (Object gcMapping : groups) {
                if (!(gcMapping instanceof String))
                    continue;
                final String[] m = ((String) gcMapping).split("\\$");
                final String groupCode = m[0];
                if (groupCode == null || groupCode.isEmpty() || m.length < 3)
                    continue;
                final List<String> classes = new LinkedList<>();
                for (int i = 2; i < m.length; i++) {
                    classes.add(externalId + "$" + m[i]);
                }
                if (!classes.isEmpty()) {
                    groupClasses.put(externalId + "$" + groupCode, classes);
                }
            }
        }
        s = structures.get(externalId);
        if (s != null) {
            s.update(struct);
        } else {
            String UAI = struct.getString("UAI");
            if (UAI != null) {
                s = structuresByUAI.get(UAI);
            }
            if (s != null) {
                structures.putIfAbsent(externalId, s);
                Object[] joinKeys = s.addJointure(externalId);
                if (joinKeys != null) {
                    String origExternalId = s.getExternalId();
                    for (Object key : joinKeys) {
                        externalIdMapping.putIfAbsent(key.toString(), origExternalId);
                    }
                }
            } else {
                try {
                    s = new Structure(externalId, struct);
                    structures.putIfAbsent(externalId, s);
                    s.create();
                } catch (IllegalArgumentException e) {
                    log.error(e.getMessage());
                }
            }
        }
    }
    return s;
}

From source file:org.entcore.feeder.dictionary.structures.Importer.java

License:Open Source License

public void createOrUpdateUser(JsonObject object, JsonArray linkStudent, boolean linkRelativeWithoutChild) {
    final String error = userValidator.validate(object);
    if (error != null) {
        report.addIgnored("Relative", error, object);
        log.warn(error);/*from   w ww. j  av  a2  s  .c o  m*/
    } else {
        object.put("source", currentSource);
        userImportedExternalId.add(object.getString("externalId"));
        String query = "MERGE (u:User { externalId : {externalId}}) "
                + "ON CREATE SET u.id = {id}, u.login = {login}, u.activationCode = {activationCode}, "
                + "u.displayName = {displayName}, u.created = {created} " + "WITH u "
                + "WHERE u.checksum IS NULL OR u.checksum <> {checksum} " + "SET "
                + Neo4jUtils.nodeSetPropertiesFromJson("u", object, "id", "externalId", "login",
                        "activationCode", "displayName", "email", "created");
        transactionHelper.add(query, object);
        checkUpdateEmail(object);
        if (linkStudent != null && linkStudent.size() > 0) {
            String query2 = "START u0=node:node_auto_index(externalId={externalId}), "
                    + "s=node:node_auto_index({studentExternalIds}) " + "MATCH u0-[:MERGED*0..1]->u "
                    + "WHERE NOT(HAS(u.mergedWith)) " + "MERGE u<-[:RELATED]-s ";
            JsonObject p = new JsonObject().put("externalId", object.getString("externalId"))
                    .put("studentExternalIds", "externalId:" + Joiner.on(" OR externalId:").join(linkStudent));
            transactionHelper.add(query2, p);
        } else if (linkRelativeWithoutChild) {
            final String externalId = object.getString("externalId");
            JsonArray structures = getMappingStructures(object.getJsonArray("structures"));
            if (externalId != null && structures != null && structures.size() > 0) {
                JsonObject p = new JsonObject().put("userExternalId", externalId);
                String q1 = "MATCH (s:Structure)<-[:DEPENDS]-(g:ProfileGroup)-[:HAS_PROFILE]->(p:Profile), "
                        + "(:User { externalId : {userExternalId}})-[:MERGED*0..1]->(u:User) "
                        + "USING INDEX s:Structure(externalId) " + "USING INDEX p:Profile(externalId) "
                        + "WHERE s.externalId IN {structuresAdmin} "
                        + "AND p.externalId = {profileExternalId} AND NOT(HAS(u.mergedWith)) "
                        + "MERGE u-[:IN]->g";
                p.put("structuresAdmin", structures).put("profileExternalId",
                        DefaultProfiles.RELATIVE_PROFILE_EXTERNAL_ID);
                transactionHelper.add(q1, p);
            }
        }
    }
}

From source file:org.entcore.feeder.dictionary.structures.Importer.java

License:Open Source License

public void createOrUpdateGuest(JsonObject object, String[][] linkClasses) {
    final String error = userValidator.validate(object);
    if (error != null) {
        report.addIgnored("Guest", error, object);
        log.warn(error);/*from   ww  w  .j ava2  s .  c  om*/
    } else {
        object.put("source", currentSource);
        final String externalId = object.getString("externalId");
        userImportedExternalId.add(externalId);
        String query = "MERGE (u:User { externalId : {externalId}}) "
                + "ON CREATE SET u.id = {id}, u.login = {login}, u.activationCode = {activationCode}, "
                + "u.displayName = {displayName}, u.created = {created} " + "WITH u "
                + "WHERE u.checksum IS NULL OR u.checksum <> {checksum} " + "SET "
                + Neo4jUtils.nodeSetPropertiesFromJson("u", object, "id", "externalId", "login",
                        "activationCode", "displayName", "email", "created");
        transactionHelper.add(query, object);
        checkUpdateEmail(object);
        JsonArray structures = getMappingStructures(object.getJsonArray("structures"));
        if (externalId != null && structures != null && structures.size() > 0) {
            JsonObject p = new JsonObject().put("userExternalId", externalId);
            String q1 = "MATCH (s:Structure)<-[:DEPENDS]-(g:ProfileGroup)-[:HAS_PROFILE]->(p:Profile), "
                    + "(:User { externalId : {userExternalId}})-[:MERGED*0..1]->(u:User) "
                    + "USING INDEX s:Structure(externalId) " + "USING INDEX p:Profile(externalId) "
                    + "WHERE s.externalId IN {structuresAdmin} "
                    + "AND p.externalId = {profileExternalId} AND NOT(HAS(u.mergedWith)) " + "MERGE u-[:IN]->g";
            p.put("structuresAdmin", structures).put("profileExternalId",
                    DefaultProfiles.GUEST_PROFILE_EXTERNAL_ID);
            transactionHelper.add(q1, p);
            String qs = "MATCH (:User {externalId : {userExternalId}})-[r:IN|COMMUNIQUE]-(:Group)-[:DEPENDS]->(s:Structure) "
                    + "WHERE NOT(s.externalId IN {structures}) AND (NOT(HAS(r.source)) OR r.source = {source}) "
                    + "DELETE r";
            JsonObject ps = new JsonObject().put("userExternalId", externalId).put("source", currentSource)
                    .put("structures", structures);
            transactionHelper.add(qs, ps);
        }
        if (externalId != null && linkClasses != null) {
            JsonArray classes = new fr.wseduc.webutils.collections.JsonArray();
            for (String[] structClass : linkClasses) {
                if (structClass != null && structClass[0] != null && structClass[1] != null) {
                    String q = "MATCH (s:Structure)<-[:BELONGS]-(c:Class)<-[:DEPENDS]-(g:ProfileGroup)"
                            + "-[:DEPENDS]->(pg:ProfileGroup)-[:HAS_PROFILE]->(p:Profile), "
                            + "(:User { externalId : {userExternalId}})-[:MERGED*0..1]->(u:User) "
                            + "USING INDEX s:Structure(externalId) " + "USING INDEX p:Profile(externalId) "
                            + "WHERE s.externalId = {structure} AND c.externalId = {class} "
                            + "AND p.externalId = {profileExternalId} AND NOT(HAS(u.mergedWith)) "
                            + "MERGE u-[:IN]->g";
                    JsonObject p = new JsonObject().put("userExternalId", externalId)
                            .put("profileExternalId", DefaultProfiles.GUEST_PROFILE_EXTERNAL_ID)
                            .put("structure", structClass[0]).put("class", structClass[1]);
                    transactionHelper.add(q, p);
                    classes.add(structClass[1]);
                }
            }
            String q = "MATCH (:User {externalId : {userExternalId}})-[r:IN|COMMUNIQUE]-(:Group)-[:DEPENDS]->(c:Class) "
                    + "WHERE NOT(c.externalId IN {classes}) AND (NOT(HAS(r.source)) OR r.source = {source}) "
                    + "DELETE r";
            JsonObject p = new JsonObject().put("userExternalId", externalId).put("source", currentSource)
                    .put("classes", classes);
            transactionHelper.add(q, p);
        }
    }
}

From source file:org.entcore.feeder.dictionary.structures.Importer.java

License:Open Source License

public void createOrUpdateStudent(JsonObject object, String profileExternalId, String module,
        JsonArray fieldOfStudy, String[][] linkClasses, String[][] linkGroups, JsonArray relative,
        boolean nodeQueries, boolean relationshipQueries) {
    final String error = studentValidator.validate(object);
    if (error != null) {
        report.addIgnored("Student", error, object);
        log.warn(error);/*  w  w w .j ava 2 s .c om*/
    } else {
        if (nodeQueries) {
            object.put("source", currentSource);
            userImportedExternalId.add(object.getString("externalId"));
            String query = "MERGE (u:`User` { externalId : {externalId}}) "
                    + "ON CREATE SET u.id = {id}, u.login = {login}, u.activationCode = {activationCode}, "
                    + "u.displayName = {displayName}, u.created = {created} " + "WITH u "
                    + "WHERE u.checksum IS NULL OR u.checksum <> {checksum} " + "SET "
                    + Neo4jUtils.nodeSetPropertiesFromJson("u", object, "id", "externalId", "login",
                            "activationCode", "displayName", "email", "created");
            transactionHelper.add(query, object);
            checkUpdateEmail(object);
        }
        if (relationshipQueries) {
            final String externalId = object.getString("externalId");
            JsonArray structures = getMappingStructures(object.getJsonArray("structures"));
            if (externalId != null && structures != null && structures.size() > 0) {
                String query;
                JsonObject p = new JsonObject().put("userExternalId", externalId);
                if (structures.size() == 1) {
                    query = "MATCH (s:Structure {externalId : {structureAdmin}})<-[:DEPENDS]-(g:ProfileGroup)-[:HAS_PROFILE]->(p:Profile {externalId : {profileExternalId}}), "
                            + "(u:User { externalId : {userExternalId}}) " + "WHERE NOT(HAS(u.mergedWith)) "
                            + "MERGE u-[:ADMINISTRATIVE_ATTACHMENT]->s " + "WITH u, g " + "MERGE u-[:IN]->g";
                    p.put("structureAdmin", structures.getString(0)).put("profileExternalId",
                            profileExternalId);
                } else {
                    query = "MATCH (s:Structure)<-[:DEPENDS]-(g:ProfileGroup)-[:HAS_PROFILE]->(p:Profile), "
                            + "(u:User { externalId : {userExternalId}})) "
                            + "WHERE s.externalId IN {structuresAdmin} AND NOT(HAS(u.mergedWith)) "
                            + "AND p.externalId = {profileExternalId} "
                            + "MERGE u-[:ADMINISTRATIVE_ATTACHMENT]->s " + "WITH u, g " + "MERGE u-[:IN]->g";
                    p.put("structuresAdmin", structures).put("profileExternalId", profileExternalId);
                }
                transactionHelper.add(query, p);
                String qs = "MATCH (:User {externalId : {userExternalId}})-[r:IN|COMMUNIQUE]-(:Group)-[:DEPENDS]->(s:Structure) "
                        + "WHERE NOT(s.externalId IN {structures}) AND (NOT(HAS(r.source)) OR r.source = {source}) "
                        + "DELETE r";
                JsonObject ps = new JsonObject().put("userExternalId", externalId).put("source", currentSource)
                        .put("structures", structures);
                transactionHelper.add(qs, ps);
                final String daa = "MATCH (u:User {externalId : {userExternalId}})-[r:ADMINISTRATIVE_ATTACHMENT]->(s:Structure) "
                        + "WHERE NOT(s.externalId IN {structures}) AND (NOT(HAS(r.source)) OR r.source = {source}) "
                        + "DELETE r";
                transactionHelper.add(daa, ps);
            }
            JsonArray classes = new fr.wseduc.webutils.collections.JsonArray();
            if (externalId != null && linkClasses != null) {
                for (String[] structClass : linkClasses) {
                    if (structClass != null && structClass[0] != null && structClass[1] != null) {
                        classes.add(structClass[1]);
                    }
                }
                String query = "MATCH (c:Class)<-[:DEPENDS]-(g:ProfileGroup)"
                        + "-[:DEPENDS]->(:ProfileGroup)-[:HAS_PROFILE]->(:Profile {externalId : {profileExternalId}}), "
                        + "(u:User { externalId : {userExternalId}}) "
                        + "WHERE c.externalId IN {classes} AND NOT(HAS(u.mergedWith))  " + "MERGE u-[:IN]->g";
                JsonObject p0 = new JsonObject().put("userExternalId", externalId)
                        .put("profileExternalId", profileExternalId).put("classes", classes);
                transactionHelper.add(query, p0);
            }
            if (externalId != null) {
                String q = "MATCH (:User {externalId : {userExternalId}})-[r:IN|COMMUNIQUE]-(:Group)-[:DEPENDS]->(c:Class) "
                        + "WHERE NOT(c.externalId IN {classes}) AND (NOT(HAS(r.source)) OR r.source = {source}) "
                        + "DELETE r";
                JsonObject p = new JsonObject().put("userExternalId", externalId).put("source", currentSource)
                        .put("classes", classes);
                transactionHelper.add(q, p);
            }
            final JsonArray groups = new fr.wseduc.webutils.collections.JsonArray();
            if (externalId != null && linkGroups != null) {
                for (String[] structGroup : linkGroups) {
                    if (structGroup != null && structGroup[0] != null && structGroup[1] != null) {
                        groups.add(structGroup[1]);
                    }
                }
                String query = "MATCH (g:FunctionalGroup), (u:User { externalId : {userExternalId}}) "
                        + "WHERE g.externalId IN {groups} AND NOT(HAS(u.mergedWith)) " + "MERGE u-[:IN]->g";
                JsonObject p = new JsonObject().put("userExternalId", externalId).put("groups", groups);
                transactionHelper.add(query, p);
            }
            if (externalId != null) {
                final String qdfg = "MATCH (:User {externalId : {userExternalId}})-[r:IN|COMMUNIQUE]-(g:FunctionalGroup) "
                        + "WHERE NOT(g.externalId IN {groups}) AND (NOT(HAS(r.source)) OR r.source = {source}) "
                        + "DELETE r";
                final JsonObject pdfg = new JsonObject().put("userExternalId", externalId)
                        .put("source", currentSource).put("groups", groups);
                transactionHelper.add(qdfg, pdfg);
            }

            if (externalId != null && module != null) {
                String query = "MATCH (u:User {externalId:{userExternalId}}), "
                        + "(m:Module {externalId:{moduleStudent}}) " + "MERGE u-[:FOLLOW]->m";
                JsonObject p = new JsonObject().put("userExternalId", externalId).put("moduleStudent", module);
                transactionHelper.add(query, p);
            }
            if (externalId != null && fieldOfStudy != null && fieldOfStudy.size() > 0) {
                String query = "MATCH (u:User {externalId:{userExternalId}}), (f:FieldOfStudy) "
                        + "WHERE f.externalId IN {fieldOfStudyStudent} " + "MERGE u-[:COURSE]->f";
                JsonObject p = new JsonObject().put("userExternalId", externalId).put("fieldOfStudyStudent",
                        fieldOfStudy);
                transactionHelper.add(query, p);
            }
            if (externalId != null && relative != null && relative.size() > 0) {
                String query2 = "MATCH (:User {externalId:{userExternalId}})-[r:RELATED]->(p:User) "
                        + "WHERE NOT(p.externalId IN {relatives}) " + "DELETE r ";
                JsonObject p2 = new JsonObject().put("userExternalId", externalId).put("relatives", relative);
                transactionHelper.add(query2, p2);
                for (Object o : relative) {
                    if (!(o instanceof String))
                        continue;
                    String query = "MATCH (u:User {externalId:{userExternalId}}), "
                            + "(:User {externalId:{user}})-[:MERGED*0..1]->(r:User) "
                            + "WHERE NOT(HAS(r.mergedWith)) " + "MERGE u-[:RELATED]->r " + "WITH r, u "
                            + "WHERE {user} <> r.externalId AND LENGTH(FILTER(eId IN u.relative WHERE eId STARTS WITH r.externalId)) = 0 "
                            + "SET u.relative = coalesce(u.relative, []) + (r.externalId + '$10$1$1$0$0') ";
                    JsonObject p = new JsonObject().put("userExternalId", externalId).put("user", (String) o);
                    transactionHelper.add(query, p);
                }
            }
        }
    }
}

From source file:org.entcore.feeder.dictionary.structures.PostImport.java

License:Open Source License

private void wsCall(JsonObject object) {
    for (String url : object.fieldNames()) {
        final JsonArray endpoints = object.getJsonArray(url);
        if (endpoints == null || endpoints.size() < 1)
            continue;
        try {/*from w  w w .j  a v a2  s . c  o  m*/
            final URI uri = new URI(url);
            HttpClientOptions options = new HttpClientOptions().setDefaultHost(uri.getHost())
                    .setDefaultPort(uri.getPort()).setMaxPoolSize(16).setSsl("https".equals(uri.getScheme()))
                    .setConnectTimeout(10000).setKeepAlive(false);
            final HttpClient client = vertx.createHttpClient(options);

            final Handler[] handlers = new Handler[endpoints.size() + 1];
            handlers[handlers.length - 1] = new Handler<Void>() {
                @Override
                public void handle(Void v) {
                    client.close();
                }
            };
            for (int i = endpoints.size() - 1; i >= 0; i--) {
                final int ji = i;
                handlers[i] = new Handler<Void>() {
                    @Override
                    public void handle(Void v) {
                        final JsonObject j = endpoints.getJsonObject(ji);
                        logger.info("endpoint : " + j.encode());
                        final HttpClientRequest req = client.request(HttpMethod.valueOf(j.getString("method")),
                                j.getString("uri"), new Handler<HttpClientResponse>() {
                                    @Override
                                    public void handle(HttpClientResponse resp) {
                                        if (resp.statusCode() >= 300) {
                                            logger.warn("Endpoint " + j.encode() + " error : "
                                                    + resp.statusCode() + " " + resp.statusMessage());
                                        }
                                        handlers[ji + 1].handle(null);
                                    }
                                });
                        JsonObject headers = j.getJsonObject("headers");
                        if (headers != null && headers.size() > 0) {
                            for (String h : headers.fieldNames()) {
                                req.putHeader(h, headers.getString(h));
                            }
                        }
                        req.exceptionHandler(
                                e -> logger.error("Error in ws call post import : " + j.encode(), e));
                        if (j.getString("body") != null) {
                            req.end(j.getString("body"));
                        } else {
                            req.end();
                        }
                    }
                };
            }
            handlers[0].handle(null);
        } catch (URISyntaxException e) {
            logger.error("Invalid uri in ws call after import : " + url, e);
        }
    }
}

From source file:org.entcore.feeder.dictionary.structures.Structure.java

License:Open Source License

public void transition(final Handler<Message<JsonObject>> handler) {
    final TransactionHelper tx = TransactionManager.getInstance().getTransaction("GraphDataUpdate");
    String query = "MATCH (s:Structure {id : {id}})<-[:BELONGS]-(c:Class)"
            + "<-[:DEPENDS]-(cpg:Group)<-[:IN]-(u:User) " + "OPTIONAL MATCH s<-[:DEPENDS]-(fg:FunctionalGroup) "
            + "RETURN collect(distinct u.id) as users, collect(distinct cpg.id) as profileGroups, "
            + "collect(distinct fg.id) as functionalGroups";
    JsonObject params = new JsonObject().put("id", id);
    tx.getNeo4j().execute(query, params, new Handler<Message<JsonObject>>() {
        @Override/*from  w ww  .j a v  a2s. com*/
        public void handle(Message<JsonObject> event) {
            JsonArray r = event.body().getJsonArray("result");
            if ("ok".equals(event.body().getString("status")) && r != null && r.size() == 1) {
                final JsonObject res = r.getJsonObject(0);
                usersInGroups(new Handler<Message<JsonObject>>() {

                    @Override
                    public void handle(Message<JsonObject> event) {
                        if ("ok".equals(event.body().getString("status"))) {
                            for (Object u : res.getJsonArray("users")) {
                                User.backupRelationship(u.toString(), tx);
                                User.transition(u.toString(), tx);
                            }
                            transitionClassGroup();
                            handler.handle(event);
                        } else {
                            log.error("Structure " + id + " transition error - useringroups.");
                            log.error(event.body().encode());
                            handler.handle(event);
                        }
                    }
                });
            } else {
                log.error("Structure " + id + " transition error.");
                log.error(event.body().encode());
                handler.handle(event);
            }
        }
    });
}

From source file:org.entcore.feeder.dictionary.users.PersEducNat.java

License:Open Source License

public void createOrUpdatePersonnel(JsonObject object, String profileExternalId,
        JsonArray structuresByFunctions, String[][] linkClasses, String[][] linkGroups, boolean nodeQueries,
        boolean relationshipQueries) {
    final String error = personnelValidator.validate(object);
    if (error != null) {
        if (object.getJsonArray("profiles") != null && object.getJsonArray("profiles").size() == 1) {
            report.addIgnored(object.getJsonArray("profiles").getString(0), error, object);
        } else {/*from   w  w w.j  a  v a2 s .c  om*/
            report.addIgnored("Personnel", error, object);
        }
        log.warn(error);
    } else {
        if (nodeQueries) {
            object.put("source", currentSource);
            if (userImportedExternalId != null) {
                userImportedExternalId.add(object.getString("externalId"));
            }
            StringBuilder sb = new StringBuilder();
            JsonObject params;
            sb.append("MERGE (u:`User` { externalId : {externalId}}) ");
            sb.append("ON CREATE SET u.id = {id}, u.login = {login}, u.activationCode = {activationCode}, ");
            sb.append("u.displayName = {displayName}, u.created = {created} ");
            sb.append("WITH u ");
            if (!EDTImporter.EDT.equals(currentSource)) {
                sb.append("WHERE u.checksum IS NULL OR u.checksum <> {checksum} ");
            }
            sb.append("SET ").append(Neo4jUtils.nodeSetPropertiesFromJson("u", object, "id", "externalId",
                    "login", "activationCode", "displayName", "email", "created"));
            if (EDTImporter.EDT.equals(currentSource)) {
                sb.append("RETURN u.id as id, u.IDPN as IDPN, head(u.profiles) as profile");
            }
            params = object;
            transactionHelper.add(sb.toString(), params);
            checkUpdateEmail(object);
        }
        if (relationshipQueries) {
            final String externalId = object.getString("externalId");
            JsonArray structures = getMappingStructures(object.getJsonArray("structures"));
            if (externalId != null && structures != null && structures.size() > 0) {
                String query;
                JsonObject p = new JsonObject().put("userExternalId", externalId);
                if (structures.size() == 1) {
                    query = "MATCH (s:Structure {externalId : {structureAdmin}}), (u:User {externalId : {userExternalId}}) "
                            + "MERGE u-[:ADMINISTRATIVE_ATTACHMENT]->s ";
                    p.put("structureAdmin", structures.getString(0));
                } else {
                    query = "MATCH (s:Structure), (u:User {externalId : {userExternalId}}) "
                            + "WHERE s.externalId IN {structuresAdmin} "
                            + "MERGE u-[:ADMINISTRATIVE_ATTACHMENT]->s ";
                    p.put("structuresAdmin", structures);
                }
                transactionHelper.add(query, p);
            }
            if (externalId != null && structuresByFunctions != null && structuresByFunctions.size() > 0) {
                String query;
                structuresByFunctions = getMappingStructures(structuresByFunctions);
                JsonObject p = new JsonObject().put("userExternalId", externalId);
                if (structuresByFunctions.size() == 1) {
                    query = "MATCH (s:Structure {externalId : {structureAdmin}})<-[:DEPENDS]-(g:ProfileGroup)-[:HAS_PROFILE]->(p:Profile {externalId : {profileExternalId}}), "
                            + "(u:User { externalId : {userExternalId}}) " + "WHERE NOT(HAS(u.mergedWith)) "
                            + "MERGE u-[:IN]->g";
                    p.put("structureAdmin", structuresByFunctions.getString(0)).put("profileExternalId",
                            profileExternalId);
                } else {
                    query = "MATCH (s:Structure)<-[:DEPENDS]-(g:ProfileGroup)-[:HAS_PROFILE]->(p:Profile), "
                            + "(u:User { externalId : {userExternalId}}) "
                            + "WHERE s.externalId IN {structuresAdmin} AND NOT(HAS(u.mergedWith)) "
                            + "AND p.externalId = {profileExternalId} " + "MERGE u-[:IN]->g ";
                    p.put("structuresAdmin", structuresByFunctions).put("profileExternalId", profileExternalId);
                }
                transactionHelper.add(query, p);
                String qs = "MATCH (:User {externalId : {userExternalId}})-[r:IN|COMMUNIQUE]-(:Group)-[:DEPENDS]->(s:Structure) "
                        + "WHERE NOT(s.externalId IN {structures}) AND (NOT(HAS(r.source)) OR r.source = {source}) "
                        + "DELETE r";
                JsonObject ps = new JsonObject().put("userExternalId", externalId).put("source", currentSource)
                        .put("structures", structuresByFunctions);
                transactionHelper.add(qs, ps);
                final String daa = "MATCH (u:User {externalId : {userExternalId}})-[r:ADMINISTRATIVE_ATTACHMENT]->(s:Structure) "
                        + "WHERE NOT(s.externalId IN {structures}) AND (NOT(HAS(r.source)) OR r.source = {source}) "
                        + "DELETE r";
                transactionHelper.add(daa, ps.copy().put("structures", getOrElse(structures, new JsonArray())));
            }
            final JsonObject fosm = new JsonObject();
            final JsonArray classes = new fr.wseduc.webutils.collections.JsonArray();
            if (externalId != null && linkClasses != null) {
                final JsonObject fcm = new JsonObject();
                for (String[] structClass : linkClasses) {
                    if (structClass != null && structClass[0] != null && structClass[1] != null) {
                        classes.add(structClass[1]);
                        if (structClass.length > 2 && isNotEmpty(structClass[2])) {
                            JsonArray fClasses = fcm.getJsonArray(structClass[2]);
                            if (fClasses == null) {
                                fClasses = new fr.wseduc.webutils.collections.JsonArray();
                                fcm.put(structClass[2], fClasses);
                            }
                            fClasses.add(structClass[1]);
                        }
                    }
                }
                String query = "MATCH (c:Class)<-[:DEPENDS]-(g:ProfileGroup)"
                        + "-[:DEPENDS]->(pg:ProfileGroup)-[:HAS_PROFILE]->(p:Profile {externalId : {profileExternalId}}), "
                        + "(u:User { externalId : {userExternalId}}) "
                        + "WHERE c.externalId IN {classes} AND NOT(HAS(u.mergedWith)) " + "MERGE u-[:IN]->g";
                JsonObject p0 = new JsonObject().put("userExternalId", externalId)
                        .put("profileExternalId", profileExternalId).put("classes", classes);
                transactionHelper.add(query, p0);
                JsonObject p = new JsonObject().put("userExternalId", externalId).put("source", currentSource)
                        .put("classes", classes);
                fosm.mergeIn(fcm);
                for (String fos : fcm.fieldNames()) {
                    String q2 = "MATCH (u:User {externalId : {userExternalId}}), (f:FieldOfStudy {externalId:{feId}}) "
                            + "MERGE u-[r:TEACHES_FOS]->f " + "SET r.classes = {classes} ";
                    transactionHelper.add(q2, p.copy().put("classes", fcm.getJsonArray(fos)).put("feId", fos));
                }
            }
            if (externalId != null) {
                String q = "MATCH (:User {externalId : {userExternalId}})-[r:IN|COMMUNIQUE]-(:Group)-[:DEPENDS]->(c:Class) "
                        + "WHERE NOT(c.externalId IN {classes}) AND (NOT(HAS(r.source)) OR r.source = {source}) "
                        + "DELETE r";
                JsonObject p = new JsonObject().put("userExternalId", externalId).put("source", currentSource)
                        .put("classes", classes);
                transactionHelper.add(q, p);
            }
            final JsonArray groups = new fr.wseduc.webutils.collections.JsonArray();
            final JsonObject fgm = new JsonObject();
            if (externalId != null && linkGroups != null) {
                for (String[] structGroup : linkGroups) {
                    if (structGroup != null && structGroup[0] != null && structGroup[1] != null) {
                        groups.add(structGroup[1]);
                        if (structGroup.length > 2 && isNotEmpty(structGroup[2])) {
                            JsonArray fGroups = fgm.getJsonArray(structGroup[2]);
                            if (fGroups == null) {
                                fGroups = new fr.wseduc.webutils.collections.JsonArray();
                                fgm.put(structGroup[2], fGroups);
                            }
                            fGroups.add(structGroup[1]);
                        }
                    }
                }
                String query = "MATCH (g:Group), (u:User {externalId : {userExternalId}}) "
                        + "WHERE (g:FunctionalGroup OR g:FunctionGroup OR g:HTGroup) AND g.externalId IN {groups} "
                        + "MERGE u-[:IN]->g";
                JsonObject p = new JsonObject().put("userExternalId", externalId).put("groups", groups);
                transactionHelper.add(query, p);
            }
            if (externalId != null) {
                final String qdfg = "MATCH (:User {externalId : {userExternalId}})-[r:IN|COMMUNIQUE]-(g:Group) "
                        + "WHERE (g:FunctionalGroup OR g:FunctionGroup OR g:HTGroup) AND "
                        + "NOT(g.externalId IN {groups}) AND (NOT(HAS(r.source)) OR r.source = {source}) "
                        + "DELETE r";
                final JsonObject pdfg = new JsonObject().put("userExternalId", externalId)
                        .put("source", currentSource).put("groups", groups);
                transactionHelper.add(qdfg, pdfg);
                fosm.mergeIn(fgm);
                final String deleteOldFoslg = "MATCH (u:User {externalId : {userExternalId}})-[r:TEACHES_FOS]->(f:FieldOfStudy) "
                        + "WHERE NOT(f.externalId IN {fos}) AND (NOT(HAS(r.source)) OR r.source = {source}) "
                        + "DELETE r";
                transactionHelper.add(deleteOldFoslg, pdfg.copy().put("fos",
                        new fr.wseduc.webutils.collections.JsonArray(new ArrayList<>(fosm.fieldNames()))));
                for (String fos : fgm.fieldNames()) {
                    String q2 = "MATCH (u:User {externalId : {userExternalId}}), (f:FieldOfStudy {externalId:{feId}}) "
                            + "MERGE u-[r:TEACHES_FOS]->f " + "SET r.groups = {groups} ";
                    transactionHelper.add(q2,
                            pdfg.copy().put("groups", fgm.getJsonArray(fos)).put("feId", fos));
                }
            }
        }
    }
}