// Creating the element at the xpath location
// Walk the XPath from the start until the end or the start of a filter
// expression.
// Collect element namespace prefix and name, check element exist and
// create them according to schema definition.
final XPathParser xpathParser = new XPathParser(new StringReader(clonedMetadata.getQualifiedName()+"/"+result.two()));
// Start from the root of the metadata document
Token currentToken = xpathParser.getNextToken();
Token previousToken = currentToken;
int depth = 0;
Element currentNode = clonedMetadata;
boolean existingElement = true;
boolean isAttribute = false;
String currentElementName = "";
String currentElementNamespacePrefix = "";
// Stop when token is null, start of an expression is found ie. "["
//
// Stop when an expression [ starts
// The expression is supposed to be part of the XML snippet to insert
// If an existing element needs to be updated use the _Xref_replace mode
// this mode is more precise with the geonet:element/@ref.
while (currentToken != null &&
currentToken.kind != 0 &&
currentToken.kind != XPathParserLocalConstants.SQBRACKET_OPEN) {
// TODO : check no .., descendant, ... are in the xpath
// Only full xpath are supported.
if (XPathParserLocalConstants.ILLEGAL_KINDS.contains(currentToken.kind)) {
return false;
}
// build element name as the parser progress into the xpath ...
if (currentToken.kind == XPathParserLocalConstants.ATTRIBUTE ) {
isAttribute = true;
}
// Match namespace prefix
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 (currentToken.kind == XPathParserLocalConstants.TEXT &&
previousToken.kind == XPathParserLocalConstants.NAMESPACE_SEP) {
// get element name if element is text and previous was /
currentElementName = currentToken.image;
// Do not change anything to the root of the
// metadata record which MUST be the root of
// the xpath
if (depth > 0) {
// If an element name is created
// Check the element exist in the metadata
// and create it if needed.
String qualifiedName = currentElementNamespacePrefix + ":" + currentElementName;
if(Log.isDebugEnabled(Geonet.EDITORADDELEMENT)) {
Log.debug(Geonet.EDITORADDELEMENT,
"Check if " + qualifiedName + " exists in " + currentNode.getName());
}
Element nodeToCheck = currentNode.getChild(currentElementName,
Namespace.getNamespace(metadataSchema.getNS(currentElementNamespacePrefix)));
if (nodeToCheck != null) {
if(Log.isDebugEnabled(Geonet.EDITORADDELEMENT)) {
Log.debug(Geonet.EDITORADDELEMENT, " > " + qualifiedName + " found");
}
// Element found, no need to create it, continue walking the xpath.
currentNode = nodeToCheck;
existingElement &= true;
} else {
if(Log.isDebugEnabled(Geonet.EDITORADDELEMENT)) {
Log.debug(Geonet.EDITORADDELEMENT, " > add new node " +
qualifiedName + " inserted in " + currentNode.getName());
}
if (metadataSchema.getElementValues(qualifiedName, currentNode.getQualifiedName()) != null) {
currentNode = addElement(metadataSchema, currentNode, qualifiedName);
existingElement = false;
} else {
// element not in schema so stop!
return false;
}
}
}
depth ++;
// Reset current element props
currentElementName = "";
currentElementNamespacePrefix = "";
}
previousToken = currentToken;
currentToken = xpathParser.getNextToken();
}
// The current node is an existing node or newly created one
// Insert the XML value
// TODO: deal with attribute ?