package org.basex.core.cmd; import static org.basex.core.Text.*; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import org.basex.core.CommandBuilder; import org.basex.core.User; import org.basex.data.MetaData; import org.basex.io.IO; import org.basex.io.IOContent; import org.basex.io.IOFile; import org.basex.io.in.BufferInput; import org.basex.io.out.PrintOutput; import org.xml.sax.InputSource; /** * Evaluates the 'store' command and stores binary content into the database. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public final class Store extends ACreate { /** * Constructor, specifying a target path. * @param path target path */ public Store(final String path) { this(path, null); } /** * Constructor, specifying a target path and an input. * @param path target path * @param input input file */ public Store(final String path, final String input) { super(DATAREF | User.WRITE, path == null ? "" : path, input); } @Override protected boolean run() { final boolean create = context.user.perm(User.CREATE); String path = MetaData.normPath(args[0]); if(path == null || path.endsWith(".")) return error(NAME_INVALID_X, args[0]); if(in == null) { final IO io = IO.get(args[1]); if(!io.exists() || io.isDir()) return error(FILE_NOT_FOUND_X, create ? io : args[1]); in = io.inputSource(); // set/add name of document if((path.isEmpty() || path.endsWith("/")) && !(io instanceof IOContent)) path += io.name(); } // ensure that the final name is not empty if(path.isEmpty()) return error(NAME_INVALID_X, path); // ensure that the name is not empty and contains no trailing dots final IOFile file = context.data().meta.binary(path); if(path.isEmpty() || path.endsWith(".") || file == null || file.isDir()) return error(NAME_INVALID_X, create ? path : args[0]); // add directory if it does not exist anyway new IOFile(file.dir()).md(); try { store(in, file); } catch(final IOException ex) { return error(FILE_NOT_STORED_X, ex.getMessage()); } return info(QUERY_EXECUTED_X, perf); } /** * Stores the specified source to the specified file. * @param in input source * @param file target file * @throws IOException I/O exception */ public static void store(final InputSource in, final IOFile file) throws IOException { // add directory if it does not exist anyway new IOFile(file.dir()).md(); final PrintOutput po = new PrintOutput(file.path()); try { final Reader r = in.getCharacterStream(); final InputStream is = in.getByteStream(); final String id = in.getSystemId(); if(r != null) { for(int c; (c = r.read()) != -1;) po.utf8(c); } else if(is != null) { for(int b; (b = is.read()) != -1;) po.write(b); } else if(id != null) { final BufferInput bi = IO.get(id).buffer(); try { for(int b; (b = bi.read()) != -1;) po.write(b); } finally { bi.close(); } } } finally { po.close(); } } @Override public void build(final CommandBuilder cb) { cb.init().arg(TO, 0).arg(1); } }