/** Saves the displayed text. */ private void save() { final BaseXFileChooser fc = new BaseXFileChooser(SAVE_AS, gui.gopts.get(GUIOptions.WORKPATH), gui).suffix(IO.XMLSUFFIX); final IO file = fc.select(Mode.FSAVE); if (file == null) return; gui.gopts.set(GUIOptions.WORKPATH, file.path()); gui.cursor(CURSORWAIT, true); final MainOptions opts = gui.context.options; final int mh = opts.get(MainOptions.MAXHITS); opts.set(MainOptions.MAXHITS, -1); opts.set(MainOptions.CACHEQUERY, false); try (final PrintOutput out = new PrintOutput(file.toString())) { if (cmd != null) { cmd.execute(gui.context, out); } else if (ns != null) { ns.serialize(Serializer.get(out)); } else { final byte[] txt = text.getText(); for (final byte t : txt) if (t < 0 || t > ' ' || ws(t)) out.write(t); } } catch (final IOException ex) { BaseXDialog.error(gui, Util.info(FILE_NOT_SAVED_X, file)); } finally { opts.set(MainOptions.MAXHITS, mh); opts.set(MainOptions.CACHEQUERY, true); gui.cursor(CURSORARROW, true); } }
@Override public void execute(final GUI gui) { final DialogExport dialog = new DialogExport(gui); if (!dialog.ok()) return; final IOFile root = new IOFile(dialog.path()); // check if existing files will be overwritten if (root.exists()) { IO file = null; boolean overwrite = false; final Data d = gui.context.data(); final IntList il = d.resources.docs(); final int is = il.size(); for (int i = 0; i < is; i++) { file = root.merge(Token.string(d.text(il.get(i), true))); if (file.exists()) { if (overwrite) { // more than one file will be overwritten; check remaining tests file = null; break; } overwrite = true; } } if (overwrite) { // show message for overwriting files or directories final String msg = file == null ? FILES_REPLACE_X : FILE_EXISTS_X; if (file == null) file = root; if (!BaseXDialog.confirm(gui, Util.info(msg, file))) return; } } DialogProgress.execute(gui, new Export(root.path())); }
/** * Scans an external ID. * * @param f full flag * @param r root flag * @return id * @throws IOException I/O exception */ private byte[] externalID(final boolean f, final boolean r) throws IOException { byte[] cont = null; final boolean pub = consume(PUBLIC); if (pub || consume(SYSTEM)) { checkS(); if (pub) { pubidLit(); if (f) checkS(); } final int qu = consume(); // [11] if (qu == '\'' || qu == '"') { int ch; final TokenBuilder tok = new TokenBuilder(); while ((ch = nextChar()) != qu) tok.add(ch); if (!f) return null; final String name = string(tok.finish()); if (!dtd && r) return cont; final XMLInput tin = input; try { final IO file = input.io().merge(name); cont = file.read(); } catch (final IOException ex) { Util.debug(ex); // skip unknown DTDs/entities cont = new byte[] {'?'}; } input = new XMLInput(new IOContent(cont, name)); if (consume(XDECL)) { check(XML); s(); if (version()) checkS(); s(); if (encoding() == null) error(TEXTENC); ch = nextChar(); if (s(ch)) ch = nextChar(); if (ch != '?') error(WRONGCHAR, '?', ch); ch = nextChar(); if (ch != '>') error(WRONGCHAR, '>', ch); cont = Arrays.copyOfRange(cont, input.pos(), cont.length); } s(); if (r) { extSubsetDecl(); if (!consume((char) 0)) error(INVEND); } input = tin; } else { if (f) error(SCANQUOTE, (char) qu); prev(1); } } return cont; }
/** * Sets a syntax highlighter, based on the file format. * * @param file file reference * @param opened indicates if file was opened from disk */ protected final void setSyntax(final IO file, final boolean opened) { setSyntax( !opened || file.hasSuffix(IO.XQSUFFIXES) ? new XQuerySyntax() : file.hasSuffix(IO.JSONSUFFIX) ? new JSONSyntax() : file.hasSuffix(IO.XMLSUFFIXES) || file.hasSuffix(IO.HTMLSUFFIXES) ? new XMLSyntax() : BaseXSyntax.SIMPLE); }
/** * 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 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 = new BufferInput(IO.get(id)); try { for (int b; (b = bi.read()) != -1; ) po.write(b); } finally { bi.close(); } } } finally { po.close(); } }
/** * Test query for stripping existing namespaces. * * @throws Exception exception */ @Test public void stripNS() throws Exception { final IO io = IO.get("<a xmlns:a='a'><b><c/><c/><c/></b></a>"); try (final QueryProcessor qp = new QueryProcessor("/*:a/*:b", context).context(new DBNode(io))) { final ANode sub = (ANode) qp.iter().next(); DataBuilder.stripNS(sub, token("a"), context); } }
@Override protected boolean run() { final boolean create = context.user.has(Perm.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(RES_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 Data data = context.data(); if (data.inMemory()) return error(NO_MAINMEM); final IOFile file = data.meta.binary(path); if (path.isEmpty() || path.endsWith(".") || file == null || file.isDir()) return error(NAME_INVALID_X, create ? path : args[0]); // start update if (!data.startUpdate()) return error(DB_PINNED_X, data.meta.name); try { store(in, file); return info(QUERY_EXECUTED_X_X, "", perf); } catch (final IOException ex) { return error(FILE_NOT_STORED_X, Util.message(ex)); } finally { data.finishUpdate(); } }
/** * Refreshes the list of recent query files and updates the query path. * * @param file new file */ void refreshHistory(final IOFile file) { final StringList sl = new StringList(); String path = null; if (file != null) { path = file.path(); gui.gprop.set(GUIProp.WORKPATH, file.dirPath()); sl.add(path); tabs.setToolTipTextAt(tabs.getSelectedIndex(), path); } final String[] qu = gui.gprop.strings(GUIProp.EDITOR); for (int q = 0; q < qu.length && q < 19; q++) { final String f = qu[q]; if (!f.equalsIgnoreCase(path) && IO.get(f).exists()) sl.add(f); } // store sorted history gui.gprop.set(GUIProp.EDITOR, sl.toArray()); hist.setEnabled(!sl.isEmpty()); }
/** * Handles info messages resulting from a query execution. * * @param msg info message * @return true if error was found */ private boolean error(final String msg) { final String line = msg.replaceAll("[\\r\\n].*", ""); Matcher m = XQERROR.matcher(line); int el, ec = 2; if (!m.matches()) { m = XMLERROR.matcher(line); if (!m.matches()) return true; el = Integer.parseInt(m.group(1)); errFile = getEditor().file.path(); } else { el = Integer.parseInt(m.group(1)); ec = Integer.parseInt(m.group(2)); errFile = m.group(3); } final EditorArea edit = find(IO.get(errFile), false); if (edit == null) return true; // find approximate error position final int ll = edit.last.length; int ep = ll; for (int e = 1, l = 1, c = 1; e < ll; ++c, e += cl(edit.last, e)) { if (l > el || l == el && c == ec) { ep = e; break; } if (edit.last[e] == '\n') { ++l; c = 0; } } if (ep < ll && Character.isLetterOrDigit(cp(edit.last, ep))) { while (ep > 0 && Character.isLetterOrDigit(cp(edit.last, ep - 1))) ep--; } edit.error(ep); errPos = ep; return true; }
/** * Constructor. * * @param args command-line arguments * @throws IOException I/O exception */ public BaseX(final String... args) throws IOException { super(args); // create session to show optional login request session(); console = true; try { // loop through all commands final StringBuilder bind = new StringBuilder(); SerializerOptions sopts = null; boolean v = false, qi = false, qp = false; final int os = ops.size(); for (int o = 0; o < os; o++) { final int c = ops.get(o); String val = vals.get(o); if (c == 'b') { // set/add variable binding if (bind.length() != 0) bind.append(','); // commas are escaped by a second comma val = bind.append(val.replaceAll(",", ",,")).toString(); execute(new Set(MainOptions.BINDINGS, val), false); } else if (c == 'c') { // evaluate commands final IO io = IO.get(val); String base = "."; if (io.exists() && !io.isDir()) { val = io.string(); base = io.path(); } execute(new Set(MainOptions.QUERYPATH, base), false); execute(val); execute(new Set(MainOptions.QUERYPATH, ""), false); console = false; } else if (c == 'D') { // hidden option: show/hide dot query graph execute(new Set(MainOptions.DOTPLAN, null), false); } else if (c == 'i') { // open database or create main memory representation execute(new Set(MainOptions.MAINMEM, true), false); execute(new Check(val), verbose); execute(new Set(MainOptions.MAINMEM, false), false); } else if (c == 'I') { // set/add variable binding if (bind.length() != 0) bind.append(','); // commas are escaped by a second comma val = bind.append("=").append(val.replaceAll(",", ",,")).toString(); execute(new Set(MainOptions.BINDINGS, val), false); } else if (c == 'o') { // change output stream if (out != System.out) out.close(); out = new PrintOutput(val); session().setOutputStream(out); } else if (c == 'q') { // evaluate query execute(new XQuery(val), verbose); console = false; } else if (c == 'Q') { // evaluate file contents or string as query final IO io = IO.get(val); String base = "."; if (io.exists() && !io.isDir()) { val = io.string(); base = io.path(); } execute(new Set(MainOptions.QUERYPATH, base), false); execute(new XQuery(val), verbose); execute(new Set(MainOptions.QUERYPATH, ""), false); console = false; } else if (c == 'r') { // parse number of runs execute(new Set(MainOptions.RUNS, Strings.toInt(val)), false); } else if (c == 'R') { // toggle query evaluation execute(new Set(MainOptions.RUNQUERY, null), false); } else if (c == 's') { // set/add serialization parameter if (sopts == null) sopts = new SerializerOptions(); final String[] kv = val.split("=", 2); sopts.assign(kv[0], kv.length > 1 ? kv[1] : ""); execute(new Set(MainOptions.SERIALIZER, sopts), false); } else if (c == 't') { // evaluate query execute(new Test(val), verbose); console = false; } else if (c == 'u') { // (de)activate write-back for updates execute(new Set(MainOptions.WRITEBACK, null), false); } else if (c == 'v') { // show/hide verbose mode v ^= true; } else if (c == 'V') { // show/hide query info qi ^= true; execute(new Set(MainOptions.QUERYINFO, null), false); } else if (c == 'w') { // toggle chopping of whitespaces execute(new Set(MainOptions.CHOP, null), false); } else if (c == 'x') { // show/hide xml query plan execute(new Set(MainOptions.XMLPLAN, null), false); qp ^= true; } else if (c == 'X') { // show query plan before/after query compilation execute(new Set(MainOptions.COMPPLAN, null), false); } else if (c == 'z') { // toggle result serialization execute(new Set(MainOptions.SERIALIZE, null), false); } verbose = qi || qp || v; } if (console) console(); } finally { quit(); } }