/** * Constructor. * * @param dt date * @param ii input info * @throws QueryException query exception */ public Dtm(final byte[] dt, final InputInfo ii) throws QueryException { super(AtomType.DTM, dt, XDTM, ii); final int i = Token.indexOf(dt, 'T'); if (i == -1) dateErr(dt, XDTM, ii); date(Token.substring(dt, 0, i), XDTM, ii); time(Token.substring(dt, i + 1), XDTM, ii); }
/** * Chooses files that match the specified pattern. * * @param file file filter * @param content content filter * @param root root directory * @return sorted file paths * @throws InterruptedException interruption */ String[] filter(final String file, final String content, final IOFile root) throws InterruptedException { final long id = ++filterId; final TreeSet<String> results = new TreeSet<>(); final int[] search = new TokenParser(Token.lc(Token.token(content))).toArray(); // glob pattern final ProjectCache pc = cache(root); if (file.contains("*") || file.contains("?")) { final Pattern pt = Pattern.compile(IOFile.regex(file)); for (final String path : pc) { final int offset = offset(path, true); if (pt.matcher(path.substring(offset)).matches() && filterContent(path, search)) { results.add(path); if (results.size() >= MAXHITS) break; } if (id != filterId) throw new InterruptedException(); } } else { // starts-with, contains, camel case final String pttrn = file.toLowerCase(Locale.ENGLISH).replace('\\', '/'); final HashSet<String> exclude = new HashSet<>(); final boolean pathSearch = pttrn.indexOf('/') != -1; for (int i = 0; i < (pathSearch ? 2 : 3); i++) { filter(pttrn, search, i, results, exclude, pathSearch, pc, id); } } return results.toArray(new String[results.size()]); }
/** * Constructor, specifying the server host:port combination, login data and an output stream. * * @param host server name * @param port server port * @param user user name * @param pass password * @param output client output; if set to {@code null}, results will be returned as strings. * @throws IOException I/O exception */ public ClientSession( final String host, final int port, final String user, final String pass, final OutputStream output) throws IOException { super(output); ehost = host; socket = new Socket(); try { // limit timeout to five seconds socket.connect(new InetSocketAddress(host, port), 5000); } catch (final IllegalArgumentException ex) { throw new BaseXException(ex); } sin = socket.getInputStream(); // receive timestamp final BufferInput bi = new BufferInput(sin); final String ts = bi.readString(); // send user name and hashed password/timestamp sout = PrintOutput.get(socket.getOutputStream()); send(user); send(Token.md5(Token.md5(pass) + ts)); sout.flush(); // receive success flag if (!ok(bi)) throw new LoginException(); }
@Override public final void plan(final Serializer ser) throws IOException { ser.openElement(this); ser.attribute(AXIS, Token.token(axis.name)); ser.attribute(TEST, Token.token(test.toString())); super.plan(ser); ser.closeElement(); }
@Override public Iter iter(final QueryContext ctx) throws QueryException { switch (def) { case ERROR: final int al = expr.length; if (al == 0) FUNERR1.thrw(input); String code = FUNERR1.code(); String msg = FUNERR1.desc; final Item it = expr[0].item(ctx, input); if (it == null) { if (al == 1) XPEMPTY.thrw(input, desc()); } else { code = Token.string(((QNm) checkType(it, AtomType.QNM)).ln()); } if (al > 1) msg = Token.string(checkEStr(expr[1], ctx)); final Value val = al > 2 ? expr[2].value(ctx) : null; final QueryException ex = new QueryException(input, code, val, msg); throw ex; case TRACE: return new Iter() { final Iter ir = expr[0].iter(ctx); final byte[] s = checkEStr(expr[1], ctx); @Override public Item next() throws QueryException { final Item i = ir.next(); if (i != null) { final TokenBuilder tb = new TokenBuilder(s); if (s.length != 0) tb.add(": "); tb.add(i.toString()); // if GUI is used, or if user is no admin, trace info is cached if (Prop.gui || !ctx.context.user.perm(User.ADMIN)) { ctx.evalInfo(tb.finish()); } else { Util.errln(tb); } } return i; } }; case ENVARS: final ItemCache ic = new ItemCache(); for (final Object k : System.getenv().keySet().toArray()) { ic.add(Str.get(k)); } return ic; default: return super.iter(ctx); } }
@Override int read(final TextInput ti) throws IOException { int ch = ti.readByte(); if (ch < 0x80) return ch; if (ch < 0xC0) return invalid(); cache[0] = (byte) ch; final int cl = Token.cl((byte) ch); for (int c = 1; c < cl; ++c) { ch = ti.readByte(); if (ch < 0x80) return invalid(); cache[c] = (byte) ch; } return Token.cp(cache, 0); }
/** * Returns the color for the specified string or {@code null}. * * @param string string string * @return color */ static String color(final byte[] string) { for (final Object[] color : COLORS) { final int cl = color.length; for (int c = 1; c < cl; c++) { final Object o = color[c]; final byte[] col = o instanceof byte[] ? (byte[]) o : Token.token(o instanceof Class ? Util.className((Class<?>) o) : o.toString()); if (Token.eq(col, string)) return color[0].toString(); } } return null; }
/** * Returns the combo box selections and the keys of the specified set. * * @param key keys * @return key array */ private String[] entries(final byte[][] key) { final StringList sl = new StringList(); sl.add(Util.info(INFOENTRIES, key.length)); for (final byte[] k : key) sl.add(Token.string(k)); sl.sort(true, true, 1); return sl.toArray(); }
/** * Test concurrent reader and writer (GH-458). * * <p><b>Test case:</b> * * <ol> * <li/>start a long running reader; * <li/>try to start a writer: it should time out; * <li/>stop the reader; * <li/>start the writer again: it should succeed. * </ol> * * @throws Exception error during request execution */ @Test @Ignore("There is no way to stop a query on the server!") public void testReaderWriter() throws Exception { final String readerQuery = "?query=(1%20to%20100000000000000)%5b.=1%5d"; final String writerQuery = "/test.xml"; final byte[] content = Token.token("<a/>"); final Get readerAction = new Get(readerQuery); final Put writerAction = new Put(writerQuery, content); final ExecutorService exec = Executors.newFixedThreadPool(2); // start reader exec.submit(readerAction); Performance.sleep(TIMEOUT); // delay in order to be sure that the reader has started // start writer Future<HTTPResponse> writer = exec.submit(writerAction); try { final HTTPResponse result = writer.get(TIMEOUT, TimeUnit.MILLISECONDS); if (result.status.isSuccess()) fail("Database modified while a reader is running"); throw new Exception(result.toString()); } catch (final TimeoutException e) { // writer is blocked by the reader: stop it writerAction.stop = true; } // stop reader readerAction.stop = true; // start the writer again writer = exec.submit(writerAction); assertEquals(HTTPCode.CREATED, writer.get().status); }
@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())); }
@Override public final int diff(final Item it, final Collation coll, final InputInfo ii) throws QueryException { return it.type.isUntyped() ? coll == null ? Token.diff(string(), it.string(ii)) : coll.compare(string(), it.string(ii)) : -it.diff(this, coll, ii); }
/** * Searches a string in a file. * * @param path file path * @param search codepoints of search string * @return success flag */ private static boolean filterContent(final String path, final int[] search) { final int cl = search.length; if (cl == 0) return true; try (final TextInput ti = new TextInput(new IOFile(path))) { final IntList il = new IntList(cl - 1); int c = 0; while (true) { if (!il.isEmpty()) { if (il.remove(0) == search[c++]) continue; c = 0; } while (true) { final int cp = ti.read(); if (cp == -1 || !XMLToken.valid(cp)) return false; final int lc = Token.lc(cp); if (c > 0) il.add(lc); if (lc == search[c]) { if (++c == cl) return true; } else { c = 0; break; } } } } catch (final IOException ex) { // file may not be accessible Util.debug(ex); return false; } }
/** * Notifies all views of a focus change. * * @param pre focused pre value * @param vw the calling view */ public void focus(final int pre, final View vw) { if (gui.context.focused == pre) return; gui.context.focused = pre; for (final View v : view) if (v != vw && v.visible()) v.refreshFocus(); if (pre != -1) { gui.status.setText(Token.string(ViewData.path(gui.context.data(), pre))); } }
@Override public void execute(final GUI gui) { final int pre = gui.context.marked.pres[0]; final byte[] txt = ViewData.path(gui.context.data(), pre); // copy path to clipboard final Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); clip.setContents(new StringSelection(Token.string(txt)), null); }
@Override public void startNonterminal(String name, int begin) { try { builder.openElem(Token.token(name), atts, nsp); } catch (IOException e) { throw new RuntimeException(e); } }
/** * Constructor. * * @param value value * @param type item type * @param ii input info * @throws QueryException query exception */ private Dur(final byte[] value, final Type type, final InputInfo ii) throws QueryException { this(type); final String val = Token.string(value).trim(); final Matcher mt = DUR.matcher(val); if (!mt.matches() || val.endsWith("P") || val.endsWith("T")) throw dateError(value, XDURR, ii); yearMonth(value, mt, ii); dayTime(value, mt, 6, ii); }
@Override public String getItemAsString(final Properties props) throws XQException { try { return it.node() && it.type != NodeType.TXT ? serialize() : Token.string(it.atom(null)); } catch (final QueryException e) { throw new XQException(e.getMessage(), e.code()); } }
/** * Adds the time to the specified token builder. * * @param tb token builder */ final void time(final TokenBuilder tb) { if (sec.remainder(DAYSECONDS).signum() == 0) return; tb.add('T'); final long h = hou(); if (h != 0) { tb.addLong(Math.abs(h)); tb.add('H'); } final long m = min(); if (m != 0) { tb.addLong(Math.abs(m)); tb.add('M'); } final BigDecimal sc = sec(); if (sc.signum() == 0) return; tb.add(Token.chopNumber(Token.token(sc.abs().toPlainString()))).add('S'); }
/** * Test client with different user. * * @throws IOException I/O exception */ @Test public void user() throws IOException { run("-cexit", "-cdrop user " + NAME); equals( "5", new String[] {"-U" + NAME, "-P" + NAME, "-q5"}, new String[] {"-ccreate user " + NAME + ' ' + Token.md5(NAME)}); run("-cexit", "-cdrop user " + NAME); }
private void characters(int begin, int end) { if (begin < end) { try { builder.text(Token.token(input.subSequence(begin, end).toString())); } catch (IOException e) { throw new RuntimeException(e); } } }
@Override public void plan(final Serializer ser) throws IOException { try { ser.emptyElement(ITM, VAL, atom(null), TYP, Token.token(name())); } catch (final QueryException ex) { // only function items throw exceptions in atomization, and they should // override plan(Serializer) sensibly Util.notexpected(ex); } }
@Override public final boolean eq( final Item it, final Collation coll, final StaticContext sc, final InputInfo ii) throws QueryException { return it.type.isUntyped() ? coll == null ? Token.eq(string(), it.string(ii)) : coll.compare(string(), it.string(ii)) == 0 : it.eq(this, coll, sc, ii); }
@Override public Item item(final QueryContext ctx, final InputInfo ii) throws QueryException { switch (def) { case ENVAR: final String e = System.getenv(Token.string(checkEStr(expr[0], ctx))); return e != null ? Str.get(e) : null; default: return super.item(ctx, ii); } }
@Override public String getAtomicValue() throws XQException { opened(); if (it.node()) throw new BXQException(ATOM); try { return Token.string(it.atom(null)); } catch (final QueryException e) { // function item throw new BXQException(ATOM); } }
@Override public URI getNodeUri() throws XQException { opened(); if (!it.node()) throw new BXQException(NODE); final ANode node = (ANode) it; try { return new URI(Token.string(node.base())); } catch (final URISyntaxException ex) { throw new BXQException(ex.toString()); } }
@Override public void actionPerformed(final ActionEvent e) { if (e != null) { final Object source = e.getSource(); // find modified component int cp = 0; final int cs = panel.getComponentCount(); for (int c = 0; c < cs; ++c) if (panel.getComponent(c) == source) cp = c; if ((cp & 1) == 0) { // combo box with tags/attributes final BaseXCombo combo = (BaseXCombo) source; panel.remove(cp + 1); final Data data = gui.context.data(); final boolean selected = combo.getSelectedIndex() != 0; if (selected) { final String item = combo.getSelectedItem().toString(); final boolean att = item.startsWith("@"); final Names names = att ? data.atnindex : data.tagindex; final byte[] key = Token.token(att ? item.substring(1) : item); final StatsKey stat = names.stat(names.id(key)); switch (stat.kind) { case INT: addSlider(stat.min, stat.max, cp + 1, true); break; case DBL: addSlider(stat.min, stat.max, cp + 1, false); break; case CAT: addCombo(entries(stat.cats.keys()), cp + 1); break; case TEXT: addInput(cp + 1); break; case NONE: panel.add(new BaseXLabel(""), cp + 1); break; } } else { panel.add(new BaseXLabel(""), cp + 1); } while (cp + 2 < panel.getComponentCount()) { panel.remove(cp + 2); panel.remove(cp + 2); } if (selected) addKeys(data); panel.revalidate(); panel.repaint(); } } query(false); }
@Override protected byte[] stem(final byte[] word) { int ln = 0; final int wl = word.length; final char[] s = new char[wl]; for (int i = 0; i < wl; i += Token.cl(word, i)) { s[ln++] = (char) Token.cp(word, i); } if (ln < 4) return word; final int olen = ln; // "short rules": if it hits one of these, it skips the "long list" int l = rule0(s, ln); l = rule1(s, l); l = rule2(s, l); l = rule3(s, l); l = rule4(s, l); l = rule5(s, l); l = rule6(s, l); l = rule7(s, l); l = rule8(s, l); l = rule9(s, l); l = rule10(s, l); l = rule11(s, l); l = rule12(s, l); l = rule13(s, l); l = rule14(s, l); l = rule15(s, l); l = rule16(s, l); l = rule17(s, l); l = rule18(s, l); l = rule19(s, l); l = rule20(s, l); if (l == olen) l = rule21(s, l); // "long list" l = rule22(s, l); final TokenBuilder tb = new TokenBuilder(l << 1); for (int i = 0; i < l; i++) tb.add(s[i]); return tb.finish(); }
/** * Calculates the text offset and writes the text value. * * @param value value to be inlined * @param text text/attribute flag * @return inline value or text position * @throws IOException I/O exception */ private long textOff(final byte[] value, final boolean text) throws IOException { // inline integer values... final long v = Token.toSimpleInt(value); if (v != Integer.MIN_VALUE) return v | IO.OFFNUM; // store text final DataOutput store = text ? xout : vout; final long off = store.size(); final byte[] val = COMP.get().pack(value); store.writeToken(val); return val == value ? off : off | IO.OFFCOMP; }
@Override public Item item(final QueryContext qc, final InputInfo ii) throws QueryException { final byte[] s; if (exprs.length == 0) { final Item it = ctxValue(qc).item(qc, info); if (it instanceof FItem) throw FISTRING_X.get(ii, it.type); s = it == null ? Token.EMPTY : it.string(ii); } else { s = toEmptyToken(arg(0, qc), qc); } return Int.get(Token.length(s)); }
/** * Initializes the date format. * * @param d input * @param e example format * @param ii input info * @throws QueryException query exception */ final void date(final byte[] d, final String e, final InputInfo ii) throws QueryException { final Matcher mt = DATE.matcher(Token.string(d).trim()); if (!mt.matches()) throw dateError(d, e, ii); yea = toLong(mt.group(1), false, ii); // +1 is added to BC values to simplify computations if (yea < 0) yea++; mon = (byte) (Strings.toInt(mt.group(3)) - 1); day = (byte) (Strings.toInt(mt.group(4)) - 1); if (mon < 0 || mon >= 12 || day < 0 || day >= dpm(yea, mon)) throw dateError(d, e, ii); if (yea <= MIN_YEAR || yea > MAX_YEAR) throw DATERANGE_X_X.get(ii, type, chop(d, ii)); zone(mt, 5, d, ii); }