Map<String, String> changes, String currVersion) throws Exception {
Lib.resource.checkEditPrivilege(context, id);
String schema = dataManager.getMetadataSchema(id);
MetadataSchema metadataSchema = dataManager.getSchema(schema);
EditLib editLib = dataManager.getEditLib();
// --- check if the metadata has been modified from last time
if (currVersion != null && !editLib.getVersion(id).equals(currVersion)) {
Log.error(Geonet.EDITOR, "Version mismatch: had " + currVersion +
" but expected " + editLib.getVersion(id));
return null;
}
// --- get metadata from session
Element md = getMetadataFromSession(session, id);
// Store XML fragments to be handled after other elements update
Map<String, String> xmlInputs = new HashMap<String, String>();
Map<String, AddElemValue> xmlAndXpathInputs = new HashMap<String, AddElemValue>();
// --- update elements
for (Map.Entry<String, String> entry : changes.entrySet()) {
String ref = entry.getKey().trim();
String value = entry.getValue().trim();
String attribute = null;
// Avoid empty key
if (ref.equals("")) {
continue;
}
// Catch element starting with a X to replace XML fragments
if (ref.startsWith("X")) {
ref = ref.substring(1);
xmlInputs.put(ref, value);
continue;
} else if (ref.startsWith("P") && ref.endsWith("_xml")) {
continue;
} else if (ref.startsWith("P") && !ref.endsWith("_xml")) {
// Catch element starting with a P for xpath update mode
String snippet = changes.get(ref + "_xml");
if(Log.isDebugEnabled(Geonet.EDITOR)) {
Log.debug(Geonet.EDITOR, "Add element by XPath: " + value);
Log.debug(Geonet.EDITOR, " Snippet is : " + snippet);
}
if (snippet != null && !"".equals(snippet)) {
xmlAndXpathInputs.put(value, new AddElemValue(snippet));
} else {
Log.warning(Geonet.EDITOR, "No XML snippet or value found for xpath " + value + " and element ref " + ref);
}
continue;
}
if (updatedLocalizedTextElement(md, schema, ref, value, editLib)) {
continue;
}
int at = ref.indexOf('_');
if (at != -1) {
attribute = ref.substring(at + 1);
ref = ref.substring(0, at);
}
Element el = editLib.findElement(md, ref);
if (el == null) {
Log.error(Geonet.EDITOR, EditLib.MSG_ELEMENT_NOT_FOUND_AT_REF + ref);
continue;
}
// Process attribute
if (attribute != null) {
Pair<Namespace, String> attInfo = parseAttributeName(attribute, EditLib.COLON_SEPARATOR, id, md, editLib);
String localname = attInfo.two();
Namespace attrNS = attInfo.one();
if (el.getAttribute(localname, attrNS) != null) {
el.setAttribute(new Attribute(localname, value, attrNS));
}
} else {
// Process element value
@SuppressWarnings("unchecked")
List<Content> content = el.getContent();
for (Iterator<Content> iterator = content.iterator(); iterator.hasNext();) {
Content content2 = iterator.next();
if (content2 instanceof Text) {
iterator.remove();
}
}
el.addContent(value);
}
}
// Deals with XML fragments to insert or update
if (!xmlInputs.isEmpty()) {
editLib.addXMLFragments(schema, md, xmlInputs);
}
// Deals with XML fragments and XPath to insert or update
if (!xmlAndXpathInputs.isEmpty()) {
editLib.addElementOrFragmentFromXpaths(md, xmlAndXpathInputs, metadataSchema, true);
}
setMetadataIntoSession(session,(Element)md.clone(), id);
// --- remove editing info
editLib.removeEditingInfo(md);
editLib.contractElements(md);
return (Element) md.detach();
}