Skip to content

Commit 2b5e00b

Browse files
authored
Batch editing - In XPATH replace mode don't try to add a node if doesn't exist (#8350) (#9266)
* Batch editing - In XPATH replace mode don't try to add a node if doesn't exist * Batch editing - In XPATH replace mode don't try to add a node if doesn't exist - Fix unit tests
1 parent 1fe8e98 commit 2b5e00b

2 files changed

Lines changed: 27 additions & 25 deletions

File tree

core/src/main/java/org/fao/geonet/kernel/AddElemValue.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2001-2016 Food and Agriculture Organization of the
2+
* Copyright (C) 2001-2026 Food and Agriculture Organization of the
33
* United Nations (FAO-UN), United Nations World Food Programme (WFP)
44
* and United Nations Environment Programme (UNEP)
55
*
@@ -37,10 +37,12 @@
3737
public class AddElemValue {
3838
private final String stringValue;
3939
private final Element nodeValue;
40+
private final boolean isAddMode;
4041

4142
public AddElemValue(String stringValue) throws JDOMException, IOException {
4243
Element finalNodeVal = null;
4344
String finalStringVal = stringValue.replaceAll("</?gn_(add|replace)>", "");
45+
boolean isAddElement = !stringValue.startsWith("<gn_replace>");
4446
if (Xml.isXMLLike(finalStringVal)) {
4547
try {
4648
finalNodeVal = Xml.loadString(stringValue, false);
@@ -55,11 +57,13 @@ public AddElemValue(String stringValue) throws JDOMException, IOException {
5557
}
5658
this.nodeValue = finalNodeVal;
5759
this.stringValue = finalStringVal;
60+
this.isAddMode = isAddElement;
5861
}
5962

6063
public AddElemValue(Element nodeValue) {
6164
this.nodeValue = nodeValue;
6265
this.stringValue = null;
66+
isAddMode = false;
6367
}
6468

6569
public boolean isXml() {
@@ -73,4 +77,8 @@ public String getStringValue() {
7377
public Element getNodeValue() {
7478
return nodeValue;
7579
}
80+
81+
public boolean isAddMode() {
82+
return isAddMode;
83+
}
7684
}

services/src/main/java/org/fao/geonet/api/records/editing/BatchEditsApi.java

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2001-2016 Food and Agriculture Organization of the
2+
* Copyright (C) 2001-2026 Food and Agriculture Organization of the
33
* United Nations (FAO-UN), United Nations World Food Programme (WFP)
44
* and United Nations Environment Programme (UNEP)
55
*
@@ -37,7 +37,6 @@
3737
import org.fao.geonet.ApplicationContextHolder;
3838
import org.fao.geonet.api.ApiParams;
3939
import org.fao.geonet.api.ApiUtils;
40-
import org.fao.geonet.api.exception.NotAllowedException;
4140
import org.fao.geonet.api.processing.report.IProcessingReport;
4241
import org.fao.geonet.api.processing.report.SimpleMetadataProcessingReport;
4342
import org.fao.geonet.domain.AbstractMetadata;
@@ -110,24 +109,21 @@ public synchronized void setApplicationContext(ApplicationContext context) {
110109
@ResponseStatus(HttpStatus.OK)
111110
@ResponseBody
112111
public Object previewBatchEdit(
113-
@Parameter(description = ApiParams.API_PARAM_RECORD_UUIDS_OR_SELECTION,
114-
required = false)
112+
@Parameter(description = ApiParams.API_PARAM_RECORD_UUIDS_OR_SELECTION)
115113
@RequestParam(required = false) String[] uuids,
116114
@Parameter(
117-
description = ApiParams.API_PARAM_BUCKET_NAME,
118-
required = false)
115+
description = ApiParams.API_PARAM_BUCKET_NAME)
119116
@RequestParam(
120117
required = false
121118
)
122-
String bucket,
119+
String bucket,
123120
@Parameter(
124-
description = "Return differences with diff, diffhtml or patch",
125-
required = false
121+
description = "Return differences with diff, diffhtml or patch"
126122
)
127123
@RequestParam(
128124
required = false
129125
)
130-
DiffType diffType,
126+
DiffType diffType,
131127
@RequestBody BatchEditParameter[] edits,
132128
HttpServletRequest request)
133129
throws Exception {
@@ -153,25 +149,22 @@ public Object previewBatchEdit(
153149
@ResponseStatus(HttpStatus.CREATED)
154150
@ResponseBody
155151
public IProcessingReport batchEdit(
156-
@Parameter(description = ApiParams.API_PARAM_RECORD_UUIDS_OR_SELECTION,
157-
required = false)
152+
@Parameter(description = ApiParams.API_PARAM_RECORD_UUIDS_OR_SELECTION)
158153
@RequestParam(required = false) String[] uuids,
159154
@Parameter(
160-
description = ApiParams.API_PARAM_BUCKET_NAME,
161-
required = false)
155+
description = ApiParams.API_PARAM_BUCKET_NAME)
162156
@RequestParam(
163157
required = false
164158
)
165-
String bucket,
159+
String bucket,
166160
@Parameter(
167-
description = ApiParams.API_PARAM_UPDATE_DATESTAMP,
168-
required = false
161+
description = ApiParams.API_PARAM_UPDATE_DATESTAMP
169162
)
170163
@RequestParam(
171164
required = false,
172165
defaultValue = "false"
173166
)
174-
boolean updateDateStamp,
167+
boolean updateDateStamp,
175168
@RequestBody BatchEditParameter[] edits,
176169
HttpServletRequest request)
177170
throws Exception {
@@ -185,7 +178,7 @@ private Pair<SimpleMetadataProcessingReport, Element> applyBatchEdits(
185178
HttpServletRequest request,
186179
boolean previewOnly, DiffType diffType) throws Exception {
187180
List<BatchEditParameter> listOfUpdates = Arrays.asList(edits);
188-
if (listOfUpdates.size() == 0) {
181+
if (listOfUpdates.isEmpty()) {
189182
throw new IllegalArgumentException("At least one edit must be defined.");
190183
}
191184

@@ -206,17 +199,14 @@ private Pair<SimpleMetadataProcessingReport, Element> applyBatchEdits(
206199
setOfUuidsToEdit = Sets.newHashSet(Arrays.asList(uuids));
207200
}
208201

209-
if (setOfUuidsToEdit.size() == 0) {
202+
if (setOfUuidsToEdit.isEmpty()) {
210203
throw new IllegalArgumentException("At least one record should be defined or selected for updates.");
211204
}
212205

213206
ConfigurableApplicationContext appContext = ApplicationContextHolder.get();
214207
DataManager dataMan = appContext.getBean(DataManager.class);
215208
SchemaManager _schemaManager = context.getBean(SchemaManager.class);
216209
AccessManager accessMan = context.getBean(AccessManager.class);
217-
final String settingId = Settings.SYSTEM_CSW_TRANSACTION_XPATH_UPDATE_CREATE_NEW_ELEMENTS;
218-
boolean createXpathNodeIfNotExists =
219-
context.getBean(SettingManager.class).getValueAsBool(settingId);
220210

221211

222212
SimpleMetadataProcessingReport report = new SimpleMetadataProcessingReport();
@@ -250,11 +240,15 @@ private Pair<SimpleMetadataProcessingReport, Element> applyBatchEdits(
250240
AddElemValue propertyValue =
251241
new AddElemValue(batchEditParameter.getValue());
252242

243+
// This value is used in replace mode to create the node if it doesn't exist.
244+
// We don't want to create a node in replace mode, just replace the element if it exists, otherwise ignore it.
245+
boolean createXpathNodeIfNotExists = propertyValue.isAddMode();
246+
253247
boolean applyEdit = true;
254248
if (StringUtils.isNotEmpty(batchEditParameter.getCondition())) {
255249
applyEdit = false;
256250
final Object node = Xml.selectSingle(metadata, batchEditParameter.getCondition(), metadataSchema.getNamespaces());
257-
if (node != null && node instanceof Boolean && (Boolean)node == true) {
251+
if (node != null && node instanceof Boolean && (Boolean) node == true) {
258252
applyEdit = true;
259253
}
260254
}

0 commit comments

Comments
 (0)