Skip to content

Commit ae20c47

Browse files
Use EId::forNode when creating new nodes with eids
RISDEV-4486
1 parent b60b2e9 commit ae20c47

File tree

15 files changed

+93
-143
lines changed

15 files changed

+93
-143
lines changed

backend/src/main/java/de/bund/digitalservice/ris/norms/application/service/UpdateNormService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import de.bund.digitalservice.ris.norms.application.port.input.UpdateActiveModificationsUseCase;
44
import de.bund.digitalservice.ris.norms.application.port.input.UpdatePassiveModificationsUseCase;
55
import de.bund.digitalservice.ris.norms.domain.entity.*;
6+
import de.bund.digitalservice.ris.norms.utils.EidConsistencyGuardian;
67
import java.time.LocalDate;
78
import java.util.HashMap;
89
import java.util.List;
@@ -56,6 +57,7 @@ public Norm updatePassiveModifications(UpdatePassiveModificationsUseCase.Query q
5657

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

6062
final List<TextualMod> activeModificationsToAdd =
6163
query

backend/src/main/java/de/bund/digitalservice/ris/norms/domain/entity/Analysis.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,7 @@ public List<TextualMod> getPassiveModifications() {
4646
*/
4747
public Node getOrCreatePassiveModificationsNode() {
4848
return NodeParser.getNodeFromExpression("./passiveModifications", node)
49-
.orElseGet(
50-
() ->
51-
NodeCreator.createElementWithEidAndGuid(
52-
"akn:passiveModifications", "pasmod", node));
49+
.orElseGet(() -> NodeCreator.createElementWithEidAndGuid("akn:passiveModifications", node));
5350
}
5451

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

7471
var textualMod =
75-
NodeCreator.createElementWithEidAndGuid(
76-
"akn:textualMod", "textualmod", passiveModificationsNode);
72+
NodeCreator.createElementWithEidAndGuid("akn:textualMod", passiveModificationsNode);
7773
textualMod.setAttribute("type", type);
7874
passiveModificationsNode.appendChild(textualMod);
7975

80-
var source = NodeCreator.createElementWithEidAndGuid("akn:source", "source", textualMod);
76+
var source = NodeCreator.createElementWithEidAndGuid("akn:source", textualMod);
8177
source.setAttribute("href", sourceHref);
8278
textualMod.appendChild(source);
8379

84-
var destination =
85-
NodeCreator.createElementWithEidAndGuid("akn:destination", "destination", textualMod);
80+
var destination = NodeCreator.createElementWithEidAndGuid("akn:destination", textualMod);
8681
destination.setAttribute("href", destinationHref);
8782
if (StringUtils.isNotEmpty(destinationUpTo)) {
8883
destination.setAttribute("upTo", destinationUpTo);
8984
}
9085
textualMod.appendChild(destination);
9186

92-
var force = NodeCreator.createElementWithEidAndGuid("akn:force", "gelzeitnachw", textualMod);
87+
var force = NodeCreator.createElementWithEidAndGuid("akn:force", textualMod);
9388
force.setAttribute("period", periodHref);
9489
textualMod.appendChild(force);
9590

backend/src/main/java/de/bund/digitalservice/ris/norms/domain/entity/FRBRExpression.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ public void setFRBRaliasPreviousVersionId(final UUID uuid) {
4141
.orElseGet(
4242
() -> {
4343
final Element newElement =
44-
NodeCreator.createElementWithEidAndGuid(
45-
"akn:FRBRalias", "meta-1_ident-1_frbrexpression-1_frbralias-1", getNode());
44+
NodeCreator.createElementWithEidAndGuid("akn:FRBRalias", getNode());
4645
newElement.setAttribute("name", "vorherige-version-id");
4746
newElement.setAttribute(VALUE_ATTIBUTE, uuid.toString());
4847
getNode().appendChild(newElement);

backend/src/main/java/de/bund/digitalservice/ris/norms/domain/entity/Meta.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ public TemporalData getOrCreateTemporalDataNode() {
6969
try {
7070
return getTemporalData();
7171
} catch (final MandatoryNodeNotFoundException e) {
72-
final var newElement =
73-
NodeCreator.createElementWithEidAndGuid("akn:temporalData", "analysis", node);
72+
final var newElement = NodeCreator.createElementWithEidAndGuid("akn:temporalData", node);
7473
newElement.setAttribute(SOURCE_ATTIBUTE, ATTRIBUTSEMANTIK_NOCH_UNDEFINIERT);
7574
return new TemporalData(newElement);
7675
}
@@ -103,8 +102,7 @@ public Analysis getOrCreateAnalysis() {
103102
return getAnalysis()
104103
.orElseGet(
105104
() -> {
106-
final var newElement =
107-
NodeCreator.createElementWithEidAndGuid("akn:analysis", "analysis", node);
105+
final var newElement = NodeCreator.createElementWithEidAndGuid("akn:analysis", node);
108106
newElement.setAttribute(SOURCE_ATTIBUTE, ATTRIBUTSEMANTIK_NOCH_UNDEFINIERT);
109107
return new Analysis(newElement);
110108
});
@@ -121,7 +119,7 @@ public Proprietary getOrCreateProprietary() {
121119
.orElseGet(
122120
() -> {
123121
final var newElement =
124-
NodeCreator.createElementWithEidAndGuid("akn:proprietary", "proprietary", node);
122+
NodeCreator.createElementWithEidAndGuid("akn:proprietary", node);
125123
newElement.setAttribute(SOURCE_ATTIBUTE, ATTRIBUTSEMANTIK_NOCH_UNDEFINIERT);
126124
return new Proprietary(newElement);
127125
});

backend/src/main/java/de/bund/digitalservice/ris/norms/domain/entity/Norm.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -188,30 +188,24 @@ public Optional<String> getStartDateForEventRef(String eId) {
188188
public TemporalGroup addTimeBoundary(LocalDate date, EventRefType eventRefType) {
189189
// Create new eventRef node
190190
final Node livecycle = getTimeBoundaries().getLast().getEventRef().getNode().getParentNode();
191-
final Element eventRef =
192-
NodeCreator.createElementWithEidAndGuid("akn:eventRef", "ereignis", livecycle);
191+
final Element eventRef = NodeCreator.createElementWithEidAndGuid("akn:eventRef", livecycle);
193192
eventRef.setAttribute("date", date.toString());
194193
eventRef.setAttribute("source", "attributsemantik-noch-undefiniert");
195194
eventRef.setAttribute("type", eventRefType.getValue());
196195
eventRef.setAttribute("refersTo", "inkrafttreten");
197-
livecycle.appendChild(eventRef);
198196

199197
// Create new temporalGroup node
200198
final TemporalData temporalData = getMeta().getTemporalData();
201199
final Element temporalGroup =
202-
NodeCreator.createElementWithEidAndGuid(
203-
"akn:temporalGroup", "geltungszeitgr", temporalData.getNode());
204-
temporalData.getNode().appendChild(temporalGroup);
200+
NodeCreator.createElementWithEidAndGuid("akn:temporalGroup", temporalData.getNode());
205201

206202
// Create new timeInterval node
207203
final Element timeInterval =
208-
NodeCreator.createElementWithEidAndGuid(
209-
"akn:timeInterval", "gelzeitintervall", temporalGroup);
204+
NodeCreator.createElementWithEidAndGuid("akn:timeInterval", temporalGroup);
210205
timeInterval.setAttribute("refersTo", "geltungszeit");
211206
final var eventRefEId = eventRef.getAttribute("eId");
212207
timeInterval.setAttribute(
213208
"start", new Href.Builder().setEId(eventRefEId).buildInternalReference().value());
214-
temporalGroup.appendChild(timeInterval);
215209

216210
return new TemporalGroup(temporalGroup);
217211
}

backend/src/main/java/de/bund/digitalservice/ris/norms/utils/NodeCreator.java

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package de.bund.digitalservice.ris.norms.utils;
22

33
import de.bund.digitalservice.ris.norms.domain.entity.EId;
4-
import de.bund.digitalservice.ris.norms.domain.entity.EIdPart;
5-
import java.util.Comparator;
64
import java.util.UUID;
75
import org.w3c.dom.Element;
86
import org.w3c.dom.Node;
@@ -32,16 +30,14 @@ public static Element createElement(final String tagName, final Node parentNode)
3230
* parent node.
3331
*
3432
* @param tagName the tag name of the new element
35-
* @param eidPartName the name for the last part of the eid for the new element
3633
* @param parentNode the element of which this newly created element should be a child
3734
* @return the newly created element
3835
*/
39-
public static Element createElementWithEidAndGuid(
40-
final String tagName, final String eidPartName, final Node parentNode) {
36+
public static Element createElementWithEidAndGuid(final String tagName, final Node parentNode) {
4137
var newElement = parentNode.getOwnerDocument().createElement(tagName);
42-
newElement.setAttribute("eId", calculateNextPossibleEid(parentNode, eidPartName));
4338
newElement.setAttribute("GUID", UUID.randomUUID().toString());
4439
parentNode.appendChild(newElement);
40+
EId.forNode(newElement).ifPresent(eId -> newElement.setAttribute("eId", eId.value()));
4541
return newElement;
4642
}
4743

@@ -62,30 +58,4 @@ public static Element createElementWithStaticEidAndGuidNoAppend(
6258
newElement.setAttribute("GUID", UUID.randomUUID().toString());
6359
return newElement;
6460
}
65-
66-
/**
67-
* Calculates the next possible eId for the given eIdPartType and parent node.
68-
*
69-
* @param parentNode The parent node under which this new eId should be used
70-
* @param eidPartType The name of the new part of the eId
71-
* @return The new eId created from the parent node eId, the eidPartType and the next available
72-
* position
73-
*/
74-
public static String calculateNextPossibleEid(Node parentNode, String eidPartType) {
75-
var lastPosition =
76-
NodeParser.nodeListToList(parentNode.getChildNodes()).stream()
77-
.flatMap(node -> EId.fromNode(node).stream())
78-
.map(eId -> eId.getParts().getLast())
79-
.filter(eIdPart -> eIdPart.getType().equals(eidPartType))
80-
.map(EIdPart::getPosition)
81-
.map(Integer::parseInt)
82-
.max(Comparator.comparingInt(Integer::intValue))
83-
.orElse(0);
84-
var newEidPart = new EIdPart(eidPartType, String.valueOf(lastPosition + 1));
85-
86-
return EId.fromNode(parentNode)
87-
.map(parendEId -> parendEId.addPart(newEidPart))
88-
.map(EId::value)
89-
.orElseThrow();
90-
}
9161
}

backend/src/test/java/de/bund/digitalservice/ris/norms/application/service/UpdateNormServiceTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ void itChangesNothingImportantIfPassiveModificationsAlreadyExist() {
5050
.contains(
5151
new Href("#hauptteil-1_para-20_abs-1_untergl-1_listenelem-2_inhalt-1_text-1/9-34"));
5252
assertThat(passiveModification.getForcePeriodEid())
53-
.contains("meta-1_geltzeiten-1_geltungszeitgr-5");
53+
.contains("meta-1_geltzeiten-1_geltungszeitgr-4");
5454
}
5555

5656
@Test

backend/src/test/java/de/bund/digitalservice/ris/norms/domain/entity/NormTest.java

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import de.bund.digitalservice.ris.norms.utils.NodeCreator;
88
import de.bund.digitalservice.ris.norms.utils.NodeParser;
9-
import de.bund.digitalservice.ris.norms.utils.XmlMapper;
109
import de.bund.digitalservice.ris.norms.utils.exceptions.MandatoryNodeNotFoundException;
1110
import java.time.LocalDate;
1211
import java.util.*;
@@ -1125,52 +1124,6 @@ void deleteTimeBoundary() {
11251124
.contains("#" + timeBoundaries.get(0).getEventRefEid().get());
11261125
}
11271126

1128-
@Test
1129-
void calculateNextPossibleEid() {
1130-
// given
1131-
Node parentNode =
1132-
XmlMapper.toNode(
1133-
"""
1134-
<akn:temporalData xmlns:akn="http://Inhaltsdaten.LegalDocML.de/1.6/" eId="meta-1_geltzeiten-1"
1135-
GUID="2fcdfa3e-1460-4ef4-b22b-5ff4a897538f"
1136-
source="attributsemantik-noch-undefiniert">
1137-
<akn:temporalGroup eId="meta-1_geltzeiten-1_geltungszeitgr-1"
1138-
GUID="7b13adb9-ef62-43c4-bf1b-155561edf89b">
1139-
</akn:temporalGroup>
1140-
<akn:temporalGroup eId="meta-1_geltzeiten-1_geltungszeitgr-2"
1141-
GUID="7af9337a-3727-424c-a3df-dee918a79b22">
1142-
</akn:temporalGroup>
1143-
</akn:temporalData>
1144-
""");
1145-
1146-
// when
1147-
final String nextPossibleEid =
1148-
NodeCreator.calculateNextPossibleEid(parentNode, "geltungszeitgr");
1149-
1150-
// then
1151-
assertThat(nextPossibleEid).contains("meta-1_geltzeiten-1_geltungszeitgr-3");
1152-
}
1153-
1154-
@Test
1155-
void calculateNextPossibleEidWhenNoChildNodeOfTypeExists() {
1156-
// given
1157-
Node parentNode =
1158-
XmlMapper.toNode(
1159-
"""
1160-
<akn:temporalData xmlns:akn="http://Inhaltsdaten.LegalDocML.de/1.6/" eId="meta-1_geltzeiten-1"
1161-
GUID="2fcdfa3e-1460-4ef4-b22b-5ff4a897538f"
1162-
source="attributsemantik-noch-undefiniert">
1163-
</akn:temporalData>
1164-
""");
1165-
1166-
// when
1167-
final String nextPossibleEid =
1168-
NodeCreator.calculateNextPossibleEid(parentNode, "geltungszeitgr");
1169-
1170-
// then
1171-
assertThat(nextPossibleEid).contains("meta-1_geltzeiten-1_geltungszeitgr-1");
1172-
}
1173-
11741127
@Test
11751128
void getMods() {
11761129
// given
@@ -1231,8 +1184,7 @@ void itShouldCreatesANewElement() {
12311184
NodeParser.getNodeFromExpression("//act/meta", norm.getDocument()).orElseThrow();
12321185

12331186
// when
1234-
final Node createdNode =
1235-
NodeCreator.createElementWithEidAndGuid("akn:analysis", "analysis", parentNode);
1187+
final Node createdNode = NodeCreator.createElementWithEidAndGuid("akn:analysis", parentNode);
12361188

12371189
// then
12381190
assertThat(NodeParser.getNodeFromExpression("//act/meta/analysis", norm.getDocument()))

backend/src/test/java/de/bund/digitalservice/ris/norms/integration/adapter/input/restapi/NormControllerIntegrationTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ void itUpdatesASingleMod() throws Exception {
981981
XmlMatcher.xml(
982982
hasXPath(
983983
"//passiveModifications/textualMod/force/@period",
984-
equalTo("#meta-1_geltzeiten-1_geltungszeitgr-5")))))
984+
equalTo("#meta-1_geltzeiten-1_geltungszeitgr-4")))))
985985
.andExpect(
986986
jsonPath("targetNormZf0Xml")
987987
.value(
@@ -1114,7 +1114,7 @@ void itDryRunsTheUpdate() throws Exception {
11141114
XmlMatcher.xml(
11151115
hasXPath(
11161116
"//textualMod[@eId=\"meta-1_analysis-1_pasmod-1_textualmod-1\"]/force/@period",
1117-
equalTo("#meta-1_geltzeiten-1_geltungszeitgr-5")))));
1117+
equalTo("#meta-1_geltzeiten-1_geltungszeitgr-4")))));
11181118

11191119
// saved norm is unchanged
11201120
mockMvc

backend/src/test/java/de/bund/digitalservice/ris/norms/utils/NodeCreatorTest.java

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,19 @@ void createElementWithEidAndGuid() {
3737
XmlMapper.toDocument(
3838
"""
3939
<root>
40-
<test eId="test-1">test value</test>
40+
<akn:p eId="text-1">test value</akn:p>
4141
</root>""");
42-
final Node testNode = NodeParser.getMandatoryNodeFromExpression("//test", document);
42+
final Node testNode = NodeParser.getMandatoryNodeFromExpression("//*/p", document);
4343

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

4847
// Then
49-
final Node childTestNode =
50-
NodeParser.getMandatoryNodeFromExpression("//test/childTest", document);
48+
final Node childTestNode = NodeParser.getMandatoryNodeFromExpression("//p/ref", document);
5149
assertThat(childTestNode).isEqualTo(newElement);
5250
assertThat(childTestNode.getAttributes().getNamedItem("GUID")).isNotNull();
5351
assertThat(childTestNode.getAttributes().getNamedItem("eId").getNodeValue())
54-
.isEqualTo("test-1_child-test-1");
52+
.isEqualTo("text-1_ref-1");
5553
}
5654

5755
@Test
@@ -78,22 +76,4 @@ void createElementWithStaticEidAndGuidNoAppend() {
7876
assertThat(newElement.getAttributes().getNamedItem("eId").getNodeValue())
7977
.isEqualTo("test-1_child-test-1");
8078
}
81-
82-
@Test
83-
void calculateNextPossibleEid() {
84-
// given
85-
final Document document =
86-
XmlMapper.toDocument(
87-
"""
88-
<root>
89-
<test eId="test-1">test value</test>
90-
</root>""");
91-
final Node testNode = NodeParser.getMandatoryNodeFromExpression("//test", document);
92-
93-
// when
94-
final String nextPossibleEid = NodeCreator.calculateNextPossibleEid(testNode, "child-test");
95-
96-
// Then
97-
assertThat(nextPossibleEid).isEqualTo("test-1_child-test-1");
98-
}
9979
}

backend/src/test/resources/de/bund/digitalservice/ris/norms/domain/entity/NormWithMods.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,18 @@
145145
refersTo="geltungszeit" start="#meta-1_lebzykl-1_ereignis-2"/>
146146
</akn:temporalGroup>
147147
</akn:temporalData>
148+
<akn:proprietary eId="meta-1_proprietary-1" GUID="fe419055-3201-41b1-b096-402eabcbe6a1"
149+
source="attributsemantik-noch-undefiniert">
150+
<meta:legalDocML.de_metadaten xmlns:meta="http://Metadaten.LegalDocML.de/1.6/">
151+
<meta:typ>gesetz</meta:typ>
152+
<meta:form>mantelform</meta:form>
153+
<meta:fassung>verkuendungsfassung</meta:fassung>
154+
<meta:art>regelungstext</meta:art>
155+
<meta:initiant>bundesregierung</meta:initiant>
156+
<meta:bearbeitendeInstitution>bundesregierung</meta:bearbeitendeInstitution>
157+
<meta:fna>nicht-vorhanden</meta:fna>
158+
</meta:legalDocML.de_metadaten>
159+
</akn:proprietary>
148160

149161
</akn:meta>
150162

backend/src/test/resources/de/bund/digitalservice/ris/norms/domain/entity/NormWithMultipleSimpleMods.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,18 @@
222222
GUID="b5f2b610-ea4e-43dc-9262-8afe1a812000"></akn:timeInterval>
223223
</akn:temporalGroup>
224224
</akn:temporalData>
225+
<akn:proprietary eId="meta-1_proprietary-1" GUID="fe419055-3201-41b1-b096-402eabcbe6a1"
226+
source="attributsemantik-noch-undefiniert">
227+
<meta:legalDocML.de_metadaten xmlns:meta="http://Metadaten.LegalDocML.de/1.6/">
228+
<meta:typ>gesetz</meta:typ>
229+
<meta:form>mantelform</meta:form>
230+
<meta:fassung>verkuendungsfassung</meta:fassung>
231+
<meta:art>regelungstext</meta:art>
232+
<meta:initiant>bundesregierung</meta:initiant>
233+
<meta:bearbeitendeInstitution>bundesregierung</meta:bearbeitendeInstitution>
234+
<meta:fna>nicht-vorhanden</meta:fna>
235+
</meta:legalDocML.de_metadaten>
236+
</akn:proprietary>
225237
</akn:meta>
226238

227239
<akn:preface eId="einleitung-1" GUID="5d844674-c11c-45bf-9bb8-4d54fe108c66">

backend/src/test/resources/de/bund/digitalservice/ris/norms/domain/entity/NormWithMultipleSimpleModsTargetNorm.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@
8989
GUID="f11ec4d9-a419-4288-b47c-0b0341a3cf74"></akn:timeInterval>
9090
</akn:temporalGroup>
9191
</akn:temporalData>
92+
<akn:proprietary eId="meta-1_proprietary-1" GUID="fe419055-3201-41b1-b096-402eabcbe6a1"
93+
source="attributsemantik-noch-undefiniert">
94+
<meta:legalDocML.de_metadaten xmlns:meta="http://Metadaten.LegalDocML.de/1.6/">
95+
<meta:typ>gesetz</meta:typ>
96+
<meta:form>stammform</meta:form>
97+
<meta:fassung>verkuendungsfassung</meta:fassung>
98+
<meta:art>regelungstext</meta:art>
99+
<meta:initiant>bundesregierung</meta:initiant>
100+
<meta:bearbeitendeInstitution>bundesregierung</meta:bearbeitendeInstitution>
101+
<meta:fna>nicht-vorhanden</meta:fna>
102+
</meta:legalDocML.de_metadaten>
103+
</akn:proprietary>
92104
</akn:meta>
93105

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

0 commit comments

Comments
 (0)