package org.basex.query.up.primitives; import static org.basex.core.Text.*; import static org.basex.query.util.Err.*; import java.io.IOException; import org.basex.data.Data; import org.basex.io.IOFile; import org.basex.io.out.PrintOutput; import org.basex.io.serial.Serializer; import org.basex.io.serial.SerializerProp; import org.basex.query.QueryContext; import org.basex.query.QueryException; import org.basex.query.item.DBNode; import org.basex.query.item.Uri; import org.basex.util.InputInfo; import org.basex.util.Util; /** * Update primitive for the fn:put() function. * * @author BaseX Team 2005-12, BSD License * @author Lukas Kircher */ public final class Put extends UpdatePrimitive { /** Put location. The same node can be stored in multiple locations. */ private Uri[] uri = new Uri[1]; /** Serializer properties. */ private final QueryContext ctx; /** * Constructor. * @param i input info * @param p pre * @param d data * @param u uri * @param context query context */ public Put(final InputInfo i, final int p, final Data d, final Uri u, final QueryContext context) { super(PrimitiveType.PUT, p, d, i); uri[0] = u; ctx = context; } @Override public void apply() throws QueryException { for(int i = 0; i < uri.length; i++) { PrintOutput po = null; final DBNode node = new DBNode(data, pre); try { po = new PrintOutput(path(i)); final SerializerProp pr = ctx.serProp(false); // try to reproduce non-chopped documents correctly pr.set(SerializerProp.S_INDENT, node.data.meta.chop ? YES : NO); node.serialize(Serializer.get(po, pr)); } catch(final IOException ex) { UPPUTERR.thrw(input, path(i)); } finally { if(po != null) try { po.close(); } catch(final IOException ex) { } } } } /** * Returns uri as string. * @param p uri position * @return string uri */ public String path(final int p) { return new IOFile(uri[p].toJava()).path(); } @Override public void merge(final UpdatePrimitive p) throws QueryException { final int l = uri.length; final Uri[] t = new Uri[l + 1]; System.arraycopy(uri, 0, t, 0, l); t[l] = ((Put) p).uri[0]; uri = t; } @Override public int size() { return uri.length; } @Override public String toString() { return Util.name(this) + '[' + targetNode() + ", " + uri[0] + ']'; } }