/** * Constructor. * * @param rq request * @param rs response * @throws IOException I/O exception */ public HTTPContext(final HttpServletRequest rq, final HttpServletResponse rs) throws IOException { req = rq; res = rs; final String m = rq.getMethod(); method = HTTPMethod.get(m); final StringBuilder uri = new StringBuilder(req.getRequestURL()); final String qs = req.getQueryString(); if (qs != null) uri.append('?').append(qs); log(false, m, uri); // set UTF8 as default encoding (can be overwritten) res.setCharacterEncoding(UTF8); segments = toSegments(req.getPathInfo()); path = join(0); user = System.getProperty(DBUSER); pass = System.getProperty(DBPASS); // set session-specific credentials final String auth = req.getHeader(AUTHORIZATION); if (auth != null) { final String[] values = auth.split(" "); if (values[0].equals(BASIC)) { final String[] cred = Base64.decode(values[1]).split(":", 2); if (cred.length != 2) throw new LoginException(NOPASSWD); user = cred[0]; pass = cred[1]; } else { throw new LoginException(WHICHAUTH, values[0]); } } }
/** * Adds a record to the table and the ID index. * * @param i index in the table where the record should be inserted * @param pre pre value * @param fid first ID value * @param nid last ID value * @param inc increment value * @param oid original ID value */ private void add( final int i, final int pre, final int fid, final int nid, final int inc, final int oid) { if (rows == pres.length) { final int s = Array.newSize(rows); pres = Arrays.copyOf(pres, s); fids = Arrays.copyOf(fids, s); nids = Arrays.copyOf(nids, s); incs = Arrays.copyOf(incs, s); oids = Arrays.copyOf(oids, s); } if (i < rows) { final int destPos = i + 1; final int length = rows - i; System.arraycopy(pres, i, pres, destPos, length); System.arraycopy(fids, i, fids, destPos, length); System.arraycopy(nids, i, nids, destPos, length); System.arraycopy(incs, i, incs, destPos, length); System.arraycopy(oids, i, oids, destPos, length); } pres[i] = pre; fids[i] = fid; nids[i] = nid; incs[i] = inc; oids[i] = oid; ++rows; }
/** * Removes a records from the table and the ID index. * * @param s start index of records in the table (inclusive) * @param e end index of records in the table (inclusive) */ private void remove(final int s, final int e) { if (s <= e) { final int last = e + 1; final int length = rows - last; System.arraycopy(pres, last, pres, s, length); System.arraycopy(fids, last, fids, s, length); System.arraycopy(nids, last, nids, s, length); System.arraycopy(incs, last, incs, s, length); System.arraycopy(oids, last, oids, s, length); rows -= last - s; } }
/** * 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(); }
/** * Runs a request with the specified arguments and server arguments. * * @param args command-line arguments * @param sargs server arguments * @return result * @throws IOException I/O exception */ private static String run(final String[] args, final String[] sargs) throws IOException { final BaseXServer server = createServer(sargs); final ArrayOutput ao = new ArrayOutput(); System.setOut(new PrintStream(ao)); System.setErr(NULL); final StringList sl = new StringList(); sl.add("-p9999").add("-U" + Text.S_ADMIN).add("-P" + Text.S_ADMIN).add(args); try { new BaseXClient(sl.finish()); return ao.toString(); } finally { System.setErr(ERR); stopServer(server); } }
/** * Writes a log message. * * @param str strings to be written * @param time add performance info */ public void log(final boolean time, final Object... str) { final Object[] obj = new Object[str.length + (time ? 2 : 1)]; obj[0] = remote(); System.arraycopy(str, 0, obj, 1, str.length); if (time) obj[obj.length - 1] = perf.toString(); context.log.write(obj); }
/** * 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) : ""; }
/** * Main method, launching the standalone mode. Command-line arguments are listed with the {@code * -h} argument. * * @param args command-line arguments */ public static void main(final String... args) { try { new BaseX(args); } catch (final IOException ex) { Util.errln(ex); System.exit(1); } }
/** * Initializes the servlet context, based on the servlet context. Parses all context parameters * and passes them on to the database context. * * @param sc servlet context * @throws IOException I/O exception */ static synchronized void init(final ServletContext sc) throws IOException { // skip process if context has already been initialized if (context != null) return; // set servlet path as home directory final String path = sc.getRealPath("/"); System.setProperty(Prop.PATH, path); // parse all context parameters final HashMap<String, String> map = new HashMap<String, String>(); // store default web root map.put(MainProp.HTTPPATH[0].toString(), path); final Enumeration<?> en = sc.getInitParameterNames(); while (en.hasMoreElements()) { final String key = en.nextElement().toString(); if (!key.startsWith(Prop.DBPREFIX)) continue; // only consider parameters that start with "org.basex." String val = sc.getInitParameter(key); if (eq(key, DBUSER, DBPASS, DBMODE, DBVERBOSE)) { // store servlet-specific parameters as system properties System.setProperty(key, val); } else { // prefix relative paths with absolute servlet path if (key.endsWith("path") && !new File(val).isAbsolute()) { val = path + File.separator + val; } // store remaining parameters (without project prefix) in map map.put(key.substring(Prop.DBPREFIX.length()).toUpperCase(Locale.ENGLISH), val); } } context = new Context(map); if (SERVER.equals(System.getProperty(DBMODE))) { new BaseXServer(context); } else { context.log = new Log(context); } }
/** * 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); }
/** * 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; } }