Skip to content

Commit

Permalink
Use EId::forNode when creating new nodes with eids
Browse files Browse the repository at this point in the history
RISDEV-4486
  • Loading branch information
malte-laukoetter committed Aug 28, 2024
1 parent b60b2e9 commit ae20c47
Show file tree
Hide file tree
Showing 15 changed files with 93 additions and 143 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import de.bund.digitalservice.ris.norms.application.port.input.UpdateActiveModificationsUseCase;
import de.bund.digitalservice.ris.norms.application.port.input.UpdatePassiveModificationsUseCase;
import de.bund.digitalservice.ris.norms.domain.entity.*;
import de.bund.digitalservice.ris.norms.utils.EidConsistencyGuardian;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -56,6 +57,7 @@ public Norm updatePassiveModifications(UpdatePassiveModificationsUseCase.Query q

// clean up existing passive modifications stemming from the amending zf0Norm
removePassiveModificationsThatStemFromSource(norm, query.amendingNorm().getEli());
EidConsistencyGuardian.correctEids(norm.getDocument());

final List<TextualMod> activeModificationsToAdd =
query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,7 @@ public List<TextualMod> getPassiveModifications() {
*/
public Node getOrCreatePassiveModificationsNode() {
return NodeParser.getNodeFromExpression("./passiveModifications", node)
.orElseGet(
() ->
NodeCreator.createElementWithEidAndGuid(
"akn:passiveModifications", "pasmod", node));
.orElseGet(() -> NodeCreator.createElementWithEidAndGuid("akn:passiveModifications", node));
}

/**
Expand All @@ -72,24 +69,22 @@ public TextualMod addPassiveModification(
var passiveModificationsNode = getOrCreatePassiveModificationsNode();

var textualMod =
NodeCreator.createElementWithEidAndGuid(
"akn:textualMod", "textualmod", passiveModificationsNode);
NodeCreator.createElementWithEidAndGuid("akn:textualMod", passiveModificationsNode);
textualMod.setAttribute("type", type);
passiveModificationsNode.appendChild(textualMod);

var source = NodeCreator.createElementWithEidAndGuid("akn:source", "source", textualMod);
var source = NodeCreator.createElementWithEidAndGuid("akn:source", textualMod);
source.setAttribute("href", sourceHref);
textualMod.appendChild(source);

var destination =
NodeCreator.createElementWithEidAndGuid("akn:destination", "destination", textualMod);
var destination = NodeCreator.createElementWithEidAndGuid("akn:destination", textualMod);
destination.setAttribute("href", destinationHref);
if (StringUtils.isNotEmpty(destinationUpTo)) {
destination.setAttribute("upTo", destinationUpTo);
}
textualMod.appendChild(destination);

var force = NodeCreator.createElementWithEidAndGuid("akn:force", "gelzeitnachw", textualMod);
var force = NodeCreator.createElementWithEidAndGuid("akn:force", textualMod);
force.setAttribute("period", periodHref);
textualMod.appendChild(force);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ public void setFRBRaliasPreviousVersionId(final UUID uuid) {
.orElseGet(
() -> {
final Element newElement =
NodeCreator.createElementWithEidAndGuid(
"akn:FRBRalias", "meta-1_ident-1_frbrexpression-1_frbralias-1", getNode());
NodeCreator.createElementWithEidAndGuid("akn:FRBRalias", getNode());
newElement.setAttribute("name", "vorherige-version-id");
newElement.setAttribute(VALUE_ATTIBUTE, uuid.toString());
getNode().appendChild(newElement);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ public TemporalData getOrCreateTemporalDataNode() {
try {
return getTemporalData();
} catch (final MandatoryNodeNotFoundException e) {
final var newElement =
NodeCreator.createElementWithEidAndGuid("akn:temporalData", "analysis", node);
final var newElement = NodeCreator.createElementWithEidAndGuid("akn:temporalData", node);
newElement.setAttribute(SOURCE_ATTIBUTE, ATTRIBUTSEMANTIK_NOCH_UNDEFINIERT);
return new TemporalData(newElement);
}
Expand Down Expand Up @@ -103,8 +102,7 @@ public Analysis getOrCreateAnalysis() {
return getAnalysis()
.orElseGet(
() -> {
final var newElement =
NodeCreator.createElementWithEidAndGuid("akn:analysis", "analysis", node);
final var newElement = NodeCreator.createElementWithEidAndGuid("akn:analysis", node);
newElement.setAttribute(SOURCE_ATTIBUTE, ATTRIBUTSEMANTIK_NOCH_UNDEFINIERT);
return new Analysis(newElement);
});
Expand All @@ -121,7 +119,7 @@ public Proprietary getOrCreateProprietary() {
.orElseGet(
() -> {
final var newElement =
NodeCreator.createElementWithEidAndGuid("akn:proprietary", "proprietary", node);
NodeCreator.createElementWithEidAndGuid("akn:proprietary", node);
newElement.setAttribute(SOURCE_ATTIBUTE, ATTRIBUTSEMANTIK_NOCH_UNDEFINIERT);
return new Proprietary(newElement);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,30 +188,24 @@ public Optional<String> getStartDateForEventRef(String eId) {
public TemporalGroup addTimeBoundary(LocalDate date, EventRefType eventRefType) {
// Create new eventRef node
final Node livecycle = getTimeBoundaries().getLast().getEventRef().getNode().getParentNode();
final Element eventRef =
NodeCreator.createElementWithEidAndGuid("akn:eventRef", "ereignis", livecycle);
final Element eventRef = NodeCreator.createElementWithEidAndGuid("akn:eventRef", livecycle);
eventRef.setAttribute("date", date.toString());
eventRef.setAttribute("source", "attributsemantik-noch-undefiniert");
eventRef.setAttribute("type", eventRefType.getValue());
eventRef.setAttribute("refersTo", "inkrafttreten");
livecycle.appendChild(eventRef);

// Create new temporalGroup node
final TemporalData temporalData = getMeta().getTemporalData();
final Element temporalGroup =
NodeCreator.createElementWithEidAndGuid(
"akn:temporalGroup", "geltungszeitgr", temporalData.getNode());
temporalData.getNode().appendChild(temporalGroup);
NodeCreator.createElementWithEidAndGuid("akn:temporalGroup", temporalData.getNode());

// Create new timeInterval node
final Element timeInterval =
NodeCreator.createElementWithEidAndGuid(
"akn:timeInterval", "gelzeitintervall", temporalGroup);
NodeCreator.createElementWithEidAndGuid("akn:timeInterval", temporalGroup);
timeInterval.setAttribute("refersTo", "geltungszeit");
final var eventRefEId = eventRef.getAttribute("eId");
timeInterval.setAttribute(
"start", new Href.Builder().setEId(eventRefEId).buildInternalReference().value());
temporalGroup.appendChild(timeInterval);

return new TemporalGroup(temporalGroup);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package de.bund.digitalservice.ris.norms.utils;

import de.bund.digitalservice.ris.norms.domain.entity.EId;
import de.bund.digitalservice.ris.norms.domain.entity.EIdPart;
import java.util.Comparator;
import java.util.UUID;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
Expand Down Expand Up @@ -32,16 +30,14 @@ public static Element createElement(final String tagName, final Node parentNode)
* parent node.
*
* @param tagName the tag name of the new element
* @param eidPartName the name for the last part of the eid for the new element
* @param parentNode the element of which this newly created element should be a child
* @return the newly created element
*/
public static Element createElementWithEidAndGuid(
final String tagName, final String eidPartName, final Node parentNode) {
public static Element createElementWithEidAndGuid(final String tagName, final Node parentNode) {
var newElement = parentNode.getOwnerDocument().createElement(tagName);
newElement.setAttribute("eId", calculateNextPossibleEid(parentNode, eidPartName));
newElement.setAttribute("GUID", UUID.randomUUID().toString());
parentNode.appendChild(newElement);
EId.forNode(newElement).ifPresent(eId -> newElement.setAttribute("eId", eId.value()));
return newElement;
}

Expand All @@ -62,30 +58,4 @@ public static Element createElementWithStaticEidAndGuidNoAppend(
newElement.setAttribute("GUID", UUID.randomUUID().toString());
return newElement;
}

/**
* Calculates the next possible eId for the given eIdPartType and parent node.
*
* @param parentNode The parent node under which this new eId should be used
* @param eidPartType The name of the new part of the eId
* @return The new eId created from the parent node eId, the eidPartType and the next available
* position
*/
public static String calculateNextPossibleEid(Node parentNode, String eidPartType) {
var lastPosition =
NodeParser.nodeListToList(parentNode.getChildNodes()).stream()
.flatMap(node -> EId.fromNode(node).stream())
.map(eId -> eId.getParts().getLast())
.filter(eIdPart -> eIdPart.getType().equals(eidPartType))
.map(EIdPart::getPosition)
.map(Integer::parseInt)
.max(Comparator.comparingInt(Integer::intValue))
.orElse(0);
var newEidPart = new EIdPart(eidPartType, String.valueOf(lastPosition + 1));

return EId.fromNode(parentNode)
.map(parendEId -> parendEId.addPart(newEidPart))
.map(EId::value)
.orElseThrow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void itChangesNothingImportantIfPassiveModificationsAlreadyExist() {
.contains(
new Href("#hauptteil-1_para-20_abs-1_untergl-1_listenelem-2_inhalt-1_text-1/9-34"));
assertThat(passiveModification.getForcePeriodEid())
.contains("meta-1_geltzeiten-1_geltungszeitgr-5");
.contains("meta-1_geltzeiten-1_geltungszeitgr-4");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import de.bund.digitalservice.ris.norms.utils.NodeCreator;
import de.bund.digitalservice.ris.norms.utils.NodeParser;
import de.bund.digitalservice.ris.norms.utils.XmlMapper;
import de.bund.digitalservice.ris.norms.utils.exceptions.MandatoryNodeNotFoundException;
import java.time.LocalDate;
import java.util.*;
Expand Down Expand Up @@ -1125,52 +1124,6 @@ void deleteTimeBoundary() {
.contains("#" + timeBoundaries.get(0).getEventRefEid().get());
}

@Test
void calculateNextPossibleEid() {
// given
Node parentNode =
XmlMapper.toNode(
"""
<akn:temporalData xmlns:akn="http://Inhaltsdaten.LegalDocML.de/1.6/" eId="meta-1_geltzeiten-1"
GUID="2fcdfa3e-1460-4ef4-b22b-5ff4a897538f"
source="attributsemantik-noch-undefiniert">
<akn:temporalGroup eId="meta-1_geltzeiten-1_geltungszeitgr-1"
GUID="7b13adb9-ef62-43c4-bf1b-155561edf89b">
</akn:temporalGroup>
<akn:temporalGroup eId="meta-1_geltzeiten-1_geltungszeitgr-2"
GUID="7af9337a-3727-424c-a3df-dee918a79b22">
</akn:temporalGroup>
</akn:temporalData>
""");

// when
final String nextPossibleEid =
NodeCreator.calculateNextPossibleEid(parentNode, "geltungszeitgr");

// then
assertThat(nextPossibleEid).contains("meta-1_geltzeiten-1_geltungszeitgr-3");
}

@Test
void calculateNextPossibleEidWhenNoChildNodeOfTypeExists() {
// given
Node parentNode =
XmlMapper.toNode(
"""
<akn:temporalData xmlns:akn="http://Inhaltsdaten.LegalDocML.de/1.6/" eId="meta-1_geltzeiten-1"
GUID="2fcdfa3e-1460-4ef4-b22b-5ff4a897538f"
source="attributsemantik-noch-undefiniert">
</akn:temporalData>
""");

// when
final String nextPossibleEid =
NodeCreator.calculateNextPossibleEid(parentNode, "geltungszeitgr");

// then
assertThat(nextPossibleEid).contains("meta-1_geltzeiten-1_geltungszeitgr-1");
}

@Test
void getMods() {
// given
Expand Down Expand Up @@ -1231,8 +1184,7 @@ void itShouldCreatesANewElement() {
NodeParser.getNodeFromExpression("//act/meta", norm.getDocument()).orElseThrow();

// when
final Node createdNode =
NodeCreator.createElementWithEidAndGuid("akn:analysis", "analysis", parentNode);
final Node createdNode = NodeCreator.createElementWithEidAndGuid("akn:analysis", parentNode);

// then
assertThat(NodeParser.getNodeFromExpression("//act/meta/analysis", norm.getDocument()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ void itUpdatesASingleMod() throws Exception {
XmlMatcher.xml(
hasXPath(
"//passiveModifications/textualMod/force/@period",
equalTo("#meta-1_geltzeiten-1_geltungszeitgr-5")))))
equalTo("#meta-1_geltzeiten-1_geltungszeitgr-4")))))
.andExpect(
jsonPath("targetNormZf0Xml")
.value(
Expand Down Expand Up @@ -1114,7 +1114,7 @@ void itDryRunsTheUpdate() throws Exception {
XmlMatcher.xml(
hasXPath(
"//textualMod[@eId=\"meta-1_analysis-1_pasmod-1_textualmod-1\"]/force/@period",
equalTo("#meta-1_geltzeiten-1_geltungszeitgr-5")))));
equalTo("#meta-1_geltzeiten-1_geltungszeitgr-4")))));

// saved norm is unchanged
mockMvc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,19 @@ void createElementWithEidAndGuid() {
XmlMapper.toDocument(
"""
<root>
<test eId="test-1">test value</test>
<akn:p eId="text-1">test value</akn:p>
</root>""");
final Node testNode = NodeParser.getMandatoryNodeFromExpression("//test", document);
final Node testNode = NodeParser.getMandatoryNodeFromExpression("//*/p", document);

// when
final Element newElement =
NodeCreator.createElementWithEidAndGuid("childTest", "child-test", testNode);
final Element newElement = NodeCreator.createElementWithEidAndGuid("akn:ref", testNode);

// Then
final Node childTestNode =
NodeParser.getMandatoryNodeFromExpression("//test/childTest", document);
final Node childTestNode = NodeParser.getMandatoryNodeFromExpression("//p/ref", document);
assertThat(childTestNode).isEqualTo(newElement);
assertThat(childTestNode.getAttributes().getNamedItem("GUID")).isNotNull();
assertThat(childTestNode.getAttributes().getNamedItem("eId").getNodeValue())
.isEqualTo("test-1_child-test-1");
.isEqualTo("text-1_ref-1");
}

@Test
Expand All @@ -78,22 +76,4 @@ void createElementWithStaticEidAndGuidNoAppend() {
assertThat(newElement.getAttributes().getNamedItem("eId").getNodeValue())
.isEqualTo("test-1_child-test-1");
}

@Test
void calculateNextPossibleEid() {
// given
final Document document =
XmlMapper.toDocument(
"""
<root>
<test eId="test-1">test value</test>
</root>""");
final Node testNode = NodeParser.getMandatoryNodeFromExpression("//test", document);

// when
final String nextPossibleEid = NodeCreator.calculateNextPossibleEid(testNode, "child-test");

// Then
assertThat(nextPossibleEid).isEqualTo("test-1_child-test-1");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@
refersTo="geltungszeit" start="#meta-1_lebzykl-1_ereignis-2"/>
</akn:temporalGroup>
</akn:temporalData>
<akn:proprietary eId="meta-1_proprietary-1" GUID="fe419055-3201-41b1-b096-402eabcbe6a1"
source="attributsemantik-noch-undefiniert">
<meta:legalDocML.de_metadaten xmlns:meta="http://Metadaten.LegalDocML.de/1.6/">
<meta:typ>gesetz</meta:typ>
<meta:form>mantelform</meta:form>
<meta:fassung>verkuendungsfassung</meta:fassung>
<meta:art>regelungstext</meta:art>
<meta:initiant>bundesregierung</meta:initiant>
<meta:bearbeitendeInstitution>bundesregierung</meta:bearbeitendeInstitution>
<meta:fna>nicht-vorhanden</meta:fna>
</meta:legalDocML.de_metadaten>
</akn:proprietary>

</akn:meta>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,18 @@
GUID="b5f2b610-ea4e-43dc-9262-8afe1a812000"></akn:timeInterval>
</akn:temporalGroup>
</akn:temporalData>
<akn:proprietary eId="meta-1_proprietary-1" GUID="fe419055-3201-41b1-b096-402eabcbe6a1"
source="attributsemantik-noch-undefiniert">
<meta:legalDocML.de_metadaten xmlns:meta="http://Metadaten.LegalDocML.de/1.6/">
<meta:typ>gesetz</meta:typ>
<meta:form>mantelform</meta:form>
<meta:fassung>verkuendungsfassung</meta:fassung>
<meta:art>regelungstext</meta:art>
<meta:initiant>bundesregierung</meta:initiant>
<meta:bearbeitendeInstitution>bundesregierung</meta:bearbeitendeInstitution>
<meta:fna>nicht-vorhanden</meta:fna>
</meta:legalDocML.de_metadaten>
</akn:proprietary>
</akn:meta>

<akn:preface eId="einleitung-1" GUID="5d844674-c11c-45bf-9bb8-4d54fe108c66">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,18 @@
GUID="f11ec4d9-a419-4288-b47c-0b0341a3cf74"></akn:timeInterval>
</akn:temporalGroup>
</akn:temporalData>
<akn:proprietary eId="meta-1_proprietary-1" GUID="fe419055-3201-41b1-b096-402eabcbe6a1"
source="attributsemantik-noch-undefiniert">
<meta:legalDocML.de_metadaten xmlns:meta="http://Metadaten.LegalDocML.de/1.6/">
<meta:typ>gesetz</meta:typ>
<meta:form>stammform</meta:form>
<meta:fassung>verkuendungsfassung</meta:fassung>
<meta:art>regelungstext</meta:art>
<meta:initiant>bundesregierung</meta:initiant>
<meta:bearbeitendeInstitution>bundesregierung</meta:bearbeitendeInstitution>
<meta:fna>nicht-vorhanden</meta:fna>
</meta:legalDocML.de_metadaten>
</akn:proprietary>
</akn:meta>

<akn:preface eId="einleitung-1" GUID="e1d90925-6093-41d9-84e1-df810c83a024">
Expand Down
Loading

0 comments on commit ae20c47

Please sign in to comment.