Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions core/src/main/java/org/fao/geonet/kernel/EditLib.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.apache.commons.jxpath.ri.parser.Token;
import org.apache.commons.jxpath.ri.parser.XPathParser;
import org.apache.commons.jxpath.ri.parser.XPathParserConstants;
import org.apache.commons.lang.StringUtils;
import org.fao.geonet.constants.Edit;
import org.fao.geonet.constants.Geonet;
import org.fao.geonet.domain.Pair;
Expand Down Expand Up @@ -583,7 +584,10 @@ public boolean addElementOrFragmentFromXpath(Element metadataRecord,
}
} else if (propNode instanceof Attribute) {
Element parent = ((Attribute) propNode).getParent();
parent.removeAttribute(((Attribute) propNode).getName());
Attribute targetAttribute = (Attribute) propNode;
parent.removeAttribute(
targetAttribute.getName(),
targetAttribute.getNamespace());
}
} else {
// Update element content with node
Expand Down Expand Up @@ -736,6 +740,7 @@ private boolean createAndAddFromXPath(Element metadataRecord, MetadataSchema met
boolean isAttribute = false;
String currentElementName = "";
String currentElementNamespacePrefix = "";
String currentAttributeNamespacePrefix = "";

// Stop when token is null, start of an expression is found ie. "["
//
Expand All @@ -758,10 +763,15 @@ private boolean createAndAddFromXPath(Element metadataRecord, MetadataSchema met
isAttribute = true;
}
// Match namespace prefix
if (currentToken.kind == XPathParserLocalConstants.TEXT && previousToken.kind == XPathParserConstants.SLASH) {
if (currentToken.kind == XPathParserLocalConstants.TEXT &&
previousToken.kind == XPathParserConstants.SLASH) {
// get element namespace if element is text and previous was /
// means qualified name only is supported
currentElementNamespacePrefix = currentToken.image;
} else if (isAttribute &&
previousToken.kind == XPathParserLocalConstants.TEXT &&
currentToken.kind == XPathParserLocalConstants.NAMESPACE_SEP) {
currentAttributeNamespacePrefix = previousToken.image;
} else if (currentToken.kind == XPathParserLocalConstants.TEXT &&
previousToken.kind == XPathParserLocalConstants.NAMESPACE_SEP) {
// get element name if element is text and previous was /
Expand All @@ -788,7 +798,9 @@ private boolean createAndAddFromXPath(Element metadataRecord, MetadataSchema met
} else {
LOGGER_ADD_ELEMENT.debug(" > add new node {} inserted in {}", qualifiedName, currentNode.getName());

if (metadataSchema.getElementValues(qualifiedName, currentNode.getQualifiedName()) != null) {
if (isAttribute) {
existingElement = false; // Attribute is created and set after.
} else if (metadataSchema.getElementValues(qualifiedName, currentNode.getQualifiedName()) != null) {
currentNode = addElement(metadataSchema, currentNode, qualifiedName);
existingElement = false;
} else {
Expand Down Expand Up @@ -833,7 +845,15 @@ private boolean createAndAddFromXPath(Element metadataRecord, MetadataSchema met
doAddFragmentFromXpath(metadataSchema, value.getNodeValue(), currentNode);
} else {
if (isAttribute) {
currentNode.setAttribute(previousToken.image, value.getStringValue());
if (StringUtils.isNotEmpty(currentAttributeNamespacePrefix)) {
currentNode.setAttribute(previousToken.image,
value.getStringValue(),
Namespace.getNamespace(currentAttributeNamespacePrefix,
metadataSchema.getNS(currentAttributeNamespacePrefix)));
} else {
currentNode.setAttribute(previousToken.image, value.getStringValue());
}

} else {
currentNode.setText(value.getStringValue());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.fao.geonet.domain.AbstractMetadata;
import org.fao.geonet.kernel.datamanager.IMetadataUtils;
import org.fao.geonet.kernel.mef.MEFLibIntegrationTest;
import org.fao.geonet.schema.iso19115_3_2018.ISO19115_3_2018Namespaces;
import org.fao.geonet.services.AbstractServiceIntegrationTest;
import org.jdom.Attribute;
import org.jdom.Element;
Expand Down Expand Up @@ -322,6 +323,66 @@ public void testUpdateRecordAddAttribute() throws Exception {
Assert.assertEquals("value", ((Element) scope.get(0)).getAttributeValue("newAttribute"));
}

@Test
public void testUpdateRecordAddAndDeleteAttributeWithNamespace() throws Exception {
final String uuid = "db07463b-6769-401e-944b-f22e2e3bcc26";
BatchEditParameter[] listOfupdates = new BatchEditParameter[]{
new BatchEditParameter(
"/mdb:MD_Metadata/mdb:metadataScope/@gco:nilReason",
"<gn_add>withheld</gn_add>"
)
};

this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
this.mockHttpSession = loginAsAdmin();

Gson gson = new GsonBuilder()
.create();
JsonElement jsonEl = gson.toJsonTree(listOfupdates);

this.mockMvc.perform(put("/srv/api/records/batchediting?uuids=" + uuid)
.content(jsonEl.toString())
.contentType(MediaType.APPLICATION_JSON)
.session(this.mockHttpSession)
.accept(MediaType.parseMediaType("application/json")))
.andExpect(status().is(201));

AbstractMetadata updatedRecord = repository.findOneByUuid(uuid);
Element xml = Xml.loadString(updatedRecord.getData(), false);

List scope = org.fao.geonet.utils.Xml.selectNodes(xml,
"./mdb:metadataScope",
xml.getAdditionalNamespaces());
Assert.assertEquals("withheld", ((Element) scope.get(0)).getAttributeValue("nilReason", ISO19115_3_2018Namespaces.GCO));


listOfupdates = new BatchEditParameter[]{
new BatchEditParameter(
"/mdb:MD_Metadata/mdb:metadataScope/@gco:nilReason",
"<gn_delete/>"
)
};

jsonEl = gson.toJsonTree(listOfupdates);

this.mockMvc.perform(put("/srv/api/records/batchediting?uuids=" + uuid)
.content(jsonEl.toString())
.contentType(MediaType.APPLICATION_JSON)
.session(this.mockHttpSession)
.accept(MediaType.parseMediaType("application/json")))
.andExpect(status().is(201));

updatedRecord = repository.findOneByUuid(uuid);
xml = Xml.loadString(updatedRecord.getData(), false);

scope = org.fao.geonet.utils.Xml.selectNodes(xml,
"./mdb:metadataScope/gco:nilReason",
xml.getAdditionalNamespaces());
Assert.assertEquals(0, scope.size());

}


@Test
public void testUpdateRecordElement() throws Exception {
final String uuid = "db07463b-6769-401e-944b-f22e2e3bcc26";
Expand Down