+++ /dev/null
-package org.open_ils.test;
-import org.open_ils.util.Utils;
-import org.open_ils.Event;
-import org.opensrf.*;
-import java.util.Map;
-import java.util.HashMap;
-
-
-public class TestLogin {
- public static void main(String args[]) {
- try {
-
- if(args.length < 3) {
- System.err.println("usage: java org.open_ils.test.TestLogin <opensrf_config> <username> <password>");
- return;
- }
-
- Sys.bootstrapClient(args[0], "/config/opensrf");
- Map<String,String> params = new HashMap<String,String>();
- params.put("username", args[1]);
- params.put("password", args[2]);
- Event evt = Utils.login(params);
- System.out.println(evt);
- } catch(Exception e) {
- System.err.println(e);
- }
- }
-}
-
+++ /dev/null
-package org.opensrf.net.xmpp;
-
-/**
- * Used for XMPP stream/authentication errors
- */
-public class XMPPException extends Exception {
- public XMPPException(String info) {
- super(info);
- }
-}
+++ /dev/null
-package org.opensrf.net.xmpp;
-
-import java.io.*;
-
-/**
- * Models a single XMPP message.
- */
-public class XMPPMessage {
-
- /** Message body */
- private String body;
- /** Message recipient */
- private String to;
- /** Message sender */
- private String from;
- /** Message thread */
- private String thread;
- /** Message xid */
- private String xid;
-
- public XMPPMessage() {
- }
-
- public String getBody() {
- return body;
- }
- public String getTo() {
- return to;
- }
- public String getFrom() {
- return from;
- }
- public String getThread() {
- return thread;
- }
- public String getXid() {
- return xid;
- }
- public void setBody(String body) {
- this.body = body;
- }
- public void setTo(String to) {
- this.to = to;
- }
- public void setFrom(String from) {
- this.from = from;
- }
- public void setThread(String thread) {
- this.thread = thread;
- }
- public void setXid(String xid) {
- this.xid = xid;
- }
-
-
- /**
- * Generates the XML representation of this message.
- */
- public String toXML() {
- StringBuffer sb = new StringBuffer("<message to='");
- escapeXML(to, sb);
- sb.append("' osrf_xid='");
- escapeXML(xid, sb);
- sb.append("'><thread>");
- escapeXML(thread, sb);
- sb.append("</thread><body>");
- escapeXML(body, sb);
- sb.append("</body></message>");
- return sb.toString();
- }
-
-
- /**
- * Escapes non-valid XML characters.
- * @param s The string to escape.
- * @param sb The StringBuffer to append new data to.
- */
- private void escapeXML(String s, StringBuffer sb) {
- if( s == null ) return;
- char c;
- int l = s.length();
- for( int i = 0; i < l; i++ ) {
- c = s.charAt(i);
- switch(c) {
- case '<':
- sb.append("<");
- break;
- case '>':
- sb.append(">");
- break;
- case '&':
- sb.append("&");
- break;
- default:
- sb.append(c);
- }
- }
- }
-}
-
-
+++ /dev/null
-package org.opensrf.net.xmpp;
-
-import javax.xml.stream.*;
-import javax.xml.stream.events.* ;
-import javax.xml.namespace.QName;
-import java.util.Queue;
-import java.io.InputStream;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.Date;
-import org.opensrf.util.Logger;
-
-/**
- * Slim XMPP Stream reader. This reader only understands enough XMPP
- * to handle logins and recv messages. It's implemented as a StAX parser.
- * @author Bill Erickson, Georgia Public Library Systems
- */
-public class XMPPReader implements Runnable {
-
- /** Queue of received messages. */
- private Queue<XMPPMessage> msgQueue;
- /** Incoming XMPP XML stream */
- private InputStream inStream;
- /** Current message body */
- private StringBuffer msgBody;
- /** Current message thread */
- private StringBuffer msgThread;
- /** Current message status */
- private StringBuffer msgStatus;
- /** Current message error type */
- private StringBuffer msgErrType;
- /** Current message sender */
- private String msgFrom;
- /** Current message recipient */
- private String msgTo;
- /** Current message error code */
- private int msgErrCode;
-
- /** Where this reader currently is in the document */
- private XMLState xmlState;
-
- /** The current connect state to the XMPP server */
- private XMPPStreamState streamState;
-
-
- /** Used to represent out connection state to the XMPP server */
- public static enum XMPPStreamState {
- DISCONNECTED, /* not connected to the server */
- CONNECT_SENT, /* we've sent the initial connect message */
- CONNECT_RECV, /* we've received a response to our connect message */
- AUTH_SENT, /* we've sent an authentication request */
- CONNECTED /* authentication is complete */
- };
-
-
- /** Used to represents where we are in the XML document stream. */
- public static enum XMLState {
- IN_NOTHING,
- IN_BODY,
- IN_THREAD,
- IN_STATUS
- };
-
-
- /**
- * Creates a new reader. Initializes the message queue.
- * Sets the stream state to disconnected, and the xml
- * state to in_nothing.
- * @param inStream the inbound XML stream
- */
- public XMPPReader(InputStream inStream) {
- msgQueue = new ConcurrentLinkedQueue<XMPPMessage>();
- this.inStream = inStream;
- resetBuffers();
- xmlState = XMLState.IN_NOTHING;
- streamState = XMPPStreamState.DISCONNECTED;
- }
-
- /**
- * Change the connect state and notify that a core
- * event has occurred.
- */
- protected void setXMPPStreamState(XMPPStreamState state) {
- streamState = state;
- notifyCoreEvent();
- }
-
- /**
- * @return The current stream state of the reader
- */
- public XMPPStreamState getXMPPStreamState() {
- return streamState;
- }
-
-
- /**
- * @return The next message in the queue, or null
- */
- public XMPPMessage popMessageQueue() {
- return (XMPPMessage) msgQueue.poll();
- }
-
-
- /**
- * Initializes the message buffers
- */
- private void resetBuffers() {
- msgBody = new StringBuffer();
- msgThread = new StringBuffer();
- msgStatus = new StringBuffer();
- msgErrType = new StringBuffer();
- msgFrom = "";
- msgTo = "";
- }
-
-
- /**
- * Notifies the waiting thread that a core event has occurred.
- * Each reader should have exactly one dependent session thread.
- */
- private synchronized void notifyCoreEvent() {
- notifyAll();
- }
-
-
- /**
- * Waits up to timeout milliseconds for a core event to occur.
- * Also, having a message already waiting in the queue
- * constitutes a core event.
- * @param timeout The number of milliseconds to wait. If
- * timeout is negative, waits potentially forever.
- * @return The number of milliseconds in wait
- */
- public synchronized long waitCoreEvent(long timeout) {
-
- if(msgQueue.peek() != null || timeout == 0) return 0;
- long start = new Date().getTime();
-
- try{
- if(timeout < 0)
- wait();
- else
- wait(timeout);
- } catch(InterruptedException ie) {}
-
- return new Date().getTime() - start;
- }
-
-
-
- /** Kickoff the thread */
- public void run() {
- read();
- }
-
-
- /**
- * Parses XML data from the provided XMPP stream.
- */
- public void read() {
-
- try {
-
- XMLInputFactory factory = XMLInputFactory.newInstance();
-
- /** disable as many unused features as possible to speed up the parsing */
- factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE);
- factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
- factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.FALSE);
- factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.FALSE);
- factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
-
- /** create the stream reader */
- XMLStreamReader reader = factory.createXMLStreamReader(inStream);
- int eventType;
-
- while(reader.hasNext()) {
- /** cycle through the XML events */
-
- eventType = reader.next();
-
- switch(eventType) {
-
- case XMLEvent.START_ELEMENT:
- handleStartElement(reader);
- break;
-
- case XMLEvent.CHARACTERS:
- switch(xmlState) {
- case IN_BODY:
- msgBody.append(reader.getText());
- break;
- case IN_THREAD:
- msgThread.append(reader.getText());
- break;
- case IN_STATUS:
- msgStatus.append(reader.getText());
- break;
- }
- break;
-
- case XMLEvent.END_ELEMENT:
- xmlState = XMLState.IN_NOTHING;
- if("message".equals(reader.getName().toString())) {
-
- /** build a message and add it to the message queue */
- XMPPMessage msg = new XMPPMessage();
- msg.setFrom(msgFrom);
- msg.setTo(msgTo);
- msg.setBody(msgBody.toString());
- msg.setThread(msgThread.toString());
-
- Logger.internal("xmpp message from="+msgFrom+" " + msg.getBody());
-
- msgQueue.offer(msg);
- resetBuffers();
- notifyCoreEvent();
- }
- break;
- }
- }
-
- } catch(javax.xml.stream.XMLStreamException se) {
- /* XXX log an error */
- xmlState = XMLState.IN_NOTHING;
- streamState = XMPPStreamState.DISCONNECTED;
- notifyCoreEvent();
- }
- }
-
-
- /**
- * Handles the start_element event.
- */
- private void handleStartElement(XMLStreamReader reader) {
-
- String name = reader.getName().toString();
-
- if("message".equals(name)) {
- xmlState = XMLState.IN_BODY;
-
- /** add a special case for the opensrf "router_from" attribute */
- String rf = reader.getAttributeValue(null, "router_from");
- if( rf != null )
- msgFrom = rf;
- else
- msgFrom = reader.getAttributeValue(null, "from");
- msgTo = reader.getAttributeValue(null, "to");
- return;
- }
-
- if("body".equals(name)) {
- xmlState = XMLState.IN_BODY;
- return;
- }
-
- if("thread".equals(name)) {
- xmlState = XMLState.IN_THREAD;
- return;
- }
-
- if("stream:stream".equals(name)) {
- setXMPPStreamState(XMPPStreamState.CONNECT_RECV);
- return;
- }
-
- if("iq".equals(name)) {
- if("result".equals(reader.getAttributeValue(null, "type")))
- setXMPPStreamState(XMPPStreamState.CONNECTED);
- return;
- }
-
- if("status".equals(name)) {
- xmlState = XMLState.IN_STATUS;
- return;
- }
-
- if("stream:error".equals(name)) {
- setXMPPStreamState(XMPPStreamState.DISCONNECTED);
- return;
- }
-
- if("error".equals(name)) {
- msgErrType.append(reader.getAttributeValue(null, "type"));
- msgErrCode = Integer.parseInt(reader.getAttributeValue(null, "code"));
- setXMPPStreamState(XMPPStreamState.DISCONNECTED);
- return;
- }
- }
-}
-
-
-
-
+++ /dev/null
-package org.opensrf.net.xmpp;
-
-import java.io.*;
-import java.net.Socket;
-import java.util.Map;
-import java.util.Iterator;
-import java.util.concurrent.ConcurrentHashMap;
-
-
-/**
- * Represents a single XMPP session. Sessions are responsible for writing to
- * the stream and for managing a stream reader.
- */
-public class XMPPSession {
-
- /** Initial jabber message */
- public static final String JABBER_CONNECT =
- "<stream:stream to='%s' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>";
-
- /** Basic auth message */
- public static final String JABBER_BASIC_AUTH =
- "<iq id='123' type='set'><query xmlns='jabber:iq:auth'>" +
- "<username>%s</username><password>%s</password><resource>%s</resource></query></iq>";
-
- public static final String JABBER_DISCONNECT = "</stream:stream>";
-
- private static Map threadConnections = new ConcurrentHashMap();
-
- /** jabber domain */
- private String host;
- /** jabber port */
- private int port;
- /** jabber username */
- private String username;
- /** jabber password */
- private String password;
- /** jabber resource */
- private String resource;
-
- /** XMPP stream reader */
- XMPPReader reader;
- /** Fprint-capable socket writer */
- PrintWriter writer;
- /** Raw socket output stream */
- OutputStream outStream;
- /** The raw socket */
- Socket socket;
-
- /** The process-wide session. All communication occurs
- * accross this single connection */
- private static XMPPSession globalSession;
-
-
- /**
- * Creates a new session.
- * @param host The jabber domain
- * @param port The jabber port
- */
- public XMPPSession( String host, int port ) {
- this.host = host;
- this.port = port;
- }
-
- /**
- * Returns the global, process-wide session
- */
- /*
- public static XMPPSession getGlobalSession() {
- return globalSession;
- }
- */
-
- public static XMPPSession getThreadSession() {
- return (XMPPSession) threadConnections.get(new Long(Thread.currentThread().getId()));
- }
-
- /**
- * Sets the given session as the global session for the current thread
- * @param ses The session
- */
- public static void setThreadSession(XMPPSession ses) {
- /* every time we create a new connection, clean up any dead threads.
- * this is cheaper than cleaning up the dead threads at every access. */
- cleanupThreadSessions();
- threadConnections.put(new Long(Thread.currentThread().getId()), ses);
- }
-
- /**
- * Analyzes the threadSession data to see if there are any sessions
- * whose controlling thread has gone away.
- */
- private static void cleanupThreadSessions() {
- Thread threads[] = new Thread[Thread.activeCount()];
- Thread.enumerate(threads);
- for(Iterator i = threadConnections.keySet().iterator(); i.hasNext(); ) {
- boolean found = false;
- Long id = (Long) i.next();
- for(Thread t : threads) {
- if(t.getId() == id.longValue()) {
- found = true;
- break;
- }
- }
- if(!found)
- threadConnections.remove(id);
- }
- }
-
- /**
- * Sets the global, process-wide section
- */
- /*
- public static void setGlobalSession(XMPPSession ses) {
- globalSession = ses;
- }
- */
-
-
- /** true if this session is connected to the server */
- public boolean connected() {
- return (
- reader != null &&
- reader.getXMPPStreamState() == XMPPReader.XMPPStreamState.CONNECTED &&
- !socket.isClosed()
- );
- }
-
-
- /**
- * Connects to the network.
- * @param username The jabber username
- * @param password The jabber password
- * @param resource The Jabber resource
- */
- public void connect(String username, String password, String resource) throws XMPPException {
-
- this.username = username;
- this.password = password;
- this.resource = resource;
-
- try {
- /* open the socket and associated streams */
- socket = new Socket(host, port);
-
- /** the session maintains control over the output stream */
- outStream = socket.getOutputStream();
- writer = new PrintWriter(outStream, true);
-
- /** pass the input stream to the reader */
- reader = new XMPPReader(socket.getInputStream());
-
- } catch(IOException ioe) {
- throw new
- XMPPException("unable to communicate with host " + host + " on port " + port);
- }
-
- /* build the reader thread */
- Thread thread = new Thread(reader);
- thread.setDaemon(true);
- thread.start();
-
- synchronized(reader) {
- /* send the initial jabber message */
- sendConnect();
- reader.waitCoreEvent(10000);
- }
- if( reader.getXMPPStreamState() != XMPPReader.XMPPStreamState.CONNECT_RECV )
- throw new XMPPException("unable to connect to jabber server");
-
- synchronized(reader) {
- /* send the basic auth message */
- sendBasicAuth();
- reader.waitCoreEvent(10000);
- }
- if(!connected())
- throw new XMPPException("Authentication failed");
- }
-
- /** Sends the initial jabber message */
- private void sendConnect() {
- reader.setXMPPStreamState(XMPPReader.XMPPStreamState.CONNECT_SENT);
- writer.printf(JABBER_CONNECT, host);
- }
-
- /** Send the basic auth message */
- private void sendBasicAuth() {
- reader.setXMPPStreamState(XMPPReader.XMPPStreamState.AUTH_SENT);
- writer.printf(JABBER_BASIC_AUTH, username, password, resource);
- }
-
-
- /**
- * Sends an XMPPMessage.
- * @param msg The message to send.
- */
- public synchronized void send(XMPPMessage msg) throws XMPPException {
- checkConnected();
- try {
- String xml = msg.toXML();
- outStream.write(xml.getBytes());
- } catch (Exception e) {
- throw new XMPPException(e.toString());
- }
- }
-
-
- /**
- * @throws XMPPException if we are no longer connected.
- */
- private void checkConnected() throws XMPPException {
- if(!connected())
- throw new XMPPException("Disconnected stream");
- }
-
-
- /**
- * Receives messages from the network.
- * @param timeout Maximum number of milliseconds to wait for a message to arrive.
- * If timeout is negative, this method will wait indefinitely.
- * If timeout is 0, this method will not block at all, but will return a
- * message if there is already a message available.
- */
- public XMPPMessage recv(long timeout) throws XMPPException {
-
- XMPPMessage msg;
-
- if(timeout < 0) {
-
- while(true) { /* wait indefinitely for a message to arrive */
- reader.waitCoreEvent(timeout);
- msg = reader.popMessageQueue();
- if( msg != null ) return msg;
- checkConnected();
- }
-
- } else {
-
- while(timeout >= 0) { /* wait at most 'timeout' milleseconds for a message to arrive */
- msg = reader.popMessageQueue();
- if( msg != null ) return msg;
- timeout -= reader.waitCoreEvent(timeout);
- msg = reader.popMessageQueue();
- if( msg != null ) return msg;
- checkConnected();
- if(timeout == 0) break;
- }
- }
-
- return reader.popMessageQueue();
- }
-
-
- /**
- * Disconnects from the jabber server and closes the socket
- */
- public void disconnect() {
- try {
- outStream.write(JABBER_DISCONNECT.getBytes());
- socket.close();
- } catch(Exception e) {}
- }
-}
-
+++ /dev/null
-package org.opensrf.test;
-import org.opensrf.*;
-import org.opensrf.util.*;
-
-public class TestConfig {
- public static void main(String args[]) throws Exception {
- Config config = new Config("");
- config.parse(args[0]);
- Config.setConfig(config);
- System.out.println(config);
- System.out.println("");
-
- for(int i = 1; i < args.length; i++)
- System.out.println("Found config value: " + args[i] + ": " + Config.global().get(args[i]));
- }
-}
+++ /dev/null
-package org.opensrf.test;
-import org.opensrf.util.Logger;
-import org.opensrf.util.FileLogger;
-
-
-/** Simple test class for tesing the logging functionality */
-public class TestLog {
- public static void main(String args[]) {
- Logger.init(Logger.DEBUG, new FileLogger("test.log"));
- Logger.error("Hello, world");
- Logger.warn("Hello, world");
- Logger.info("Hello, world");
- Logger.debug("Hello, world");
- }
-}
+++ /dev/null
-package org.opensrf.util;
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-
-
-public class FileLogger extends Logger {
-
- /** File to log to */
- private String filename;
-
- /**
- * FileLogger constructor
- * @param filename The path to the log file
- */
- public FileLogger(String filename) {
- this.filename = filename;
- }
-
- /**
- * Logs the mesage to a file.
- * @param level The log level
- * @param msg The mesage to log
- */
- protected synchronized void log(short level, String msg) {
- if(level > logLevel) return;
-
- BufferedWriter out = null;
- try {
- out = new BufferedWriter(new FileWriter(this.filename, true));
- out.write(formatMessage(level, msg) + "\n");
-
- } catch(Exception e) {
- /** If we are unable to write our log message, go ahead and
- * fall back to the default (stdout) logger */
- Logger.init(logLevel, new Logger());
- Logger.logByLevel(ERROR, "Unable to write to log file " + this.filename);
- Logger.logByLevel(level, msg);
- }
-
- try {
- out.close();
- } catch(Exception e) {}
- }
-}
+++ /dev/null
-package org.opensrf.util;
-import java.text.SimpleDateFormat;
-import java.text.FieldPosition;
-import java.util.Date;
-
-/**
- * Basic OpenSRF logging API. This default implementation
- * logs to stderr.
- */
-public class Logger {
-
- /** Log levels */
- public static final short ERROR = 1;
- public static final short WARN = 2;
- public static final short INFO = 3;
- public static final short DEBUG = 4;
- public static final short INTERNAL = 5;
-
- /** The global log instance */
- private static Logger instance;
- /** The global log level */
- protected static short logLevel;
-
- public Logger() {}
-
- /** Sets the global Logger instance
- * @param level The global log level.
- * @param l The Logger instance to use
- */
- public static void init(short level, Logger l) {
- instance = l;
- logLevel = level;
- }
-
- /**
- * @return The global Logger instance
- */
- public static Logger instance() {
- return instance;
- }
-
- /**
- * Logs an error message
- * @param msg The message to log
- */
- public static void error(String msg) {
- instance.log(ERROR, msg);
- }
-
- /**
- * Logs an warning message
- * @param msg The message to log
- */
- public static void warn(String msg) {
- instance.log(WARN, msg);
- }
-
- /**
- * Logs an info message
- * @param msg The message to log
- */
- public static void info(String msg) {
- instance.log(INFO, msg);
- }
-
- /**
- * Logs an debug message
- * @param msg The message to log
- */
- public static void debug(String msg) {
- instance.log(DEBUG, msg);
- }
-
- /**
- * Logs an internal message
- * @param msg The message to log
- */
- public static void internal(String msg) {
- instance.log(INTERNAL, msg);
- }
-
-
- /**
- * Appends the text representation of the log level
- * @param sb The stringbuffer to append to
- * @param level The log level
- */
- protected static void appendLevelString(StringBuffer sb, short level) {
- switch(level) {
- case DEBUG:
- sb.append("DEBG"); break;
- case INFO:
- sb.append("INFO"); break;
- case INTERNAL:
- sb.append("INT "); break;
- case WARN:
- sb.append("WARN"); break;
- case ERROR:
- sb.append("ERR "); break;
- }
- }
-
- /**
- * Formats a message for logging. Appends the current date+time
- * and the log level string.
- * @param level The log level
- * @param msg The message to log
- */
- protected static String formatMessage(short level, String msg) {
-
- StringBuffer sb = new StringBuffer();
- new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(
- new Date(), sb, new FieldPosition(0));
-
- sb.append(" [");
- appendLevelString(sb, level);
- sb.append(":");
- sb.append(Thread.currentThread().getId());
- sb.append("] ");
- sb.append(msg);
- return sb.toString();
- }
-
- /**
- * Logs a message by passing the log level explicitly
- * @param level The log level
- * @param msg The message to log
- */
- public static void logByLevel(short level, String msg) {
- instance.log(level, msg);
- }
-
- /**
- * Performs the actual logging. Subclasses should override
- * this method.
- * @param level The log level
- * @param msg The message to log
- */
- protected synchronized void log(short level, String msg) {
- if(level > logLevel) return;
- System.err.println(formatMessage(level, msg));
- }
-}
-