use of org.exist.dom.persistent.ElementImpl in project exist by eXist-db.
the class FunInScopePrefixes method collectNamespacePrefixes.
public static void collectNamespacePrefixes(final Element element, final Map<String, String> prefixes) {
final String namespaceURI = element.getNamespaceURI();
if (namespaceURI != null && !namespaceURI.isEmpty()) {
final String prefix = element.getPrefix();
prefixes.put(prefix == null ? XMLConstants.DEFAULT_NS_PREFIX : prefix, namespaceURI);
}
if (element instanceof org.exist.dom.memtree.ElementImpl) {
((org.exist.dom.memtree.ElementImpl) element).getNamespaceMap(prefixes);
} else {
final ElementImpl elementImpl = (org.exist.dom.persistent.ElementImpl) element;
if (elementImpl.declaresNamespacePrefixes()) {
for (final Iterator<String> i = elementImpl.getPrefixes(); i.hasNext(); ) {
final String prefix = i.next();
prefixes.put(prefix, elementImpl.getNamespaceForPrefix(prefix));
}
}
}
if (namespaceURI != null && namespaceURI.isEmpty()) {
final String prefix = element.getPrefix();
prefixes.remove(prefix == null ? XMLConstants.DEFAULT_NS_PREFIX : prefix);
}
}
use of org.exist.dom.persistent.ElementImpl in project exist by eXist-db.
the class Indexer method comment.
@Override
public void comment(final char[] ch, final int start, final int length) {
if (insideDTD) {
return;
}
final CommentImpl comment = new CommentImpl(ch, start, length);
comment.setOwnerDocument(document);
if (stack.isEmpty()) {
comment.setNodeId(broker.getBrokerPool().getNodeFactory().createInstance(nodeFactoryInstanceCnt++));
if (!validate) {
broker.storeNode(transaction, comment, currentPath, indexSpec);
}
document.appendChild((NodeHandle) comment);
} else {
final ElementImpl last = stack.peek();
processText(last, ProcessTextParent.COMMENT);
last.appendChildInternal(prevNode, comment);
setPrevious(comment);
if (!validate) {
broker.storeNode(transaction, comment, currentPath, indexSpec);
}
}
}
use of org.exist.dom.persistent.ElementImpl in project exist by eXist-db.
the class Indexer method processingInstruction.
@Override
public void processingInstruction(final String target, final String data) {
final ProcessingInstructionImpl pi = new ProcessingInstructionImpl(target, data);
pi.setOwnerDocument(document);
if (stack.isEmpty()) {
pi.setNodeId(broker.getBrokerPool().getNodeFactory().createInstance(nodeFactoryInstanceCnt++));
if (!validate)
broker.storeNode(transaction, pi, currentPath, indexSpec);
document.appendChild((NodeHandle) pi);
} else {
final ElementImpl last = stack.peek();
processText(last, ProcessTextParent.PI);
last.appendChildInternal(prevNode, pi);
setPrevious(pi);
if (!validate)
broker.storeNode(transaction, pi, currentPath, indexSpec);
}
}
use of org.exist.dom.persistent.ElementImpl in project exist by eXist-db.
the class Indexer method startElement.
@Override
public void startElement(final String namespace, final String name, final String qname, final Attributes attributes) throws SAXException {
// calculate number of real attributes:
// don't store namespace declarations
int attrLength = attributes.getLength();
for (int i = 0; i < attributes.getLength(); i++) {
final String attrNS = attributes.getURI(i);
final String attrQName = attributes.getQName(i);
if (attrQName.startsWith("xmlns") || attrNS.equals(Namespaces.EXIST_NS)) {
--attrLength;
}
}
ElementImpl node;
int p = qname.indexOf(':');
final String prefix = (p != Constants.STRING_NOT_FOUND) ? qname.substring(0, p) : "";
final QName qn = broker.getBrokerPool().getSymbols().getQName(Node.ELEMENT_NODE, namespace, name, prefix);
if (!stack.isEmpty()) {
final ElementImpl last = stack.peek();
processText(last, ProcessTextParent.ELEMENT_START);
try {
if (!usedElements.isEmpty()) {
node = usedElements.pop();
node.setNodeName(qn, broker.getBrokerPool().getSymbols());
} else {
node = new ElementImpl(qn, broker.getBrokerPool().getSymbols());
}
} catch (final DOMException e) {
throw new SAXException(e.getMessage(), e);
}
// copy xml:space setting
node.setPreserveSpace(last.preserveSpace());
// append the node to its parent
// (computes the node id and updates the parent's child count)
last.appendChildInternal(prevNode, node);
setPrevious(null);
node.setOwnerDocument(document);
node.setAttributes((short) attrLength);
if (nsMappings != null && nsMappings.size() > 0) {
node.setNamespaceMappings(nsMappings);
nsMappings.clear();
}
stack.push(node);
currentPath.addNode(node, attributes);
node.setPosition(elementCnt++);
if (!validate) {
if (childCnt != null) {
node.setChildCount(childCnt[node.getPosition()]);
}
storeElement(node);
}
} else {
try {
node = new ElementImpl(qn, broker.getBrokerPool().getSymbols());
} catch (final DOMException e) {
throw new SAXException(e.getMessage(), e);
}
rootNode = node;
setPrevious(null);
node.setOwnerDocument(document);
node.setNodeId(broker.getBrokerPool().getNodeFactory().createInstance(nodeFactoryInstanceCnt++));
node.setAttributes((short) attrLength);
if (nsMappings != null && nsMappings.size() > 0) {
node.setNamespaceMappings(nsMappings);
nsMappings.clear();
}
stack.push(node);
currentPath.addNode(node, attributes);
node.setPosition(elementCnt++);
if (!validate) {
if (childCnt != null) {
node.setChildCount(childCnt[node.getPosition()]);
}
storeElement(node);
}
document.appendChild((NodeHandle) node);
}
level++;
for (int i = 0; i < attributes.getLength(); i++) {
final String attrNS = attributes.getURI(i);
final String attrLocalName = attributes.getLocalName(i);
final String attrQName = attributes.getQName(i);
// skip xmlns-attributes and attributes in eXist's namespace
if (attrQName.startsWith("xmlns") || attrNS.equals(Namespaces.EXIST_NS)) {
--attrLength;
} else {
p = attrQName.indexOf(':');
final String attrPrefix = (p != Constants.STRING_NOT_FOUND) ? attrQName.substring(0, p) : null;
final AttrImpl attr = (AttrImpl) NodePool.getInstance().borrowNode(Node.ATTRIBUTE_NODE);
final QName attrQN = broker.getBrokerPool().getSymbols().getQName(Node.ATTRIBUTE_NODE, attrNS, attrLocalName, attrPrefix);
try {
attr.setNodeName(attrQN, broker.getBrokerPool().getSymbols());
} catch (final DOMException e) {
throw new SAXException(e.getMessage(), e);
}
attr.setValue(attributes.getValue(i));
attr.setOwnerDocument(document);
if (attributes.getType(i).equals(ATTR_ID_TYPE)) {
attr.setType(AttrImpl.ID);
} else if (attributes.getType(i).equals(ATTR_IDREF_TYPE)) {
attr.setType(AttrImpl.IDREF);
} else if (attributes.getType(i).equals(ATTR_IDREFS_TYPE)) {
attr.setType(AttrImpl.IDREFS);
} else if (attr.getQName().equals(Namespaces.XML_ID_QNAME)) {
// an xml:id attribute. Normalize the attribute and set its
// type to ID
attr.setValue(StringValue.trimWhitespace(StringValue.collapseWhitespace(attr.getValue())));
attr.setType(AttrImpl.ID);
} else if (attr.getQName().equals(Namespaces.XML_SPACE_QNAME)) {
node.setPreserveSpace("preserve".equals(attr.getValue()));
}
node.appendChildInternal(prevNode, attr);
setPrevious(attr);
if (!validate) {
broker.storeNode(transaction, attr, currentPath, indexSpec);
if (indexListener != null) {
indexListener.attribute(transaction, attr, currentPath);
}
}
}
}
if (attrLength > 0) {
node.setAttributes((short) attrLength);
}
// notify observers about progress every 100 lines
if (locator != null) {
currentLine = locator.getLineNumber();
if (!validate) {
progress.setValue(currentLine);
}
}
docSize++;
}
use of org.exist.dom.persistent.ElementImpl in project exist by eXist-db.
the class Replace method eval.
/* (non-Javadoc)
* @see org.exist.xquery.AbstractExpression#eval(org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
*/
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
if (context.getProfiler().isEnabled()) {
context.getProfiler().start(this);
context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
if (contextSequence != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
}
if (contextItem != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
}
}
if (contextItem != null) {
contextSequence = contextItem.toSequence();
}
final Sequence inSeq = select.eval(contextSequence);
if (inSeq.isEmpty()) {
return Sequence.EMPTY_SEQUENCE;
}
/* If we try and Replace a node at an invalid location,
* trap the error in a context variable,
* this is then accessible from xquery via. the context extension module - deliriumsky
* TODO: This trapping could be expanded further - basically where XPathException is thrown from thiss class
* TODO: Maybe we could provide more detailed messages in the trap, e.g. couldnt replace node `xyz` into `abc` becuase... this would be nicer for the end user of the xquery application
*/
if (!Type.subTypeOf(inSeq.getItemType(), Type.NODE)) {
// Indicate the failure to perform this update by adding it to the sequence in the context variable XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR
ValueSequence prevUpdateErrors = null;
final XPathException xpe = new XPathException(this, Messages.getMessage(Error.UPDATE_SELECT_TYPE));
final Object ctxVarObj = context.getAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR);
if (ctxVarObj == null) {
prevUpdateErrors = new ValueSequence();
} else {
prevUpdateErrors = (ValueSequence) XPathUtil.javaObjectToXPath(ctxVarObj, context);
}
prevUpdateErrors.add(new StringValue(xpe.getMessage()));
context.setAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR, prevUpdateErrors);
if (!inSeq.isEmpty()) {
// TODO: should we trap this instead of throwing an exception - deliriumsky?
throw xpe;
}
}
// END trap Replace failure
Sequence contentSeq = value.eval(contextSequence);
if (contentSeq.isEmpty()) {
throw new XPathException(this, Messages.getMessage(Error.UPDATE_EMPTY_CONTENT));
}
context.pushInScopeNamespaces();
contentSeq = deepCopy(contentSeq);
// start a transaction
try (final Txn transaction = getTransaction()) {
final StoredNode[] ql = selectAndLock(transaction, inSeq);
final NotificationService notifier = context.getBroker().getBrokerPool().getNotificationService();
Item temp;
TextImpl text;
AttrImpl attribute;
ElementImpl parent;
for (final StoredNode node : ql) {
final DocumentImpl doc = node.getOwnerDocument();
if (!doc.getPermissions().validate(context.getSubject(), Permission.WRITE)) {
throw new PermissionDeniedException("User '" + context.getSubject().getName() + "' does not have permission to write to the document '" + doc.getDocumentURI() + "'!");
}
// update the document
parent = (ElementImpl) node.getParentStoredNode();
if (parent == null) {
throw new XPathException(this, "The root element of a document can not be replaced with 'update replace'. " + "Please consider removing the document or use 'update value' to just replace the children of the root.");
}
switch(node.getNodeType()) {
case Node.ELEMENT_NODE:
temp = contentSeq.itemAt(0);
if (!Type.subTypeOf(temp.getType(), Type.NODE)) {
throw new XPathException(this, Messages.getMessage(Error.UPDATE_REPLACE_ELEM_TYPE, Type.getTypeName(temp.getType())));
}
parent.replaceChild(transaction, ((NodeValue) temp).getNode(), node);
break;
case Node.TEXT_NODE:
text = new TextImpl(contentSeq.getStringValue());
text.setOwnerDocument(doc);
parent.updateChild(transaction, node, text);
break;
case Node.ATTRIBUTE_NODE:
final AttrImpl attr = (AttrImpl) node;
attribute = new AttrImpl(attr.getQName(), contentSeq.getStringValue(), context.getBroker().getBrokerPool().getSymbols());
attribute.setOwnerDocument(doc);
parent.updateChild(transaction, node, attribute);
break;
default:
throw new EXistException("unsupported node-type");
}
doc.setLastModified(System.currentTimeMillis());
modifiedDocuments.add(doc);
context.getBroker().storeXMLResource(transaction, doc);
notifier.notifyUpdate(doc, UpdateListener.UPDATE);
}
finishTriggers(transaction);
// commit the transaction
transaction.commit();
} catch (final LockException | PermissionDeniedException | EXistException | TriggerException e) {
throw new XPathException(this, e.getMessage(), e);
} finally {
unlockDocuments();
context.popInScopeNamespaces();
}
if (context.getProfiler().isEnabled()) {
context.getProfiler().end(this, "", Sequence.EMPTY_SEQUENCE);
}
return Sequence.EMPTY_SEQUENCE;
}
Aggregations