From f89e3367eab65617ca2f7746ab4ceee273c5cac0 Mon Sep 17 00:00:00 2001 From: sofi2002sofi Date: Tue, 1 Nov 2022 12:55:41 -0300 Subject: [PATCH] CARDS-1937: Computed answers: implement deletion the value of dependent on change reference answers computed answers changed the logic of searching dependent computed answers --- .../ReferenceAnswersChangedListener.java | 84 +++++++++++-------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/modules/data-model/forms/impl/src/main/java/io/uhndata/cards/forms/internal/ReferenceAnswersChangedListener.java b/modules/data-model/forms/impl/src/main/java/io/uhndata/cards/forms/internal/ReferenceAnswersChangedListener.java index 348691ace9..455af18944 100644 --- a/modules/data-model/forms/impl/src/main/java/io/uhndata/cards/forms/internal/ReferenceAnswersChangedListener.java +++ b/modules/data-model/forms/impl/src/main/java/io/uhndata/cards/forms/internal/ReferenceAnswersChangedListener.java @@ -17,7 +17,6 @@ package io.uhndata.cards.forms.internal; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -65,12 +64,6 @@ public class ReferenceAnswersChangedListener implements ResourceChangeListener public static final String VALUE = "value"; private static final Logger LOGGER = LoggerFactory.getLogger(ReferenceAnswersChangedListener.class); - /** Computed answers' paths that values need to be changed, with appropriate parent form path. **/ - private final Map toBeDeleted = new HashMap<>(); - - /** Set of changed reference answers' paths per form. **/ - private final Map> changedReferenceAnswers = new HashMap<>(); - /** Provides access to resources. */ @Reference private volatile ResourceResolverFactory resolverFactory; @@ -116,9 +109,13 @@ private void handleEvent(final ResourceChange event) this.rrp.push(localResolver); NodeIterator children = form.getNodes(); final VersionManager versionManager = session.getWorkspace().getVersionManager(); - checkAndUpdateAnswersValues(children, localResolver, session, versionManager); - searchComputedReferenceAnswers(); - deleteComputedReferenceAnswersValues(session, versionManager); + Set nodesToBeDeleted = new HashSet<>(); + Set updatedReferenceAnswersPaths = checkAndUpdateAnswersValues(children, localResolver, session, + versionManager); + for (String answerPath : updatedReferenceAnswersPaths) { + nodesToBeDeleted.addAll(searchComputedReferenceAnswers(answerPath, session)); + } + deleteComputedReferenceAnswersValues(nodesToBeDeleted, session, versionManager); } catch (RepositoryException e) { LOGGER.error(e.getMessage(), e); } finally { @@ -141,10 +138,11 @@ private void handleEvent(final ResourceChange event) * @param serviceResolver a ResourceResolver that can be used for querying the JCR * @param session a service session providing access to the repository */ - private void checkAndUpdateAnswersValues(final NodeIterator nodeIterator, final ResourceResolver serviceResolver, - final Session session, final VersionManager versionManager) - throws RepositoryException + private Set checkAndUpdateAnswersValues(final NodeIterator nodeIterator, + final ResourceResolver serviceResolver, final Session session, + final VersionManager versionManager) throws RepositoryException { + Set changedReferenceAnswersPaths = new HashSet<>(); Set checkoutPaths = new HashSet<>(); while (nodeIterator.hasNext()) { final Node node = nodeIterator.nextNode(); @@ -174,7 +172,7 @@ private void checkAndUpdateAnswersValues(final NodeIterator nodeIterator, final Node changingAnswer = this.formUtils.getAnswer(formNode, getQuestionNode(referenceAnswer, session, serviceResolver)); changingAnswer.setProperty(VALUE, sourceAnswerValue.getValue()); - addChangedReferenceAnswer(formNode, referenceAnswer.getPath()); + changedReferenceAnswersPaths.add(referenceAnswer.getPath()); } } } @@ -183,26 +181,28 @@ private void checkAndUpdateAnswersValues(final NodeIterator nodeIterator, final for (String path : checkoutPaths) { versionManager.checkin(path); } + return changedReferenceAnswersPaths; } - private void searchComputedReferenceAnswers() throws RepositoryException + private Set searchComputedReferenceAnswers(String computedFromAnswerPath, Session session) + throws RepositoryException { - for (Map.Entry> changedReferenceAnswersPerForm : this.changedReferenceAnswers.entrySet()) { - final Node formNode = changedReferenceAnswersPerForm.getKey(); - final NodeIterator children = formNode.getNodes(); - final Set changedReferenceAnswersPaths = changedReferenceAnswersPerForm.getValue(); - searchForComputedReferencesAnswers(formNode, children, changedReferenceAnswersPaths); - } + final Node formNode = getParentFormNode(session.getNode(computedFromAnswerPath)); + final NodeIterator children = formNode.getNodes(); + return searchForComputedReferencesAnswers(children, computedFromAnswerPath); } - private void searchForComputedReferencesAnswers(final Node parentFormNode, final NodeIterator nodes, - final Set changedReferenceAnswersPaths) + private Set searchForComputedReferencesAnswers(final NodeIterator nodes, + final String changedReferenceAnswerPath) throws RepositoryException { + Set nodesToBeDeleted = new HashSet<>(); while (nodes.hasNext()) { final Node node = nodes.nextNode(); if (node.isNodeType("cards:AnswerSection")) { - searchForComputedReferencesAnswers(parentFormNode, node.getNodes(), changedReferenceAnswersPaths); + nodesToBeDeleted.addAll( + searchForComputedReferencesAnswers(node.getNodes(), changedReferenceAnswerPath)); + continue; } if (!node.hasProperty("computedFrom")) { @@ -211,25 +211,25 @@ private void searchForComputedReferencesAnswers(final Node parentFormNode, final Value[] computedFromPropertyValues = node.getProperty("computedFrom").getValues(); for (Value computedFromPropertyValue : computedFromPropertyValues) { - if (changedReferenceAnswersPaths.contains(computedFromPropertyValue.getString())) { + if (!changedReferenceAnswerPath.equals(computedFromPropertyValue.getString())) { continue; } - this.toBeDeleted.put(node.getPath(), parentFormNode.getPath()); + nodesToBeDeleted.add(node); break; } } + return nodesToBeDeleted; } - private void deleteComputedReferenceAnswersValues(final Session session, final VersionManager versionManager) - throws RepositoryException + private void deleteComputedReferenceAnswersValues(final Set nodesToBeDeleted, final Session session, + final VersionManager versionManager) throws RepositoryException { Set checkoutPaths = new HashSet<>(); - for (Map.Entry changedComputedReferenceAnswer : this.toBeDeleted.entrySet()) { - final String formPath = changedComputedReferenceAnswer.getValue(); + for (Node node : nodesToBeDeleted) { + final String formPath = getParentFormNode(node).getPath(); versionManager.checkout(formPath); checkoutPaths.add(formPath); - Node changingComputerAnswer = session.getNode(changedComputedReferenceAnswer.getKey()); - changingComputerAnswer.remove(); + node.remove(); } session.save(); for (String path : checkoutPaths) { @@ -278,12 +278,22 @@ private String getParentFormPath(Resource child) return parent.getPath(); } - private void addChangedReferenceAnswer(final Node formNode, final String path) + /** + * Gets the node of the parent Form for a given descendant node. + * + * @param child node for which the parent form is sought + * @return node of the parent form + */ + private Node getParentFormNode(Node child) throws RepositoryException { - if (this.changedReferenceAnswers.containsKey(formNode)) { - this.changedReferenceAnswers.get(formNode).add(path); - } else { - this.changedReferenceAnswers.put(formNode, Set.of(path)); + Node parent = child.getParent(); + + if (parent == null) { + return null; + } + if (!parent.isNodeType("cards:Form")) { + return getParentFormNode(parent); } + return parent; } }