use of org.exist.indexing.IndexController in project exist by eXist-db.
the class ElementImpl method setAttributeNode.
private Attr setAttributeNode(final Attr newAttr, final Function<QName, Attr> getFn) {
final QName attrName = new QName(newAttr.getLocalName(), newAttr.getNamespaceURI(), newAttr.getPrefix(), ElementValue.ATTRIBUTE);
final Attr existingAttr = getFn.apply(attrName);
if (existingAttr != null) {
if (existingAttr.equals(newAttr)) {
return newAttr;
}
// update an existing attribute
existingAttr.setValue(newAttr.getValue());
try (final DBBroker broker = ownerDocument.getBrokerPool().getBroker();
final Txn transaction = broker.getBrokerPool().getTransactionManager().beginTransaction()) {
if (!(existingAttr instanceof IStoredNode)) {
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, "Wrong node type");
}
final IStoredNode<?> existing = (IStoredNode<?>) existingAttr;
if (!existing.getNodeId().isChildOf(nodeId)) {
throw new DOMException(DOMException.NOT_FOUND_ERR, "node " + existing.getNodeId().getParentId() + " is not a child of element " + nodeId);
}
// update old custom indexes
final IndexController indexes = broker.getIndexController();
indexes.reindex(transaction, existing, ReindexMode.STORE);
broker.updateNode(transaction, existing, true);
transaction.commit();
} catch (final EXistException e) {
LOG.error(e);
throw new DOMException(DOMException.INVALID_ACCESS_ERR, e.getMessage());
}
return existingAttr;
} else {
try (final DBBroker broker = ownerDocument.getBrokerPool().getBroker()) {
final AttrImpl attrib = new AttrImpl(attrName, newAttr.getValue(), broker.getBrokerPool().getSymbols());
return (Attr) appendChild(attrib);
} catch (final EXistException e) {
LOG.error(e);
throw new DOMException(DOMException.INVALID_ACCESS_ERR, e.getMessage());
}
}
}
use of org.exist.indexing.IndexController in project exist by eXist-db.
the class ElementImpl method appendChild.
private Node appendChild(final Txn transaction, final NodeId newNodeId, final NodeImplRef last, final NodePath lastPath, final Node child, final StreamListener listener) throws DOMException {
if (last == null || last.getNode() == null) {
throw new DOMException(DOMException.INVALID_MODIFICATION_ERR, "invalid node");
}
final DocumentImpl owner = getOwnerDocument();
try (final DBBroker broker = ownerDocument.getBrokerPool().getBroker()) {
switch(child.getNodeType()) {
case Node.DOCUMENT_FRAGMENT_NODE:
appendChildren(transaction, newNodeId, null, last, lastPath, child.getChildNodes(), listener);
// TODO: implement document fragments so
return null;
case Node.ELEMENT_NODE:
// create new element
final ElementImpl elem = new ElementImpl(new QName(child.getLocalName() == null ? child.getNodeName() : child.getLocalName(), child.getNamespaceURI(), child.getPrefix()), broker.getBrokerPool().getSymbols());
elem.setNodeId(newNodeId);
elem.setOwnerDocument(owner);
final org.exist.dom.NodeListImpl ch = new org.exist.dom.NodeListImpl();
final NamedNodeMap attribs = child.getAttributes();
int numActualAttribs = 0;
for (int i = 0; i < attribs.getLength(); i++) {
final Attr attr = (Attr) attribs.item(i);
if (!attr.getNodeName().startsWith(XMLConstants.XMLNS_ATTRIBUTE)) {
ch.add(attr);
numActualAttribs++;
} else {
final String xmlnsDecl = attr.getNodeName();
final String prefix = xmlnsDecl.length() == 5 ? XMLConstants.DEFAULT_NS_PREFIX : xmlnsDecl.substring(6);
elem.addNamespaceMapping(prefix, attr.getNodeValue());
}
}
final NodeList cl = child.getChildNodes();
for (int i = 0; i < cl.getLength(); i++) {
final Node n = cl.item(i);
ch.add(n);
}
elem.setChildCount(ch.getLength());
if (numActualAttribs != (short) numActualAttribs) {
throw new DOMException(DOMException.INVALID_MODIFICATION_ERR, "Too many attributes");
}
elem.setAttributes((short) numActualAttribs);
lastPath.addComponent(elem.getQName());
// insert the node
broker.insertNodeAfter(transaction, last.getNode(), elem);
broker.indexNode(transaction, elem, lastPath);
final IndexController indexes = broker.getIndexController();
indexes.startIndexDocument(transaction, listener);
try {
indexes.indexNode(transaction, elem, lastPath, listener);
elem.setChildCount(0);
last.setNode(elem);
// process child nodes
elem.appendChildren(transaction, newNodeId.newChild(), null, last, lastPath, ch, listener);
broker.endElement(elem, lastPath, null);
indexes.endElement(transaction, elem, lastPath, listener);
} finally {
indexes.endIndexDocument(transaction, listener);
}
lastPath.removeLastComponent();
return elem;
case Node.TEXT_NODE:
final TextImpl text = new TextImpl(newNodeId, ((Text) child).getData());
text.setOwnerDocument(owner);
// insert the node
broker.insertNodeAfter(transaction, last.getNode(), text);
broker.indexNode(transaction, text, lastPath);
broker.getIndexController().indexNode(transaction, text, lastPath, listener);
last.setNode(text);
return text;
case Node.CDATA_SECTION_NODE:
final CDATASectionImpl cdata = new CDATASectionImpl(newNodeId, ((CDATASection) child).getData());
cdata.setOwnerDocument(owner);
// insert the node
broker.insertNodeAfter(transaction, last.getNode(), cdata);
broker.indexNode(transaction, cdata, lastPath);
last.setNode(cdata);
return cdata;
case Node.ATTRIBUTE_NODE:
final Attr attr = (Attr) child;
final String ns = attr.getNamespaceURI();
final String prefix = (Namespaces.XML_NS.equals(ns) ? XMLConstants.XML_NS_PREFIX : attr.getPrefix());
String name = attr.getLocalName();
if (name == null) {
name = attr.getName();
}
final QName attrName = new QName(name, ns, prefix);
final AttrImpl attrib = new AttrImpl(attrName, attr.getValue(), broker.getBrokerPool().getSymbols());
attrib.setNodeId(newNodeId);
attrib.setOwnerDocument(owner);
if (ns != null && attrName.compareTo(Namespaces.XML_ID_QNAME) == Constants.EQUAL) {
// an xml:id attribute. Normalize the attribute and set its type to ID
attrib.setValue(StringValue.trimWhitespace(StringValue.collapseWhitespace(attrib.getValue())));
attrib.setType(AttrImpl.ID);
} else {
attrib.setQName(new QName(attrib.getQName(), ElementValue.ATTRIBUTE));
}
broker.insertNodeAfter(transaction, last.getNode(), attrib);
broker.indexNode(transaction, attrib, lastPath);
broker.getIndexController().indexNode(transaction, attrib, lastPath, listener);
last.setNode(attrib);
return attrib;
case Node.COMMENT_NODE:
final CommentImpl comment = new CommentImpl(((Comment) child).getData());
comment.setNodeId(newNodeId);
comment.setOwnerDocument(owner);
// insert the node
broker.insertNodeAfter(transaction, last.getNode(), comment);
broker.indexNode(transaction, comment, lastPath);
last.setNode(comment);
return comment;
case Node.PROCESSING_INSTRUCTION_NODE:
final ProcessingInstructionImpl pi = new ProcessingInstructionImpl(newNodeId, ((ProcessingInstruction) child).getTarget(), ((ProcessingInstruction) child).getData());
pi.setOwnerDocument(owner);
// insert the node
broker.insertNodeAfter(transaction, last.getNode(), pi);
broker.indexNode(transaction, pi, lastPath);
last.setNode(pi);
return pi;
default:
throw new DOMException(DOMException.INVALID_MODIFICATION_ERR, "Unknown node type: " + child.getNodeType() + " " + child.getNodeName());
}
} catch (final EXistException e) {
LOG.warn("Exception while appending node: {}", e.getMessage(), e);
}
return null;
}
use of org.exist.indexing.IndexController in project exist by eXist-db.
the class ElementImpl method appendChildren.
@Override
public void appendChildren(final Txn transaction, NodeList nodes, final int child) throws DOMException {
// attributes are handled differently. Call checkForAttributes to extract them.
nodes = checkForAttributes(transaction, nodes);
if (nodes == null || nodes.getLength() == 0) {
return;
}
try (final DBBroker broker = ownerDocument.getBrokerPool().getBroker()) {
final NodePath path = getPath();
StreamListener listener = null;
final IndexController indexes = broker.getIndexController();
// May help getReindexRoot() to make some useful things
indexes.setDocument(ownerDocument);
final IStoredNode reindexRoot = indexes.getReindexRoot(this, path, true, true);
indexes.setMode(ReindexMode.STORE);
// only reindex if reindexRoot is an ancestor of the current node
if (reindexRoot == null) {
listener = indexes.getStreamListener();
}
if (children == 0) {
// no children: append a new child
appendChildren(transaction, nodeId.newChild(), null, new NodeImplRef(this), path, nodes, listener);
} else {
if (child == 1) {
final Node firstChild = getFirstChild();
insertBefore(transaction, nodes, firstChild);
} else {
if (child > 1 && child <= children) {
final NodeList cl = getAttrsAndChildNodes();
final IStoredNode<?> last = (IStoredNode<?>) cl.item(child - 2);
insertAfter(transaction, nodes, last);
} else {
final IStoredNode<?> last = (IStoredNode<?>) getLastChild(true);
appendChildren(transaction, last.getNodeId().nextSibling(), null, new NodeImplRef(getLastNode(last)), path, nodes, listener);
}
}
}
broker.updateNode(transaction, this, false);
indexes.reindex(transaction, reindexRoot, ReindexMode.STORE);
broker.flush();
} catch (final EXistException e) {
LOG.warn("Exception while appending child node: {}", e.getMessage(), e);
}
}
use of org.exist.indexing.IndexController in project exist by eXist-db.
the class ElementImpl method replaceChild.
/**
* Replaces the oldNode with the newChild
*
* @param transaction the transaction
* @param newChild to replace oldChild
* @param oldChild to be replace by newChild
* @return The new node (this differs from the {@link org.w3c.dom.Node#replaceChild(Node, Node)} specification)
* @throws DOMException in case of a DOM error
* @see org.w3c.dom.Node#replaceChild(org.w3c.dom.Node, org.w3c.dom.Node)
*/
@Override
public Node replaceChild(final Txn transaction, final Node newChild, final Node oldChild) throws DOMException {
if (!(oldChild instanceof IStoredNode)) {
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, "Wrong node type");
}
final IStoredNode<?> oldNode = (IStoredNode<?>) oldChild;
if (!oldNode.getNodeId().getParentId().equals(nodeId)) {
throw new DOMException(DOMException.NOT_FOUND_ERR, "Node is not a child of this element");
}
final NodePath thisPath = getPath();
IStoredNode<?> previous = (IStoredNode<?>) oldNode.getPreviousSibling();
if (previous == null) {
previous = this;
} else {
previous = getLastNode(previous);
}
final NodePath oldPath = oldNode.getPath();
StreamListener listener = null;
Node newNode = null;
try (final DBBroker broker = ownerDocument.getBrokerPool().getBroker()) {
final IndexController indexes = broker.getIndexController();
// May help getReindexRoot() to make some useful things
indexes.setDocument(ownerDocument);
final IStoredNode reindexRoot = broker.getIndexController().getReindexRoot(oldNode, oldPath, false);
indexes.setMode(ReindexMode.REMOVE_SOME_NODES);
if (reindexRoot == null) {
listener = indexes.getStreamListener();
} else {
indexes.reindex(transaction, reindexRoot, ReindexMode.REMOVE_SOME_NODES);
}
broker.removeAllNodes(transaction, oldNode, oldPath, listener);
broker.endRemove(transaction);
broker.flush();
indexes.setMode(ReindexMode.STORE);
listener = indexes.getStreamListener();
newNode = appendChild(transaction, oldNode.getNodeId(), new NodeImplRef(previous), thisPath, newChild, listener);
// Reindex if required
broker.storeXMLResource(transaction, getOwnerDocument());
broker.updateNode(transaction, this, false);
indexes.reindex(transaction, reindexRoot, ReindexMode.STORE);
broker.flush();
} catch (final EXistException e) {
LOG.warn("Exception while inserting node: {}", e.getMessage(), e);
}
// returning the newNode is more sensible than returning the oldNode
return newNode;
}
use of org.exist.indexing.IndexController in project exist by eXist-db.
the class ElementImpl method setAttribute.
private void setAttribute(final QName attrName, final String value, final Function<QName, Attr> getFn) {
final Attr existingAttr = getFn.apply(attrName);
if (existingAttr != null) {
// update an existing attribute
existingAttr.setValue(value);
try (final DBBroker broker = ownerDocument.getBrokerPool().getBroker();
final Txn transaction = broker.getBrokerPool().getTransactionManager().beginTransaction()) {
if (!(existingAttr instanceof IStoredNode)) {
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, "Wrong node type");
}
final IStoredNode<?> existing = (IStoredNode<?>) existingAttr;
if (!existing.getNodeId().isChildOf(nodeId)) {
throw new DOMException(DOMException.NOT_FOUND_ERR, "node " + existing.getNodeId().getParentId() + " is not a child of element " + nodeId);
}
// update old custom indexes
final IndexController indexes = broker.getIndexController();
indexes.reindex(transaction, existing, ReindexMode.STORE);
broker.updateNode(transaction, existing, true);
transaction.commit();
} catch (final EXistException e) {
LOG.error(e);
throw new DOMException(DOMException.INVALID_ACCESS_ERR, e.getMessage());
}
} else {
try (final DBBroker broker = ownerDocument.getBrokerPool().getBroker()) {
final AttrImpl attrib = new AttrImpl(attrName, value, broker.getBrokerPool().getSymbols());
appendChild(attrib);
} catch (final EXistException e) {
LOG.error(e);
throw new DOMException(DOMException.INVALID_ACCESS_ERR, e.getMessage());
}
}
}
Aggregations