package org.basex.query.up.primitives; import static org.basex.query.util.Err.*; import org.basex.data.Data; import org.basex.data.MemData; import org.basex.query.QueryException; import org.basex.util.InputInfo; import org.basex.util.Util; /** * Replace element content primitive. * * @author BaseX Team 2005-12, BSD License * @author Lukas Kircher */ public final class ReplaceElementContent extends StructuralUpdate { /** New value. */ private final byte[] value; /** * Constructor. * @param p pre * @param d data * @param i input info * @param val new value */ public ReplaceElementContent(final int p, final Data d, final InputInfo i, final byte[] val) { super(PrimitiveType.REPLACEELEMCONT, p, d, i); value = val; } @Override public void apply() { /* * Kind is hard coded because the target of a replace element content * expression can only be an element node. */ final int kind = Data.ELEM; final int loc = pre + data.attSize(pre, kind); /* * Attributes are not affected by this expression. * * As a result of this expression all child nodes are deleted and replaced * by either a single text node or no node at all (depends on wheter the * replacing value is an empty string or not). */ shifts = data.size(pre, kind) - data.attSize(pre, kind) - 1 + value.length == 0 ? 0 : 1; if(pre + data.size(pre, kind) == loc + 1 && data.kind(loc) == Data.TEXT) { // overwrite existing text node data.update(loc, Data.TEXT, value); } else { while(pre + data.size(pre, kind) > loc) data.delete(loc); if(value.length > 0) { final MemData md = new MemData(data); md.text(pre, loc - pre, value, Data.TEXT); md.insert(0); data.insert(loc, pre, md); } } } @Override public void merge(final UpdatePrimitive p) throws QueryException { UPMULTREPV.thrw(input, targetNode()); } @Override public boolean adjacentTexts(final int c) { return false; } @Override public int size() { return 1; } @Override public String toString() { return Util.info("%[%, %]", Util.name(this), targetNode(), value); } }