/** * Constructor. * * @throws Exception if any error occurs. */ public GUIMacOSX() throws Exception { // Name for the dock icon and the application menu System.setProperty(P_ABOUT_NAME, NAME); // Show menu in the screen menu instead of inside the application window System.setProperty(P_SCREEN_MENU_BAR, "true"); // load native java classes... appClass = Class.forName(C_APPLICATION); appObj = invoke(appClass, null, "getApplication", EC, EO); Class.forName(C_APPLICATION_EVENT); if (appObj != null) { invoke("addAboutMenuItem"); invoke("setEnabledAboutMenu", true); invoke("addPreferencesMenuItem"); invoke("setEnabledPreferencesMenu", true); addDockIcon(); final Class<?> alc = Class.forName(C_APPLICATION_LISTENER); final Object listener = Proxy.newProxyInstance( getClass().getClassLoader(), new Class[] {alc}, new AppInvocationHandler()); invoke("addApplicationListener", alc, listener); } }
/** * Returns an information string for an unexpected exception. * * @param ex exception * @return dummy object */ public static String bug(final Throwable ex) { final TokenBuilder tb = new TokenBuilder(BUGINFO); tb.add(NL).add("Contact: ").add(MAIL); tb.add(NL).add("Version: ").add(TITLE); tb.add(NL).add("Java: ").add(System.getProperty("java.vendor")); tb.add(", ").add(System.getProperty("java.version")); tb.add(NL).add("OS: ").add(System.getProperty("os.name")); tb.add(", ").add(System.getProperty("os.arch")); tb.add(NL).add("Stack Trace: "); for (final String e : toArray(ex)) tb.add(NL).add(e); return tb.toString(); }
/** * Recursively deletes the specified namespace URI reference. * * @param uri namespace URI reference */ void delete(final int uri) { for (int c = 0; c < sz; ++c) children[c].delete(uri); final int vl = values.length; for (int v = 0; v < vl; v += 2) { if (values[v + 1] != uri) continue; final int[] vals = new int[vl - 2]; System.arraycopy(values, 0, vals, 0, v); System.arraycopy(values, v + 2, vals, v, vl - v - 2); values = vals; break; } }
/** * Constructor. * * @param s socket * @param c database context * @param l log reference * @param srv server reference */ public ClientListener(final Socket s, final Context c, final Log l, final BaseXServer srv) { context = new Context(c, this); socket = s; log = l; server = srv; last = System.currentTimeMillis(); }
/** * Returns a password from standard input. * * @return password */ public static String password() { // use standard input if no console if defined (such as in Eclipse) if (NOCONSOLE) return input(); // hide password final char[] pw = System.console().readPassword(); return pw != null ? new String(pw) : ""; }
@Override public void run() { running = true; while (running) { try { final Socket s = socket.accept(); if (stop.exists()) { if (!stop.delete()) log.write(Util.info(FILE_NOT_DELETED_X, stop)); quit(); } else { // drop inactive connections final long ka = context.mprop.num(MainProp.KEEPALIVE) * 1000L; if (ka > 0) { final long ms = System.currentTimeMillis(); for (final ClientListener cs : context.sessions) { if (ms - cs.last > ka) cs.quit(); } } new ClientListener(s, context, log, this).start(); } } catch (final IOException ex) { // socket was closed.. break; } } }
/** * Main method, launching the server process. Command-line arguments are listed with the {@code * -h} argument. * * @param args command-line arguments */ public static void main(final String[] args) { try { new BaseXServer(args); } catch (final IOException ex) { Util.errln(ex); System.exit(1); } }
/** * Sends a notification to the client. * * @param name event name * @param msg event message * @throws IOException I/O exception */ public synchronized void notify(final byte[] name, final byte[] msg) throws IOException { last = System.currentTimeMillis(); eout.print(name); eout.write(0); eout.print(msg); eout.write(0); eout.flush(); }
/** * Adds the specified node into the child array, which is sorted by pre values. * * @param node child node */ void add(final NSNode node) { if (sz == children.length) children = Array.copy(children, new NSNode[Array.newSize(sz)]); // find inserting position int s = find(node.pr); if (s < 0 || node.pr != children[s].pr) s++; System.arraycopy(children, s, children, s + 1, sz++ - s); children[s] = node; node.parent = this; }
/** * Sets the output text. * * @param out cached output */ public void setText(final ArrayOutput out) { final byte[] buf = out.buffer(); final int size = (int) out.size(); final byte[] chop = token(DOTS); if (out.finished() && size >= chop.length) { System.arraycopy(chop, 0, buf, size - chop.length, chop.length); } text.setText(buf, size); header.setText((out.finished() ? CHOPPED : "") + RESULT); home.setEnabled(gui.context.data() != null); }
/** * Creates an item iterator for the given XML fragment. * * @param xml fragment * @param frag fragment flag * @return iterator */ private ItemCache toIter(final String xml, final boolean frag) { final ItemCache it = new ItemCache(); try { String str = frag ? "<X>" + xml + "</X>" : xml; final Data d = CreateDB.xml(IO.get(str), context); for (int p = frag ? 2 : 0; p < d.meta.size; p += d.size(p, d.kind(p))) it.add(new DBNode(d, p)); } catch (final IOException ex) { return new ItemCache(new Item[] {Str.get(Long.toString(System.nanoTime()))}, 1); } return it; }
/** * Starts the specified class in a separate process. * * @param clz class to start * @param args command-line arguments * @return reference to a {@link Process} instance representing the started process */ public static Process start(final Class<?> clz, final String... args) { final String[] largs = { "java", "-Xmx" + Runtime.getRuntime().maxMemory(), "-cp", System.getProperty("java.class.path"), clz.getName(), "-D", }; final StringList sl = new StringList().add(largs).add(args); try { return new ProcessBuilder(sl.toArray()).start(); } catch (final IOException ex) { notexpected(ex); return null; } }
/** * Adds values to the index. * * @param key key to be indexed * @param vals sorted values */ void add(final byte[] key, final int... vals) { // token index: add values. otherwise, reference existing values final int id = type == IndexType.TOKEN ? values.put(key) : values.id(key), vl = vals.length; // updatable index: if required, resize existing arrays while (idsList.size() < id + 1) idsList.add(null); if (lenList.size() < id + 1) lenList.set(id, 0); final int len = lenList.get(id), size = len + vl; int[] ids = idsList.get(id); if (ids == null) { ids = vals; } else { if (ids.length < size) ids = Arrays.copyOf(ids, Array.newSize(size)); System.arraycopy(vals, 0, ids, len, vl); if (ids[len - 1] > vals[0]) { if (reorder == null) reorder = new BoolList(values.size()); reorder.set(id, true); } } idsList.set(id, ids); lenList.set(id, size); }
/** * Deletes nodes in the specified range (p .. p + sz - 1) and updates the following pre values * * @param pre pre value * @param size number of nodes to be deleted, or actually the size of the pre value which is to be * deleted */ void delete(final int pre, final int size) { // find the pre value which must be deleted int s = find(pre); /* if the node is not directly contained as a child, either start at array * index 0 or proceed with the next node in the child array to search for * descendants of pre */ if (s == -1 || children[s].pr != pre) ++s; // first pre value which is not deleted final int upper = pre + size; // number of nodes to be deleted int num = 0; // determine number of nodes to be deleted for (int i = s; i < sz && children[i].pr < upper; ++i, ++num) ; // new size of child array sz -= num; // if all nodes are deleted, just create an empty array if (sz == 0) children = new NSNode[0]; // otherwise remove nodes from the child array else if (num > 0) System.arraycopy(children, s + num, children, s, sz - s); }
/** * Sets the specified value if property has not been set yet. * * @param key property key * @param value property value * @param force force setting */ private void set(final String key, final Object value, final boolean force) { if (force || System.getProperty(key) == null) { System.setProperty(key, value.toString()); } }
@Override public void run() { // initialize the session via cram-md5 authentication try { final String ts = Long.toString(System.nanoTime()); final byte[] address = socket.getInetAddress().getAddress(); // send {TIMESTAMP}0 out = PrintOutput.get(socket.getOutputStream()); out.print(ts); send(true); // evaluate login data in = new BufferInput(socket.getInputStream()); // receive {USER}0{PASSWORD}0 final String us = in.readString(); final String pw = in.readString(); context.user = context.users.get(us); running = context.user != null && md5(string(context.user.password) + ts).equals(pw); // write log information if (running) { log.write(this, "LOGIN " + context.user.name, OK); // send {OK} send(true); server.unblock(address); context.add(this); } else { if (!us.isEmpty()) log.write(this, ACCESS_DENIED + COLS + us); new ClientDelayer(server.block(address), this, server).start(); } } catch (final IOException ex) { Util.stack(ex); log.write(ex.getMessage()); return; } if (!running) return; // authentification done, start command loop ServerCmd sc = null; String cmd = null; try { while (running) { command = null; try { final int b = in.read(); if (b == -1) { // end of stream: exit session quit(); break; } last = System.currentTimeMillis(); perf.time(); sc = ServerCmd.get(b); cmd = null; if (sc == ServerCmd.CREATE) { create(); } else if (sc == ServerCmd.ADD) { add(); } else if (sc == ServerCmd.WATCH) { watch(); } else if (sc == ServerCmd.UNWATCH) { unwatch(); } else if (sc == ServerCmd.REPLACE) { replace(); } else if (sc == ServerCmd.STORE) { store(); } else if (sc != ServerCmd.COMMAND) { query(sc); } else { // database command cmd = new ByteList().add(b).add(in.readBytes()).toString(); } } catch (final IOException ex) { // this exception may be thrown if a session is stopped quit(); break; } if (sc != ServerCmd.COMMAND) continue; // parse input and create command instance try { command = new CommandParser(cmd, context).parseSingle(); } catch (final QueryException ex) { // log invalid command final String msg = ex.getMessage(); log.write(this, cmd, ERROR_C + msg); // send 0 to mark end of potential result out.write(0); // send {INFO}0 out.writeString(msg); // send 1 to mark error send(false); continue; } // start timeout command.startTimeout(context.mprop.num(MainProp.TIMEOUT)); log.write(this, command.toString().replace('\r', ' ').replace('\n', ' ')); // execute command and send {RESULT} boolean ok = true; String info; try { command.execute(context, new EncodingOutput(out)); info = command.info(); } catch (final BaseXException ex) { ok = false; info = ex.getMessage(); if (info.startsWith(INTERRUPTED)) info = TIMEOUT_EXCEEDED; } // stop timeout command.stopTimeout(); // send 0 to mark end of result out.write(0); // send info info(info, ok); // stop console if (command instanceof Exit) { command = null; quit(); } } } catch (final IOException ex) { log.write(this, sc == ServerCmd.COMMAND ? cmd : sc, ERROR_C + ex.getMessage()); Util.debug(ex); command = null; quit(); } command = null; }
/** * This class contains static methods, which are used throughout the project. The methods are used * for dumping error output, debugging information, getting the application path, etc. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public final class Util { /** Flag for using default standard input. */ private static final boolean NOCONSOLE = System.console() == null; /** Hidden constructor. */ private Util() {} /** * Returns an information string for an unexpected exception. * * @param ex exception * @return dummy object */ public static String bug(final Throwable ex) { final TokenBuilder tb = new TokenBuilder(BUGINFO); tb.add(NL).add("Contact: ").add(MAIL); tb.add(NL).add("Version: ").add(TITLE); tb.add(NL).add("Java: ").add(System.getProperty("java.vendor")); tb.add(", ").add(System.getProperty("java.version")); tb.add(NL).add("OS: ").add(System.getProperty("os.name")); tb.add(", ").add(System.getProperty("os.arch")); tb.add(NL).add("Stack Trace: "); for (final String e : toArray(ex)) tb.add(NL).add(e); return tb.toString(); } /** * Throws a runtime exception for an unexpected exception. * * @param ext optional extension * @return runtime exception (indicates that an error is raised) */ public static RuntimeException notexpected(final Object... ext) { final TokenBuilder tb = new TokenBuilder(); tb.addExt("%", ext.length == 0 ? "Not Expected." : ext[0]); throw new RuntimeException(tb.toString()); } /** * Throws a runtime exception for an unimplemented method. * * @param ext optional extension * @return runtime exception (indicates that an error is raised) */ public static RuntimeException notimplemented(final Object... ext) { final TokenBuilder tb = new TokenBuilder("Not Implemented"); if (ext.length != 0) tb.addExt(" (%)", ext); throw new UnsupportedOperationException(tb.add('.').toString()); } /** * Returns the class name of the specified object. * * @param o object * @return class name */ public static String name(final Object o) { return name(o.getClass()); } /** * Returns the name of the specified class. * * @param o object * @return class name */ public static String name(final Class<?> o) { return o.getSimpleName(); } /** * Returns a single line from standard input. * * @return string */ public static String input() { final Scanner sc = new Scanner(System.in); return sc.hasNextLine() ? sc.nextLine().trim() : ""; } /** * Returns a password from standard input. * * @return password */ public static String password() { // use standard input if no console if defined (such as in Eclipse) if (NOCONSOLE) return input(); // hide password final char[] pw = System.console().readPassword(); return pw != null ? new String(pw) : ""; } /** Prints a newline to standard output. */ public static void outln() { out(NL); } /** * Prints a string to standard output, followed by a newline. * * @param str output string * @param ext text optional extensions */ public static void outln(final Object str, final Object... ext) { out((str instanceof byte[] ? Token.string((byte[]) str) : str) + NL, ext); } /** * Prints a string to standard output. * * @param str output string * @param ext text optional extensions */ public static void out(final Object str, final Object... ext) { System.out.print(info(str, ext)); } /** * Prints a string to standard error, followed by a newline. * * @param obj error string * @param ext text optional extensions */ public static void errln(final Object obj, final Object... ext) { err((obj instanceof Throwable ? message((Throwable) obj) : obj) + NL, ext); } /** * Prints a string to standard error. * * @param string debug string * @param ext text optional extensions */ public static void err(final String string, final Object... ext) { System.err.print(info(string, ext)); } /** * Returns a more user-friendly error message for the specified exception. * * @param ex throwable reference * @return error message */ public static String message(final Throwable ex) { debug(ex); if (ex instanceof BindException) return SRV_RUNNING; if (ex instanceof LoginException) return ACCESS_DENIED; if (ex instanceof ConnectException) return CONNECTION_ERROR; if (ex instanceof SocketTimeoutException) return TIMEOUT_EXCEEDED; if (ex instanceof SocketException) return CONNECTION_ERROR; String msg = ex.getMessage(); if (msg == null || msg.isEmpty()) msg = ex.toString(); if (ex instanceof FileNotFoundException) return info(RES_NOT_FOUND_X, msg); if (ex instanceof UnknownHostException) return info(UNKNOWN_HOST_X, msg); return msg; } /** * Prints the exception stack trace if the {@link Prop#debug} flag is set. * * @param ex exception */ public static void debug(final Throwable ex) { if (Prop.debug && ex != null) stack(ex); } /** * Prints a string to standard error if the {@link Prop#debug} flag is set. * * @param str debug string * @param ext text optional extensions */ public static void debug(final Object str, final Object... ext) { if (Prop.debug) errln(str, ext); } /** * Prints performance information if the {@link Prop#debug} flag is set. * * @param perf performance reference */ public static void memory(final Performance perf) { if (!Prop.debug) return; errln(" " + perf + " (" + Performance.getMemory() + ')'); } /** * Returns a string and replaces all % characters by the specified extensions (see {@link * TokenBuilder#addExt} for details). * * @param str string to be extended * @param ext text text extensions * @return extended string */ public static String info(final Object str, final Object... ext) { return Token.string(inf(str, ext)); } /** * Returns a token and replaces all % characters by the specified extensions (see {@link * TokenBuilder#addExt} for details). * * @param str string to be extended * @param ext text text extensions * @return token */ public static byte[] inf(final Object str, final Object... ext) { return new TokenBuilder().addExt(str, ext).finish(); } /** * Prints the current stack trace to System.err. * * @param i number of steps to print */ public static void stack(final int i) { errln("You're here:"); final String[] stack = toArray(new Throwable()); final int l = Math.min(Math.max(2, i + 2), stack.length); for (int s = 2; s < l; ++s) errln(stack[s]); } /** * Prints the stack of the specified error to standard error. * * @param th error/exception instance */ public static void stack(final Throwable th) { for (final String s : toArray(th)) errln(s); } /** * Returns an string array representation of the specified throwable. * * @param th throwable * @return string array */ private static String[] toArray(final Throwable th) { final StackTraceElement[] st = th.getStackTrace(); final String[] obj = new String[st.length + 1]; obj[0] = th.toString(); for (int i = 0; i < st.length; i++) obj[i + 1] = " " + st[i]; return obj; } /** * Starts the specified class in a separate process. * * @param clz class to start * @param args command-line arguments * @return reference to a {@link Process} instance representing the started process */ public static Process start(final Class<?> clz, final String... args) { final String[] largs = { "java", "-Xmx" + Runtime.getRuntime().maxMemory(), "-cp", System.getProperty("java.class.path"), clz.getName(), "-D", }; final StringList sl = new StringList().add(largs).add(args); try { return new ProcessBuilder(sl.toArray()).start(); } catch (final IOException ex) { notexpected(ex); return null; } } /** * Checks if the specified string is "yes", "true" or "on". * * @param string string to be checked * @return result of check */ public static boolean yes(final String string) { return Token.eqic(string, YES, TRUE, ON, INFOON); } /** * Checks if the specified string is "no", "false" or "off". * * @param string string to be checked * @return result of check */ public static boolean no(final String string) { return Token.eqic(string, NO, FALSE, OFF, INFOOFF); } /** * Returns an info message for the specified flag. * * @param flag current flag status * @return ON/OFF message */ public static String flag(final boolean flag) { return flag ? INFOON : INFOOFF; } }