moved opensrf sources to fit android library project structure
authorkenstir <kenstir@gmail.com>
Wed, 18 Nov 2015 17:23:47 +0000 (12:23 -0500)
committerkenstir <kenstir@gmail.com>
Wed, 18 Nov 2015 17:23:47 +0000 (12:23 -0500)
96 files changed:
Open-ILS/src/Android/opensrf/org/opensrf/ClientSession.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/Message.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/Method.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/MethodException.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/MultiSession.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/Request.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/Result.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/ServerSession.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/Session.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/SessionException.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/Stack.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/Status.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/Sys.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/net/http/GatewayRequest.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/net/http/HttpConnection.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/net/http/HttpRequest.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/net/http/HttpRequestHandler.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPException.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPMessage.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPReader.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPSession.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/MathBench.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/TestCache.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/TestClient.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/TestConfig.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/TestJSON.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/TestLog.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/TestMultiSession.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/TestSettings.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/TestThread.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/TestXMLFlattener.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/TestXMLTransformer.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/test/TestXMPP.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/Cache.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/Config.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/ConfigException.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/FileLogger.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/JSONException.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/JSONReader.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/JSONWriter.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/Logger.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/OSRFObject.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/OSRFRegistry.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/OSRFSerializable.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/SettingsClient.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/Utils.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/XMLFlattener.java [deleted file]
Open-ILS/src/Android/opensrf/org/opensrf/util/XMLTransformer.java [deleted file]
Open-ILS/src/Android/opensrf/src/org/opensrf/ClientSession.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/Message.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/Method.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/MethodException.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/MultiSession.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/Request.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/Result.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/ServerSession.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/Session.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/SessionException.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/Stack.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/Status.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/Sys.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/GatewayRequest.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/HttpConnection.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/HttpRequest.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/HttpRequestHandler.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPException.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPMessage.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPReader.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPSession.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/MathBench.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestCache.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestClient.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestConfig.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestJSON.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestLog.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestMultiSession.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestSettings.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestThread.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestXMLFlattener.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestXMLTransformer.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestXMPP.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/Cache.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/Config.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/ConfigException.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/FileLogger.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/JSONException.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/JSONReader.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/JSONWriter.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/Logger.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/OSRFObject.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/OSRFRegistry.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/OSRFSerializable.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/SettingsClient.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/Utils.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/XMLFlattener.java [new file with mode: 0644]
Open-ILS/src/Android/opensrf/src/org/opensrf/util/XMLTransformer.java [new file with mode: 0644]

diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/ClientSession.java b/Open-ILS/src/Android/opensrf/org/opensrf/ClientSession.java
deleted file mode 100644 (file)
index 3ed4908..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-package org.opensrf;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.ArrayList;
-import java.util.Random;
-import java.util.Arrays;
-
-import org.opensrf.util.*;
-import org.opensrf.net.xmpp.*;
-
-
-/**
- * Models an OpenSRF client session.
- */
-public class ClientSession extends Session {
-
-    /** The remote service to communicate with */
-    private String service;
-    /** OpenSRF domain */
-    private String domain;
-    /** Router name */
-    private String router;
-
-    /** 
-     * original remote node.  The current remote node will change based 
-     * on server responses.  This is used to reset the remote node to 
-     * its original state.
-     */
-    private String origRemoteNode;
-    /** The next request id */
-    private int nextId;
-    /** The requests this session has sent */
-    private Map<Integer, Request> requests;
-
-    /**
-     * Creates a new client session.  Initializes the 
-     * @param service The remote service.
-     */
-    public ClientSession(String service) throws ConfigException {
-        this(service, null);
-    }
-
-    /**
-     * Creates a new client session.  Initializes the 
-     * @param service The remote service.
-     * @param locale The locale for this session.
-     */
-    public ClientSession(String service, String locale) throws ConfigException {
-        this.service = service;
-        if(locale != null) 
-            setLocale(locale);
-
-        /** generate the remote node string */
-        domain = (String) Config.global().getFirst("/domain");
-        router = Config.global().getString("/router_name");
-        setRemoteNode(router + "@" + domain + "/" + service);
-        origRemoteNode = getRemoteNode();
-
-
-        /** create a random thread */
-        long time = new Date().getTime();
-        Random rand = new Random(time);
-        setThread(rand.nextInt()+""+rand.nextInt()+""+time+Thread.currentThread().getId());
-
-        nextId = 0;
-        requests = new HashMap<Integer, Request>();
-        cacheSession();
-    }
-
-    /**
-     * Creates a new request to send to our remote service.
-     * @param method The method API name
-     * @param params The list of method parameters
-     * @return The request object.
-     */
-    public Request request(String method, List<Object> params) throws SessionException {
-        return request(new Request(this, nextId++, method, params));
-    }
-
-    /**
-     * Creates a new request to send to our remote service.
-     * @param method The method API name
-     * @param params The list of method parameters
-     * @return The request object.
-     */
-    public Request request(String method, Object[] params) throws SessionException {
-        return request(new Request(this, nextId++, method, Arrays.asList(params)));
-    }
-
-
-    /**
-     * Creates a new request to send to our remote service.
-     * @param method The method API name
-     * @return The request object.
-     */
-    public Request request(String method) throws SessionException {
-        return request(new Request(this, nextId++, method));
-    }
-
-
-    private Request request(Request req) throws SessionException {
-        if(getConnectState() != ConnectState.CONNECTED)
-            resetRemoteId();
-        requests.put(new Integer(req.getId()), req);
-        req.send();
-        return req;
-    }
-
-
-    /**
-     * Resets the remoteNode to its original state.
-     */
-    public void resetRemoteId() {
-        setRemoteNode(origRemoteNode);
-    }
-
-
-    /**
-     * Pushes a response onto the result queue of the appropriate request.
-     * @param msg The received RESULT Message
-     */
-    public void pushResponse(Message msg) {
-
-        Request req = findRequest(msg.getId());
-        if(req == null) {
-            /** LOG that we've received a result to a non-existant request */
-            System.err.println(msg.getId() +" has no corresponding request");
-            return;
-        }
-        OSRFObject payload = (OSRFObject) msg.get("payload");
-
-        /** build a result and push it onto the request's result queue */
-        req.pushResponse(
-            new Result( 
-                payload.getString("status"), 
-                payload.getInt("statusCode"),
-                payload.get("content")
-            )
-        );
-    }
-
-    public Request findRequest(int reqId) {
-        return requests.get(new Integer(reqId));
-    }
-
-    /**
-     * Removes a request for this session's request set
-     */
-    public void cleanupRequest(int reqId) {
-        requests.remove(new Integer(reqId));
-    }
-
-     public void setRequestComplete(int reqId) {
-        Request req = findRequest(reqId);
-        if(req == null) return;
-        req.setComplete();
-    }
-
-    public static Object atomicRequest(String service, String method, Object[] params) throws MethodException {
-        try {
-            ClientSession session = new ClientSession(service);
-            Request osrfRequest = session.request(method, params);
-            Result result = osrfRequest.recv(600000);
-            if(result.getStatusCode() != 200) 
-                throw new MethodException( 
-                    "Request "+service+":"+method+":"+" failed with status code " + result.getStatusCode());
-            return result.getContent();
-        } catch(Exception e) {
-            throw new MethodException(e);
-        }
-    }
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/Message.java b/Open-ILS/src/Android/opensrf/org/opensrf/Message.java
deleted file mode 100644 (file)
index 6bfe1ea..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-package org.opensrf;
-import org.opensrf.util.*;
-
-
-public class Message implements OSRFSerializable {
-
-    /** Message types */
-    public static final String REQUEST = "REQUEST";
-    public static final String STATUS = "STATUS";
-    public static final String RESULT = "RESULT";
-    public static final String CONNECT = "CONNECT";
-    public static final String DISCONNECT = "DISCONNECT";
-
-    /** Message ID.  This number is used to relate requests to responses */
-    private int id;
-    /** type of message. */
-    private String type;
-    /** message payload */
-    private Object payload;
-    /** message locale */
-    private String locale;
-
-    /** Create a registry for the osrfMessage object */
-    private static OSRFRegistry registry = 
-        OSRFRegistry.registerObject(
-            "osrfMessage", 
-            OSRFRegistry.WireProtocol.HASH, 
-            new String[] {"threadTrace", "type", "payload", "locale"});
-
-    /**
-     * @param id This message's ID
-     * @param type The type of message
-     */
-    public Message(int id, String type) {
-        setId(id);
-        setString(type);
-    }
-
-    /**
-     * @param id This message's ID
-     * @param type The type of message
-     * @param payload The message payload
-     */
-    public Message(int id, String type, Object payload) {
-        this(id, type);
-        setPayload(payload);
-    }
-
-    /**
-     * @param id This message's ID
-     * @param type The type of message
-     * @param payload The message payload
-     * @param locale The message locale
-     */
-    public Message(int id, String type, Object payload, String locale) {
-        this(id, type, payload);
-        setPayload(payload);
-        setLocale(locale);
-    }
-
-
-    public int getId() {
-        return id;
-    }   
-    public String getType() {
-        return type;
-    }
-    public Object getPayload() {
-        return payload;
-    }
-    public String getLocale() {
-        return locale;
-    }
-    public void setId(int id) {
-        this.id = id;
-    }
-    public void setString(String type) {
-        this.type = type;
-    }
-    public void setPayload(Object p) {
-        payload = p;
-    }
-    public void setLocale(String l) {
-        locale = l;
-    }
-
-    /**
-     * Implements the generic get() API required by OSRFSerializable
-     */
-    public Object get(String field) {
-        if("threadTrace".equals(field))
-            return getId();
-        if("type".equals(field))
-            return getType().toString();
-        if("payload".equals(field))
-            return getPayload();
-        if("locale".equals(field))
-            return getLocale();
-        return null;
-    }
-
-    /**
-     * @return The osrfMessage registry.
-     */
-    public OSRFRegistry getRegistry() {
-        return registry;
-    }
-}
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/Method.java b/Open-ILS/src/Android/opensrf/org/opensrf/Method.java
deleted file mode 100644 (file)
index b708d4f..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.opensrf;
-import java.util.List;
-import java.util.ArrayList;
-import org.opensrf.util.*;
-
-
-public class Method extends OSRFObject {
-
-    /** The method API name */
-    private String name;
-    /** The ordered list of method params */
-    private List<Object> params;
-
-    /** Create a registry for the osrfMethod object */
-    private static OSRFRegistry registry = 
-        OSRFRegistry.registerObject(
-            "osrfMethod", 
-            OSRFRegistry.WireProtocol.HASH, 
-            new String[] {"method", "params"});
-
-    /**
-     * @param name The method API name 
-     */
-    public Method(String name) {
-        this.name = name;
-        this.params = new ArrayList<Object>(8);
-    }
-
-    /**
-     * @param name The method API name
-     * @param params The ordered list of params
-     */
-    public Method(String name, List<Object> params) {
-        this.name = name;
-        this.params = params;
-    }
-
-    /**
-     * @return The method API name
-     */
-    public String getName() {
-        return name;
-    }
-    /**
-     * @return The ordered list of params
-     */
-    public List<Object> getParams() {
-       return params; 
-    }
-
-    /**
-     * Pushes a new param object onto the set of params 
-     * @param p The new param to add to the method.
-     */
-    public void addParam(Object p) {
-        this.params.add(p);
-    }
-
-    /**
-     * Implements the generic get() API required by OSRFSerializable
-     */
-    public Object get(String field) {
-        if("method".equals(field))
-            return getName();
-        if("params".equals(field))
-            return getParams();
-        return null;
-    }
-
-    /**
-     * @return The osrfMethod registry.
-     */
-    public OSRFRegistry getRegistry() {
-        return registry;
-    }
-
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/MethodException.java b/Open-ILS/src/Android/opensrf/org/opensrf/MethodException.java
deleted file mode 100644 (file)
index f87e638..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.opensrf;
-
-/**
- * Thrown when the server responds with a method exception.
- */
-public class MethodException extends Exception {
-    public MethodException(String info) {
-        super(info);
-    }
-    public MethodException(Throwable cause) {
-        super(cause);
-    }
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/MultiSession.java b/Open-ILS/src/Android/opensrf/org/opensrf/MultiSession.java
deleted file mode 100644 (file)
index a312aff..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-package org.opensrf;
-import java.util.List;
-import java.util.ArrayList;
-import org.opensrf.util.ConfigException;
-
-public class MultiSession {
-
-    class RequestContainer {
-        Request request;
-        int id;
-        RequestContainer(Request r) {
-            request = r; 
-        }
-    }
-
-    private boolean complete;
-    private List<RequestContainer> requests;
-    private int lastId;
-
-    public MultiSession() {
-        requests = new ArrayList<RequestContainer>();
-    }
-
-    public boolean isComplete() {
-        return complete;
-    }
-
-    public int lastId() {
-        return lastId;
-    }
-
-    /**
-     * Adds a new request to the set of requests.
-     * @param service The OpenSRF service
-     * @param method The OpenSRF method
-     * @param params The array of method params
-     * @return The request ID, which is used to map results from recv() to the original request.
-     */
-    public int request(String service, String method, Object[] params) throws SessionException, ConfigException {
-        ClientSession ses = new ClientSession(service);
-        return request(ses.request(method, params));
-    }
-
-
-    public int request(String service, String method) throws SessionException, ConfigException {
-        ClientSession ses = new ClientSession(service);
-        return request(ses.request(method));
-    }
-
-    private int request(Request req) {
-        RequestContainer c = new RequestContainer(req);
-        c.id = requests.size();
-        requests.add(c);
-        return c.id;
-    }
-
-
-    /**
-     * Calls recv on all pending requests until there is data to return.  The ID which
-     * maps the received object to the request can be retrieved by calling lastId().
-     * @param millis Number of milliseconds to wait for some data to arrive.
-     * @return The object result or null if all requests are complete
-     * @throws MethodException Thrown if no response is received within 
-     * the given timeout or the method fails.
-     */
-    public Object recv(int millis) throws MethodException {
-        if(complete) return null;
-
-        Request req = null;
-        Result res = null;
-        RequestContainer cont = null;
-
-        long duration = 0;
-        long blockTime = 100;
-
-        /* if there is only 1 outstanding request, don't poll */
-        if(requests.size() == 1)
-            blockTime = millis;
-
-        while(true) {
-            for(int i = 0; i < requests.size(); i++) {
-
-                cont = requests.get(i);
-                req = cont.request;
-
-                try {
-                    if(i == 0) {
-                        res = req.recv(blockTime);
-                    } else {
-                        res = req.recv(0);
-                    }
-                } catch(SessionException e) {
-                    throw new MethodException(e);
-                }
-
-                if(res != null) break;
-            }
-
-            if(res != null) break;
-            duration += blockTime;
-
-            if(duration >= millis) {
-                System.out.println("duration = " + duration + " millis = " + millis);
-                throw new MethodException("No request received within " + millis + " milliseconds");
-            }
-        }
-
-        if(res.getStatusCode() != 200) {
-            throw new MethodException("Request " + cont.id + " failed  with status code " + 
-                res.getStatusCode() + " and status message " + res.getStatus());
-        }
-
-        if(req.isComplete())
-            requests.remove(requests.indexOf(cont));
-
-        if(requests.size() == 0)
-            complete = true;
-
-        lastId = cont.id;
-        return res.getContent();
-    }
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/Request.java b/Open-ILS/src/Android/opensrf/org/opensrf/Request.java
deleted file mode 100644 (file)
index 2d72e2d..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-package org.opensrf;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.List;
-import java.util.Date;
-import org.opensrf.net.xmpp.XMPPException;
-import org.opensrf.util.Logger;
-
-public class Request {
-    
-    /** This request's controlling session */
-    private ClientSession session;
-    /** The method */
-    private Method method;
-    /** The ID of this request */
-    private int id;
-    /** Queue of Results */
-    private Queue<Result> resultQueue;
-    /** If true, the receive timeout for this request should be reset */
-    private boolean resetTimeout;
-
-    /** If true, the server has indicated that this request is complete. */
-    private boolean complete;
-
-    /**
-     * @param ses The controlling session for this request.
-     * @param id This request's ID.
-     * @param method The requested method.
-     */
-    public Request(ClientSession ses, int id, Method method) {
-        this.session = ses;
-        this.id = id;
-        this.method = method;
-        resultQueue = new ConcurrentLinkedQueue<Result>();
-        complete = false;
-        resetTimeout = false;
-    }
-
-    /**
-     * @param ses The controlling session for this request.
-     * @param id This request's ID.
-     * @param methodName The requested method's API name.
-     */
-    public Request(ClientSession ses, int id, String methodName) {
-        this(ses, id, new Method(methodName));
-    }
-
-    /**
-     * @param ses The controlling session for this request.
-     * @param id This request's ID.
-     * @param methodName The requested method's API name.
-     * @param params The list of request params
-     */
-    public Request(ClientSession ses, int id, String methodName, List<Object> params) {
-        this(ses, id, new Method(methodName, params));
-    }
-
-    /**
-     * Sends the request to the server.
-     */
-    public void send() throws SessionException {
-        session.send(new Message(id, Message.REQUEST, method, session.getLocale()));
-    }
-
-    /**
-     * Receives the next result for this request.  This method
-     * will wait up to the specified number of milliseconds for 
-     * a response. 
-     * @param millis Number of milliseconds to wait for a result.  If
-     * negative, this method will wait indefinitely.
-     * @return The result or null if none arrives in time
-     */
-    public Result recv(long millis) throws SessionException, MethodException {
-
-        Result result = null;
-
-        if((result = resultQueue.poll()) != null)
-            return result;
-
-        if(millis < 0 && !complete) {
-            /** wait potentially forever for a result to arrive */
-            while(!complete) {
-                session.waitForMessage(millis);
-                if((result = resultQueue.poll()) != null)
-                    return result;
-            }
-
-        } else {
-
-            while(millis >= 0 && !complete) {
-
-                /** wait up to millis milliseconds for a result.  waitForMessage() 
-                 * will return if a response to any request arrives, so we keep track
-                 * of how long we've been waiting in total for a response to 
-                 * this request */
-
-                long start = new Date().getTime();
-                session.waitForMessage(millis);
-                millis -= new Date().getTime() - start;
-                if((result = resultQueue.poll()) != null)
-                    return result;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Pushes a result onto the result queue 
-     * @param result The result to push
-     */
-    public void pushResponse(Result result) {
-        resultQueue.offer(result);
-    }
-
-    /**
-     * @return This request's ID
-     */
-    public int getId() {
-        return id;
-    }
-
-    /**
-     * Removes this request from the controlling session's request set
-     */
-    public void cleanup() {
-        session.cleanupRequest(id);
-    }
-
-    /** Sets this request as complete */
-    public void setComplete() {
-        complete = true;
-    }
-
-    public boolean isComplete() {
-        return complete;
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/Result.java b/Open-ILS/src/Android/opensrf/org/opensrf/Result.java
deleted file mode 100644 (file)
index 80b71dd..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.opensrf;
-import org.opensrf.util.*;
-
-
-/**
- * Models a single result from a method request.
- */
-public class Result implements OSRFSerializable {
-
-    /** Method result content */
-    private Object content;
-    /** Name of the status */
-    private String status;
-    /** Status code number */
-    private int statusCode;
-
-
-    /** Register this object */
-    private static OSRFRegistry registry = 
-        OSRFRegistry.registerObject(
-            "osrfResult", 
-            OSRFRegistry.WireProtocol.HASH, 
-            new String[] {"status", "statusCode", "content"});
-
-
-    /**
-     * @param status The status message for this result
-     * @param statusCode The status code
-     * @param content The content of the result
-     */
-    public Result(String status, int statusCode, Object content) {
-        this.status = status;
-        this.statusCode = statusCode;
-        this.content = content;
-    }
-    
-    /**
-     * Get status.
-     * @return status as String.
-     */
-    public String getStatus() {
-        return status;
-    }
-    
-    /**
-     * Set status.
-     * @param status the value to set.
-     */
-    public void setStatus(String status) {
-        this.status = status;
-    }
-    
-    /**
-     * Get statusCode.
-     * @return statusCode as int.
-     */
-    public int getStatusCode() {
-        return statusCode;
-    }
-    
-    /**
-     * Set statusCode.
-     * @param statusCode the value to set.
-     */
-    public void setStatusCode(int statusCode) {
-        this.statusCode = statusCode;
-    }
-    
-    /**
-     * Get content.
-     * @return content as Object.
-     */
-    public Object getContent() {
-        return content;
-    }
-    
-    /**
-     * Set content.
-     * @param content the value to set.
-     */
-    public void setContent(Object content) {
-        this.content = content;
-    }
-
-    /**
-     * Implements the generic get() API required by OSRFSerializable
-     */
-    public Object get(String field) {
-        if("status".equals(field))
-            return getStatus();
-        if("statusCode".equals(field))
-            return getStatusCode();
-        if("content".equals(field))
-            return getContent();
-        return null;
-    }
-
-    /**
-     * @return The osrfMethod registry.
-     */
-    public OSRFRegistry getRegistry() {
-        return registry;
-    }
-
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/ServerSession.java b/Open-ILS/src/Android/opensrf/org/opensrf/ServerSession.java
deleted file mode 100644 (file)
index 62e5133..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.opensrf;
-
-/**
- * Models an OpenSRF server session.
- */
-public class ServerSession extends Session {
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/Session.java b/Open-ILS/src/Android/opensrf/org/opensrf/Session.java
deleted file mode 100644 (file)
index 15fd352..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-package org.opensrf;
-import org.opensrf.util.JSONWriter;
-import org.opensrf.net.xmpp.*;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Arrays;
-
-public abstract class Session {
-
-    /** Represents the different connection states for a session */
-    public enum ConnectState {
-        DISCONNECTED,
-        CONNECTING,
-        CONNECTED
-    };
-
-    /** local cache of existing sessions */
-    private static Map<String, Session> 
-        sessionCache = new HashMap<String, Session>();
-
-    /** the current connection state */
-    private ConnectState connectState;
-
-    /** The address of the remote party we are communicating with */
-    private String remoteNode;
-
-    /** Session locale */
-    protected String locale;
-    /** Default session locale */
-    protected static String defaultLocale = "en-US";
-
-    /** 
-     * The thread is used to link messages to a given session. 
-     * In other words, each session has a unique thread, and all messages 
-     * in that session will carry this thread around as an indicator.
-     */
-    private String thread;
-
-    public Session() {
-        connectState = ConnectState.DISCONNECTED;
-    }
-    
-    /**
-     * Sends a Message to our remoteNode.
-     */
-    public void send(Message omsg) throws SessionException {
-
-        /** construct the XMPP message */
-        XMPPMessage xmsg = new XMPPMessage();
-        xmsg.setTo(remoteNode);
-        xmsg.setThread(thread);
-        xmsg.setBody(new JSONWriter(Arrays.asList(new Message[] {omsg})).write());
-
-        try {
-            XMPPSession.getThreadSession().send(xmsg);
-        } catch(XMPPException e) {
-            connectState = ConnectState.DISCONNECTED;
-            throw new SessionException("Error sending message to " + remoteNode, e);
-        }
-    }
-
-    /**
-     * Waits for a message to arrive over the network and passes
-     * all received messages to the stack for processing
-     * @param millis The number of milliseconds to wait for a message to arrive
-     */
-    public static void waitForMessage(long millis) throws SessionException, MethodException {
-        try {
-            Stack.processXMPPMessage(
-                XMPPSession.getThreadSession().recv(millis));
-        } catch(XMPPException e) {
-            throw new SessionException("Error waiting for message", e);
-        }
-    }
-
-    /**
-     * Removes this session from the session cache.
-     */
-    public void cleanup() {
-        sessionCache.remove(thread);
-    }
-
-    /**
-     * Searches for the cached session with the given thread.
-     * @param thread The session thread.
-     * @return The found session or null.
-     */
-    public static Session findCachedSession(String thread) {
-        return sessionCache.get(thread);
-    }
-
-    /**
-     * Puts this session into session cache.
-     */
-    protected void cacheSession() {
-        sessionCache.put(thread, this);
-    }
-
-    /**
-     * Sets the remote address
-     * @param nodeName The name of the remote node.
-     */
-    public void setRemoteNode(String nodeName) {
-        remoteNode = nodeName;
-    }
-    /**
-     * @return The remote node
-     */
-    public String getRemoteNode() {
-        return remoteNode;
-    }
-
-
-    /**
-     * Get thread.
-     * @return thread as String.
-     */
-    public String getThread() {
-        return thread;
-    }
-    
-    /**
-     * Set thread.
-     * @param thread the value to set.
-     */
-    public void setThread(String thread) {
-        this.thread = thread;
-    }
-
-    /**
-     * Get locale.
-     * @return locale as String.
-     */
-    public String getLocale() {
-        if(locale == null)
-            return defaultLocale;
-        return locale;
-    }
-    
-    /**
-     * Set locale.
-     * @param locale the value to set.
-     */
-    public void setLocale(String locale) {
-        this.locale = locale;
-    }
-
-    /**
-     * Get defaultLocale.
-     * @return defaultLocale as String.
-     */
-    public String getDefaultLocale() {
-        return defaultLocale;
-    }
-    
-    /**
-     * Set defaultLocale.
-     * @param defaultLocale the value to set.
-     */
-    public void setDefaultLocale(String defaultLocale) {
-        this.defaultLocale = defaultLocale;
-    }
-
-    
-    /**
-     * Get connectState.
-     * @return connectState as ConnectState.
-     */
-    public ConnectState getConnectState() {
-        return connectState;
-    }
-    
-    /**
-     * Set connectState.
-     * @param connectState the value to set.
-     */
-    public void setConnectState(ConnectState connectState) {
-        this.connectState = connectState;
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/SessionException.java b/Open-ILS/src/Android/opensrf/org/opensrf/SessionException.java
deleted file mode 100644 (file)
index bd90a76..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.opensrf;
-/**
- * Used by sessions to indicate communication errors
- */
-public class SessionException extends Exception {
-    public SessionException(String info) {
-        super(info);
-    }
-    public SessionException(String info, Throwable cause) {
-        super(info, cause);
-    }
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/Stack.java b/Open-ILS/src/Android/opensrf/org/opensrf/Stack.java
deleted file mode 100644 (file)
index 3e7e606..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-package org.opensrf;
-import org.opensrf.net.xmpp.XMPPMessage;
-import org.opensrf.util.*;
-import java.util.Date;
-import java.util.List;
-import java.util.Iterator;
-
-
-public class Stack {
-
-    public static void processXMPPMessage(XMPPMessage msg) throws MethodException {
-
-        if(msg == null) return;
-
-        //System.out.println(msg.getBody());
-
-        /** fetch this session from the cache */
-        Session ses = Session.findCachedSession(msg.getThread());
-
-        if(ses == null) {
-            /** inbound client request, create a new server session */
-            return;
-        }
-
-        /** parse the JSON message body, which should result in a list of OpenSRF messages */
-        List msgList; 
-
-        try {
-            msgList = new JSONReader(msg.getBody()).readArray();
-        } catch(JSONException e) {
-            /** XXX LOG error */
-            e.printStackTrace();
-            return;
-        }
-
-        Iterator itr = msgList.iterator();
-
-        OSRFObject obj = null;
-        long start = new Date().getTime();
-
-        /** cycle through the messages and push them up the stack */
-        while(itr.hasNext()) {
-
-            /** Construct a Message object from the parsed generic OSRFObject */
-            obj = (OSRFObject) itr.next();
-
-            processOSRFMessage(
-                ses, 
-                new Message(
-                    obj.getInt("threadTrace"),
-                    obj.getString("type"),
-                    obj.get("payload")
-                )
-            );
-        }
-
-        /** LOG the duration */
-    }
-
-    private static void processOSRFMessage(Session ses, Message msg) throws MethodException {
-
-        Logger.debug("received id=" + msg.getId() + 
-            " type=" + msg.getType() + " payload=" + msg.getPayload());
-
-        if( ses instanceof ClientSession ) 
-            processResponse((ClientSession) ses, msg);
-        else
-            processRequest((ServerSession) ses, msg);
-    }
-
-    /** 
-     * Process a server response
-     */
-    private static void processResponse(ClientSession session, Message msg) throws MethodException {
-        String type = msg.getType();
-
-        if(msg.RESULT.equals(type)) {
-            session.pushResponse(msg);
-            return;
-        }
-
-        if(msg.STATUS.equals(type)) {
-
-            OSRFObject obj = (OSRFObject) msg.getPayload();
-            Status stat = new Status(obj.getString("status"), obj.getInt("statusCode"));
-            int statusCode = stat.getStatusCode();
-            String status = stat.getStatus();
-
-            switch(statusCode) {
-                case Status.COMPLETE:
-                    session.setRequestComplete(msg.getId());
-                    break;
-                case Status.NOTFOUND: 
-                    session.setRequestComplete(msg.getId());
-                    throw new MethodException(status);
-            }
-        }
-    }
-
-    /**
-     * Process a client request
-     */
-    private static void processRequest(ServerSession session, Message msg) {
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/Status.java b/Open-ILS/src/Android/opensrf/org/opensrf/Status.java
deleted file mode 100644 (file)
index 8026c7b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.opensrf;
-import org.opensrf.util.*;
-
-public class Status {
-
-    public static final int CONTINUE            = 100;
-    public static final int OK                  = 200;
-    public static final int ACCEPTED            = 202;
-    public static final int COMPLETE            = 205;
-    public static final int REDIRECTED          = 307;
-    public static final int EST                 = 400;
-    public static final int STATUS_UNAUTHORIZED = 401;
-    public static final int FORBIDDEN           = 403;
-    public static final int NOTFOUND            = 404;
-    public static final int NOTALLOWED          = 405;
-    public static final int TIMEOUT             = 408;
-    public static final int EXPFAILED           = 417;
-    public static final int INTERNALSERVERERROR = 500;
-    public static final int NOTIMPLEMENTED      = 501;
-    public static final int VERSIONNOTSUPPORTED = 505;
-
-    private OSRFRegistry registry = OSRFRegistry.registerObject(
-        "osrfConnectStatus",
-        OSRFRegistry.WireProtocol.HASH,
-        new String[] {"status", "statusCode"});
-
-    /** The name of the status */
-    String status;
-    /** The status code */
-    int statusCode;
-
-    public Status(String status, int statusCode) {
-        this.status = status;
-        this.statusCode = statusCode;
-    }
-
-    public int getStatusCode() {
-        return statusCode;
-    }
-    public String getStatus() {
-        return status;
-    }
-
-    /**
-     * Implements the generic get() API required by OSRFSerializable
-     */
-    public Object get(String field) {
-        if("status".equals(field))
-            return getStatus();
-        if("statusCode".equals(field))
-            return new Integer(getStatusCode());
-        return null;
-    }
-
-    /**
-     * @return The osrfMessage registry.
-     */
-    public OSRFRegistry getRegistry() {
-        return registry;
-    }
-}
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/Sys.java b/Open-ILS/src/Android/opensrf/org/opensrf/Sys.java
deleted file mode 100644 (file)
index d65f8a4..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-package org.opensrf;
-
-import org.opensrf.util.*;
-import org.opensrf.net.xmpp.*;
-import java.util.Random;
-import java.util.Date;
-import java.net.InetAddress;
-
-
-public class Sys {
-
-    private static void initLogger(Config config) {
-        if(Logger.instance() == null) {
-            try {
-                String logFile = config.getString("/logfile");
-                int logLevel = config.getInt("/loglevel");
-                Logger.init( (short) config.getInt("/loglevel"), new FileLogger(logFile));
-                /** add syslog support... */
-            } catch(Exception e) {
-                /* by default, log to stderr at WARN level */
-                Logger.init(Logger.WARN, new Logger()); 
-            }
-        }
-    }
-
-    /**
-     * Connects to the OpenSRF network so that client sessions may communicate.
-     * @param configFile The OpenSRF config file 
-     * @param configContext Where in the XML document the config chunk lives.  This
-     * allows an OpenSRF client config chunk to live in XML files where other config
-     * information lives.
-     */
-    public static void bootstrapClient(String configFile, String configContext) 
-            throws ConfigException, SessionException  {
-
-
-        /** see if the current thread already has a connection */
-        XMPPSession existing = XMPPSession.getThreadSession();
-        if(existing != null && existing.connected())
-            return;
-
-        /** create the config parser */
-        Config config = new Config(configContext);
-        config.parse(configFile);
-        Config.setConfig(config); /* set this as the global config */
-
-        initLogger(config);
-
-        /** Collect the network connection info from the config */
-        String username = config.getString("/username");
-        String passwd = config.getString("/passwd");
-        String host = (String) config.getFirst("/domain");
-        int port = config.getInt("/port");
-
-
-        /** Create a random login resource string */
-        String res = "java_";
-        try {
-            res += InetAddress.getLocalHost().getHostAddress();
-        } catch(java.net.UnknownHostException e) {}
-        res += "_"+Math.abs(new Random(new Date().getTime()).nextInt()) 
-            + "_t"+ Thread.currentThread().getId();
-
-
-
-        try {
-
-            /** Connect to the Jabber network */
-            Logger.info("attempting to create XMPP session "+username+"@"+host+"/"+res);
-            XMPPSession xses = new XMPPSession(host, port);
-            xses.connect(username, passwd, res);
-            XMPPSession.setThreadSession(xses);
-
-        } catch(XMPPException e) {
-            throw new SessionException("Unable to bootstrap client", e);
-        }
-    }
-
-    /**
-     * Shuts down the connection to the opensrf network
-     */
-    public static void shutdown() {
-        XMPPSession.getThreadSession().disconnect();
-    }
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/net/http/GatewayRequest.java b/Open-ILS/src/Android/opensrf/org/opensrf/net/http/GatewayRequest.java
deleted file mode 100644 (file)
index 61d7306..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-package org.opensrf.net.http;
-
-import android.util.Log;
-import org.json.JSONObject;
-import org.opensrf.*;
-import org.opensrf.util.*;
-
-import java.io.IOException;
-import java.io.BufferedInputStream;
-import java.io.OutputStreamWriter;
-import java.io.InputStream;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URI;
-import java.net.HttpURLConnection;
-import java.lang.StringBuffer;
-import java.util.List;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-public class GatewayRequest extends HttpRequest {
-
-    private boolean readComplete;
-    private String TAG = GatewayRequest.class.getName();
-
-    public GatewayRequest(HttpConnection conn, String service, Method method) {
-        super(conn, service, method);
-        readComplete = false;
-    }
-
-    public GatewayRequest send() {
-        try {
-
-            String postData = compilePostData(service, method);
-
-            urlConn = (HttpURLConnection) httpConn.url.openConnection();
-            urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
-            urlConn.setDoInput(true);
-            urlConn.setDoOutput(true);
-
-            
-            
-            OutputStreamWriter wr = new OutputStreamWriter(urlConn.getOutputStream());
-            wr.write(postData);
-            wr.flush();
-            wr.close();
-
-        } catch (java.io.IOException ex) {
-            failed = true;
-            failure = ex;
-        }
-
-        return this;
-    }
-
-    public Object recv() {
-
-        if (readComplete) 
-            return nextResponse();
-
-        try {
-
-            InputStream netStream = new BufferedInputStream(urlConn.getInputStream());
-            StringBuffer readBuf = new StringBuffer();
-
-            int bytesRead = 0;
-            byte[] buffer = new byte[1024];
-
-            while ((bytesRead = netStream.read(buffer)) != -1) {
-                readBuf.append(new String(buffer, 0, bytesRead));
-            }
-            
-            netStream.close();
-            urlConn = null;
-
-            Map<String,?> result = null;
-
-            //System.out.println("osrf: Received " +  readBuf.toString());
-            //Log.d(TAG, "received:" +  readBuf.toString());
-            try {
-                result = (Map<String, ?>) new JSONReader(readBuf.toString()).readObject();
-            } catch (org.opensrf.util.JSONException ex) {
-                ex.printStackTrace();
-                return null;
-            }
-            //System.out.println("osrf: Converted object " + result);
-            Log.d(TAG, "service:" + this.service
-                    + " method:" + this.method.getName()
-                    + " result:" + new JSONObject(result).toString());
-            String status = result.get("status").toString();
-            if (!"200".equals(status)) {
-                failed = true;
-                // failure = <some new exception>
-            }
-
-             // gateway always returns a wrapper array with the full results set
-             responseList = (List) result.get("payload"); 
-
-            // System.out.println("Response list : " + responseList);
-        } catch (java.io.IOException ex) { 
-            failed = true;
-            failure = ex;
-        }
-
-        readComplete = true;
-        return nextResponse();
-    }
-
-    private String compilePostData(String service, Method method) {
-        URI uri = null;
-        StringBuffer postData = new StringBuffer();
-
-        postData.append("service=");
-        postData.append(service);
-        postData.append("&method=");
-        postData.append(method.getName());
-
-        List params = method.getParams();
-        Iterator itr = params.iterator();
-
-        while (itr.hasNext()) {
-            postData.append("&param=");
-            postData.append(new JSONWriter(itr.next()).write());
-        }
-
-        try {
-            // not using URLEncoder because it replaces ' ' with '+'.
-            uri = new URI("http", "", null, postData.toString(), null);
-        } catch (java.net.URISyntaxException ex) {
-            ex.printStackTrace(); 
-        }
-
-        return uri.getRawQuery();
-    }
-}
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/net/http/HttpConnection.java b/Open-ILS/src/Android/opensrf/org/opensrf/net/http/HttpConnection.java
deleted file mode 100644 (file)
index 32fdebc..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.opensrf.net.http;
-
-import java.net.URL;
-import java.net.MalformedURLException;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import org.opensrf.*;
-import org.opensrf.util.*;
-
-
-/**
- * Manages connection parameters and thread limiting for opensrf json gateway connections.
- */
-
-public class HttpConnection {
-
-    /** Compiled URL object */
-    protected URL url;
-    /** Number of threads currently communicating with the server */
-    protected int activeThreads;
-    /** Queue of pending async requests */
-    protected Queue<HttpRequest> pendingThreadQueue;
-    /** maximum number of actively communicating threads allowed */
-    protected int maxThreads = 10;
-
-    public HttpConnection(String fullUrl) throws java.net.MalformedURLException {
-        activeThreads = 0;
-        pendingThreadQueue = new ConcurrentLinkedQueue();
-        url = new URL(fullUrl);
-    }
-
-    public int getMaxThreads() {
-        return maxThreads;
-    }
-
-    /** 
-     * Set the maximum number of actively communicating threads allowed 
-     */
-    public void setMaxThreads(int max) {
-        maxThreads = max;
-    }
-
-    /**
-     * Launches or queues an asynchronous request.
-     *
-     * If the maximum active thread count has not been reached,
-     * start a new thread and use it to send and receive the request.
-     * The response is passed to the request's HttpRequestHandler
-     * onComplete().  After complete, if the number of active threads
-     * is still lower than the max, one request will be pulled (if 
-     * present) from the async queue and fired.
-     *
-     * If there are too many active threads, the main request is
-     * pushed onto the async queue for later processing
-     */
-    protected void manageAsyncRequest(final HttpRequest request) {
-
-        if (activeThreads >= maxThreads) {
-            pendingThreadQueue.offer(request);
-            return;
-        }
-
-        activeThreads++;
-
-         //Send the request receive the response, fire off the next 
-         //thread if necessary, then pass the result to the handler
-        Runnable r = new Runnable() {
-            public void run() {
-
-                Object response;
-                request.send();
-
-                while ((response = request.recv()) != null) {
-                    if (request.handler != null) 
-                        request.handler.onResponse(request, response);
-                }
-
-                if (request.handler != null)
-                    request.handler.onComplete(request);
-
-                activeThreads--;
-
-                if (activeThreads < maxThreads) {
-                    try {
-                        manageAsyncRequest(pendingThreadQueue.remove());
-                    } catch (java.util.NoSuchElementException ex) {
-                        // may have been gobbled by another thread
-                    }
-                }
-            }
-        };
-
-        new Thread(r).start();
-    }
-}
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/net/http/HttpRequest.java b/Open-ILS/src/Android/opensrf/org/opensrf/net/http/HttpRequest.java
deleted file mode 100644 (file)
index 8af4623..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-package org.opensrf.net.http;
-import org.opensrf.*;
-import org.opensrf.util.*;
-
-import java.util.List;
-import java.util.LinkedList;
-import java.net.HttpURLConnection;
-
-public abstract class HttpRequest {
-
-    protected String service;
-    protected Method method;
-    protected HttpURLConnection urlConn;
-    protected HttpConnection httpConn;
-    protected HttpRequestHandler handler;
-    protected List<Object> responseList;
-    protected Exception failure;
-    protected boolean failed;
-    protected boolean complete;
-
-    public HttpRequest() {
-        failed = false;
-        complete = false;
-        handler = null;
-        urlConn = null;
-    }
-
-    public HttpRequest(HttpConnection conn, String service, Method method) {
-        this();
-        this.httpConn = conn;
-        this.service = service;
-        this.method = method;
-    }
-
-    public void sendAsync(final HttpRequestHandler handler) {
-        this.handler = handler;
-        httpConn.manageAsyncRequest(this);
-    }
-
-    protected void pushResponse(Object response) {
-        if (responseList == null)
-            responseList = new LinkedList<Object>();
-        responseList.add(response);
-    }
-
-    protected List responses() {
-        return responseList;
-    }
-    
-    protected Object nextResponse() {
-        if (complete || failed) return null;
-        if (responseList.size() > 0)
-            return responseList.remove(0);
-        return null;
-    }
-
-    public Exception getFailure() {
-        return failure;
-    }
-
-    public abstract HttpRequest send();
-
-    public abstract Object recv();
-    
-    public boolean failed(){
-       return failed;
-    }
-}
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/net/http/HttpRequestHandler.java b/Open-ILS/src/Android/opensrf/org/opensrf/net/http/HttpRequestHandler.java
deleted file mode 100644 (file)
index 9c0f9e5..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.opensrf.net.http;
-
-import java.util.List;
-
-/*
- * Handler for async gateway responses.
- */
-public abstract class HttpRequestHandler {
-
-    /**
-     * Called when all responses have been received.
-     *
-     * If discardResponses() returns true, will be passed null.
-     */
-    public void onComplete(HttpRequest request) {
-    }
-
-    /**
-     * Called with each response received from the server.
-     * 
-     * @param payload the value returned from the server.
-     */
-    public void onResponse(HttpRequest request, Object response) {
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPException.java b/Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPException.java
deleted file mode 100644 (file)
index 8c20ab7..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.opensrf.net.xmpp;
-
-/**
- * Used for XMPP stream/authentication errors
- */
-public class XMPPException extends Exception {
-    public XMPPException(String info) {
-        super(info);
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPMessage.java b/Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPMessage.java
deleted file mode 100644 (file)
index b6e2c76..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-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("&lt;");
-                    break;
-                case '>': 
-                    sb.append("&gt;");
-                    break;
-                case '&': 
-                    sb.append("&amp;");
-                    break;
-                default:
-                    sb.append(c);
-            }
-        }
-    }
-}
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPReader.java b/Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPReader.java
deleted file mode 100644 (file)
index 406298a..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-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;
-        }
-    }
-}
-
-
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPSession.java b/Open-ILS/src/Android/opensrf/org/opensrf/net/xmpp/XMPPSession.java
deleted file mode 100644 (file)
index f9be7d2..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-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) {}
-    }
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/MathBench.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/MathBench.java
deleted file mode 100644 (file)
index b6e67f9..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.opensrf.test;
-import org.opensrf.*;
-import org.opensrf.util.*;
-import java.util.Date;
-import java.util.List;
-import java.util.ArrayList;
-import java.io.PrintStream;
-
-
-public class MathBench {
-
-    public static void main(String args[]) throws Exception {
-
-        PrintStream out = System.out;
-
-        if(args.length < 2) {
-            out.println("usage: java org.opensrf.test.MathBench <osrfConfig> <numIterations>");
-            return;
-        }
-
-        /** connect to the opensrf network */
-        Sys.bootstrapClient(args[0], "/config/opensrf");
-
-        /** how many iterations */
-        int count = Integer.parseInt(args[1]);
-
-        /** create the client session */
-        ClientSession session = new ClientSession("opensrf.math");
-
-        /** params are 1,2 */
-        List<Object> params = new ArrayList<Object>();
-        params.add(new Integer(1));
-        params.add(new Integer(2));
-
-        Request request;
-        Result result;
-        long start;
-        double total = 0;
-
-        for(int i = 0; i < count; i++) {
-
-            start = new Date().getTime();
-
-            /** create (and send) the request */
-            request = session.request("add", params);
-
-            /** wait up to 3 seconds for a response */
-            result = request.recv(3000);
-
-            /** collect the round-trip time */
-            total += new Date().getTime() - start;
-
-            if(result.getStatusCode() == Status.OK) {
-                out.print("+");
-            } else {
-                out.println("\nrequest failed");
-                out.println("status = " + result.getStatus());
-                out.println("status code = " + result.getStatusCode());
-            }
-
-            /** remove this request from the session's request set */
-            request.cleanup();
-
-            if((i+1) % 100 == 0) /** print 100 responses per line */
-                out.println(" [" + (i+1) + "]");
-        }
-
-        out.println("\nAverage request time is " + (total/count) + " ms");
-        
-        /** remove this session from the global session cache */
-        session.cleanup();
-
-        /** disconnect from the opensrf network */
-        Sys.shutdown();
-    }
-}
-
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/TestCache.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/TestCache.java
deleted file mode 100644 (file)
index d555444..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.opensrf.test;
-import org.opensrf.util.Cache;
-
-public class TestCache {
-    public static void main(String args[]) throws Exception {
-
-        /**
-         * args is a list of string like so:  server:port server2:port server3:port ...
-         */
-
-        Cache.initCache(args);
-        Cache cache = new Cache();
-
-        cache.set("key1", "HI, MA!");
-        cache.set("key2", "HI, MA! 2");
-        cache.set("key3", "HI, MA! 3");
-
-        System.out.println("got key1 = " + (String) cache.get("key1"));
-        System.out.println("got key2 = " + (String) cache.get("key2"));
-        System.out.println("got key3 = " + (String) cache.get("key3"));
-    }
-}
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/TestClient.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/TestClient.java
deleted file mode 100644 (file)
index a1136cd..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.opensrf.test;
-import org.opensrf.*;
-import org.opensrf.util.*;
-import java.util.Map;
-import java.util.Date;
-import java.util.List;
-import java.util.ArrayList;
-import java.io.PrintStream;
-
-public class TestClient {
-
-    public static void main(String args[]) throws Exception {
-
-        /** which opensrf service are we sending our request to */
-        String service; 
-        /** which opensrf method we're calling */
-        String method;
-        /** method params, captures from command-line args */
-        List<Object> params;
-        /** knows how to read JSON */
-        JSONReader reader;
-        /** opensrf request */
-        Request request;
-        /** request result */
-        Result result;
-        /** start time for the request */
-        long start;
-        /** for brevity */
-        PrintStream out = System.out;
-
-        if(args.length < 3) {
-            out.println( "usage: org.opensrf.test.TestClient "+
-                "<osrfConfigFile> <service> <method> [<JSONparam1>, <JSONparam2>]");
-            return;
-        }
-
-        /** connect to the opensrf network,  default config context 
-         * for opensrf_core.xml is /config/opensrf */
-        Sys.bootstrapClient(args[0], "/config/opensrf");
-
-        /* grab the server, method, and any params from the command line */
-        service = args[1];
-        method = args[2];
-        params = new ArrayList<Object>();
-        for(int i = 3; i < args.length; i++) 
-            params.add(new JSONReader(args[i]).read());
-
-
-        /** build the client session */
-        ClientSession session = new ClientSession(service);
-
-        /** kick off the timer */
-        start = new Date().getTime();
-
-        /** Create the request object from the session, method and params */
-        request = session.request(method, params);
-
-        while( (result = request.recv(60000)) != null ) { 
-            /** loop over the results and print the JSON version of the content */
-
-            if(result.getStatusCode() != 200) { 
-                /** make sure the request succeeded */
-                out.println("status = " + result.getStatus());
-                out.println("status code = " + result.getStatusCode());
-                continue;
-            }
-
-            /** JSON-ify the resulting object and print it */
-            out.println("\nresult JSON: " + new JSONWriter(result.getContent()).write());
-        }
-        
-        /** How long did the request take? */
-        out.println("Request round trip took: " + (new Date().getTime() - start) + " ms.");
-
-        Sys.shutdown();
-    }
-}
-
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/TestConfig.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/TestConfig.java
deleted file mode 100644 (file)
index f65a84f..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-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]));
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/TestJSON.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/TestJSON.java
deleted file mode 100644 (file)
index b19d408..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.opensrf.test;
-
-import org.opensrf.*;
-import org.opensrf.util.*;
-import java.util.*;
-
-public class TestJSON {
-
-    public static void main(String args[]) throws Exception {
-        
-        Map<String,Object> map = new HashMap<String,Object>();
-        map.put("key1", "value1");
-        map.put("key2", "value2");
-        map.put("key3", "value3");
-        map.put("key4", "athe\u0301s");
-        map.put("key5", null);
-
-        List<Object> list = new ArrayList<Object>(16);
-        list.add(new Integer(1));
-        list.add(new Boolean(true));
-        list.add("WATER");
-        list.add(null);
-        map.put("key6", list);
-
-        System.out.println(new JSONWriter(map).write() + "\n");
-
-        String[] fields = {"isnew", "name", "shortname", "ill_address"};
-        OSRFRegistry.registerObject("aou", OSRFRegistry.WireProtocol.ARRAY, fields);
-
-        OSRFObject obj = new OSRFObject(OSRFRegistry.getRegistry("aou"));
-        obj.put("name", "athens clarke county");
-        obj.put("ill_address", new Integer(1));
-        obj.put("shortname", "ARL-ATH");
-
-        map.put("key7", obj);
-        list.add(obj);
-        System.out.println(new JSONWriter(map).write() + "\n");
-
-
-        Message m = new Message(1, Message.REQUEST);
-        Method method = new Method("opensrf.settings.host_config.get");
-        method.addParam("app07.dev.gapines.org");
-        m.setPayload(method);
-
-        String s = new JSONWriter(m).write();
-        System.out.println(s + "\n");
-
-        Object o = new JSONReader(s).read();
-        System.out.println("Read+Wrote: " + new JSONWriter(o).write());
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/TestLog.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/TestLog.java
deleted file mode 100644 (file)
index 1d60242..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-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");
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/TestMultiSession.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/TestMultiSession.java
deleted file mode 100644 (file)
index bb0f1a1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.opensrf.test;
-import org.opensrf.*;
-import org.opensrf.util.*;
-
-public class TestMultiSession {
-    public static void main(String[] args) {
-        try {
-            String config = args[0];
-
-            Sys.bootstrapClient(config, "/config/opensrf");
-            MultiSession ses = new MultiSession();
-
-            for(int i = 0; i < 40; i++) {
-                ses.request("opensrf.settings", "opensrf.system.time");
-            }
-
-            while(!ses.isComplete()) 
-                System.out.println("result = " + ses.recv(5000) + " and id = " + ses.lastId());
-
-            System.out.println("done");
-            Sys.shutdown();
-        } catch(Exception e) {
-            e.printStackTrace();
-        }
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/TestSettings.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/TestSettings.java
deleted file mode 100644 (file)
index 116bbe1..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.opensrf.test;
-import org.opensrf.*;
-import org.opensrf.util.*;
-
-public class TestSettings {
-    public static void main(String args[]) throws Exception {
-        Sys.bootstrapClient(args[0], "/config/opensrf");
-        SettingsClient client = SettingsClient.instance();
-        String lang = client.getString("/apps/opensrf.settings/language");
-        String impl = client.getString("/apps/opensrf.settings/implementation");
-        System.out.println("opensrf.settings language = " + lang);
-        System.out.println("opensrf.settings implementation = " + impl);
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/TestThread.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/TestThread.java
deleted file mode 100644 (file)
index bb4cf06..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.opensrf.test;
-import org.opensrf.*;
-import org.opensrf.util.*;
-import java.util.Map;
-import java.util.Date;
-import java.util.List;
-import java.util.ArrayList;
-import java.io.PrintStream;
-
-/**
- * Connects to the opensrf network once per thread and runs
- * and runs a series of request acccross all launched threads.
- * The purpose is to verify that the java threaded client api 
- * is functioning as expected
- */
-public class TestThread implements Runnable {
-
-    String args[];
-
-    public TestThread(String args[]) {
-        this.args = args;
-    }
-
-    public void run() {
-
-        try {
-
-            Sys.bootstrapClient(args[0], "/config/opensrf");
-            ClientSession session = new ClientSession(args[3]);
-    
-            List params = new ArrayList<Object>();
-            for(int i = 5; i < args.length; i++) 
-                params.add(new JSONReader(args[3]).read());
-    
-            for(int i = 0; i < Integer.parseInt(args[2]); i++) {
-                System.out.println("thread " + Thread.currentThread().getId()+" sending request " + i);
-                Request request = session.request(args[4], params);
-                Result result = request.recv(3000);
-                if(result != null) {
-                    System.out.println("thread " + Thread.currentThread().getId()+ 
-                        " got result JSON: " + new JSONWriter(result.getContent()).write());
-                } else {
-                    System.out.println("* thread " + Thread.currentThread().getId()+ " got NO result");
-                }
-            }
-    
-            Sys.shutdown();
-        } catch(Exception e) {
-            System.err.println(e);
-        }
-    }
-
-    public static void main(String args[]) throws Exception {
-
-        if(args.length < 5) {
-            System.out.println( "usage: org.opensrf.test.TestClient "+
-                "<osrfConfigFile> <numthreads> <numiter> <service> <method> [<JSONparam1>, <JSONparam2>]");
-            return;
-        }
-
-        int numThreads = Integer.parseInt(args[1]);
-        for(int i = 0; i < numThreads; i++) 
-            new Thread(new TestThread(args)).start();
-    }
-}
-
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/TestXMLFlattener.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/TestXMLFlattener.java
deleted file mode 100644 (file)
index c1fa394..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.opensrf.test;
-import org.opensrf.util.XMLFlattener;
-import java.io.FileInputStream;
-
-public class TestXMLFlattener {
-    public static void main(String args[]) throws Exception {
-        FileInputStream fis = new FileInputStream(args[0]);
-        XMLFlattener f = new XMLFlattener(fis);
-        System.out.println(f.read());
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/TestXMLTransformer.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/TestXMLTransformer.java
deleted file mode 100644 (file)
index 9768372..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.opensrf.test;
-import org.opensrf.util.XMLTransformer;
-import java.io.File;
-
-public class TestXMLTransformer {
-    /**
-     * arg[0] path to an XML file
-     * arg[1] path to the XSL file to apply
-     */
-    public static void main(String[] args) {
-        try {
-            File xmlFile = new File(args[0]);
-            File xslFile = new File(args[1]);
-            XMLTransformer t = new XMLTransformer(xmlFile, xslFile);
-            System.out.println(t.apply());
-        } catch(Exception e) {
-            e.printStackTrace();
-        }
-    }
-}
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/test/TestXMPP.java b/Open-ILS/src/Android/opensrf/org/opensrf/test/TestXMPP.java
deleted file mode 100644 (file)
index 2fba67f..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.opensrf.test;
-
-import org.opensrf.net.xmpp.XMPPReader;
-import org.opensrf.net.xmpp.XMPPMessage;
-import org.opensrf.net.xmpp.XMPPSession;
-
-public class TestXMPP {
-
-    /**
-     * Connects to the jabber server and waits for inbound messages.
-     * If a recipient is provided, a small message is sent to the recipient.
-     */
-    public static void main(String args[]) throws Exception {
-
-        String host;
-        int port;
-        String username;
-        String password;
-        String resource;
-        String recipient;
-
-        try {
-            host = args[0];
-            port = Integer.parseInt(args[1]);
-            username = args[2];
-            password = args[3];
-            resource = args[4];
-
-        } catch(ArrayIndexOutOfBoundsException e) {
-            System.err.println("usage: org.opensrf.test.TestXMPP <host> <port> <username> <password> <resource> [<recipient>]");
-            return;
-        }
-
-        XMPPSession session = new XMPPSession(host, port);
-        session.connect(username, password, resource);
-
-        XMPPMessage msg;
-
-        if( args.length == 6 ) {
-
-            /** they specified a recipient */
-
-            recipient = args[5];
-            msg = new XMPPMessage();
-            msg.setTo(recipient);
-            msg.setThread("test-thread");
-            msg.setBody("Hello, from java-xmpp");
-            System.out.println("Sending message to " + recipient);
-            session.send(msg);
-        }
-
-        while(true) {
-            System.out.println("waiting for message...");
-            msg = session.recv(-1); /* wait forever for a message to arrive */
-            System.out.println("got message: " + msg.toXML());
-        }
-    }
-}
-
-
-
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/Cache.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/Cache.java
deleted file mode 100644 (file)
index 5303688..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.opensrf.util;
-import com.danga.MemCached.*;
-import java.util.List;
-
-/**
- * Memcache client
- */
-public class Cache extends MemCachedClient {
-
-    public Cache() {
-        super();
-        setCompressThreshold(4096); /* ?? */
-    }
-
-    /**
-     * Initializes the cache client
-     * @param serverList Array of server:port strings specifying the
-     * set of memcache servers this client will talk to
-     */
-    public static void initCache(String[] serverList) {
-        SockIOPool pool = SockIOPool.getInstance();
-        pool.setServers(serverList);
-        pool.initialize();      
-        com.danga.MemCached.Logger logger = 
-            com.danga.MemCached.Logger.getLogger(MemCachedClient.class.getName());
-        logger.setLevel(logger.LEVEL_ERROR);
-    }
-
-    /**
-     * Initializes the cache client
-     * @param serverList List of server:port strings specifying the
-     * set of memcache servers this client will talk to
-     */
-    public static void initCache(List<String> serverList) {
-        initCache(serverList.toArray(new String[]{}));
-    }
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/Config.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/Config.java
deleted file mode 100644 (file)
index ddac9c0..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-package org.opensrf.util;
-
-import org.json.*;
-import java.util.Map;
-import java.util.List;
-
-
-/**
- * Config reader and accesor module.  This module reads an XML config file,
- * then loads the file into an internal config, whose values may be accessed
- * by xpath-style lookup paths.
- */
-public class Config {
-
-    /** The globl config instance */
-    private static Config config;
-    /** The object form of the parsed config */
-    private Map configObject;
-    /** 
-     * The log parsing context.  This is used as a prefix to the
-     * config item search path.  This allows config XML chunks to 
-     * be inserted into arbitrary XML files.
-     */
-    private String context;
-
-    public static Config global() {
-        return config;
-    }
-
-
-    /**
-     * @param context The config context
-     */
-    public Config(String context) {
-        this.context = context;
-    }
-
-    /**
-     * Sets the global config object.
-     * @param c The config object to use.
-     */
-    public static void setGlobalConfig(Config c) {
-        config = c;
-    }
-
-    /**
-     * Parses an XML config file.
-     * @param filename The path to the file to parse.
-     */
-    public void parse(String filename) throws ConfigException {
-        try {
-            String xml = Utils.fileToString(filename);
-            JSONObject jobj = XML.toJSONObject(xml);
-            configObject = (Map) new JSONReader(jobj.toString()).readObject();
-        } catch(Exception e) {
-            throw new ConfigException("Error parsing config", e);
-        }
-    }
-
-    public static void setConfig(Config conf) {
-        config = conf;
-    }
-
-    public void setConfigObject(Map config) {
-        this.configObject = config;
-    }
-
-    protected Map getConfigObject() {
-        return this.configObject;
-    }
-
-
-    /**
-     * Returns the configuration value found at the requested path.
-     * @param path The search path
-     * @return The config value, or null if no value exists at the given path.  
-     * @throws ConfigException thrown if nothing is found at the path
-     */
-    public String getString(String path) throws ConfigException {
-        try {
-            return (String) get(path);
-        } catch(Exception e) {
-            throw new 
-                ConfigException("No config string found at " + path);
-        }
-    }
-
-    /**
-     * Gets the int value at the given path
-     * @param path The search path
-     */
-    public int getInt(String path) throws ConfigException {
-        try {
-            return Integer.parseInt(getString(path));
-        } catch(Exception e) {
-            throw new
-                ConfigException("No config int found at " + path);
-        }
-    }
-
-    /**
-     * Returns the configuration object found at the requested path.
-     * @param path The search path
-     * @return The config value
-     * @throws ConfigException thrown if nothing is found at the path
-     */
-    public Object get(String path) throws ConfigException {
-        try {
-            Object obj = Utils.findPath(configObject, context + path);
-            if(obj == null)
-                throw new ConfigException("");
-            return obj;
-        } catch(Exception e) {
-            e.printStackTrace();
-            throw new ConfigException("No config object found at " + path);
-        }
-    }
-
-    /**
-     * Returns the first item in the list found at the given path.  If
-     * no list is found, ConfigException is thrown.
-     * @param path The search path
-     */
-    public Object getFirst(String path) throws ConfigException {
-        Object obj = get(path); 
-        if(obj instanceof List) 
-            return ((List) obj).get(0);
-        return obj;
-    }
-
-
-    /**
-     * Returns the config as a JSON string
-     */
-    public String toString() {
-        return new JSONWriter(configObject).write();
-    }
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/ConfigException.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/ConfigException.java
deleted file mode 100644 (file)
index c1c491e..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.opensrf.util;
-
-/**
- * Thrown by the Config module when a user requests a configuration
- * item that does not exist
- */
-public class ConfigException extends Exception {
-    public ConfigException(String info) {
-        super(info);
-    }
-    public ConfigException(String info, Throwable t) {
-        super(info, t);
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/FileLogger.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/FileLogger.java
deleted file mode 100644 (file)
index 9eb838d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-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) {}
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/JSONException.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/JSONException.java
deleted file mode 100644 (file)
index ec28e1d..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.opensrf.util;
-/**
- * Used to indicate JSON parsing errors
- */
-public class JSONException extends Exception {
-    public JSONException(String s) {
-        super(s);
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/JSONReader.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/JSONReader.java
deleted file mode 100644 (file)
index 55eb5c0..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-package org.opensrf.util;
-
-import java.io.*;
-import java.util.*;
-
-import org.json.JSONTokener;
-import org.json.JSONObject;
-import org.json.JSONArray;
-
-
-/**
- * JSON utilities.
- */
-public class JSONReader {
-
-    /** Special OpenSRF serializable object netClass key */
-    public static final String JSON_CLASS_KEY = "__c";
-
-    /** Special OpenSRF serializable object payload key */
-    public static final String JSON_PAYLOAD_KEY = "__p";
-
-    /** The JSON string to parser */
-    private String json;
-
-    /**
-     * @param json The JSON to parse
-     */
-    public JSONReader(String json) {
-        this.json = json;
-    }
-
-    /**
-     * Parses JSON and creates an object.
-     * @return The resulting object which may be a List, 
-     * Map, Number, String, Boolean, or null
-     */
-    public Object read() throws JSONException {
-        JSONTokener tk = new JSONTokener(json);
-        try {
-            return readSubObject(tk.nextValue());
-        } catch(org.json.JSONException e) {
-            throw new JSONException(e.toString());
-        }
-    }
-
-    /**
-     * Assumes that a JSON array will be read.  Returns
-     * the resulting array as a list.
-     */
-    public List<?> readArray() throws JSONException {
-        Object o = read();
-        try {
-            return (List<?>) o;
-        } catch(Exception e) {
-            throw new JSONException("readArray(): JSON cast exception");
-        }
-    }
-
-    /**
-     * Assumes that a JSON object will be read.  Returns 
-     * the resulting object as a map.
-     */
-    public Map<?,?> readObject() throws JSONException {
-        Object o = read();
-        try {
-            return (Map<?,?>) o;
-        } catch(Exception e) {
-            throw new JSONException("readObject(): JSON cast exception");
-        }
-    }
-
-
-    /**
-     * Recurse through the object and turn items into maps, lists, etc.
-     */
-    private Object readSubObject(Object obj) throws JSONException {
-
-        if( obj == null || 
-            obj instanceof String || 
-            obj instanceof Number ||
-            obj instanceof Boolean)
-                return obj;
-
-        try {
-
-            if( obj instanceof JSONObject ) {
-
-                /* read objects */
-                String key;
-                JSONObject jobj = (JSONObject) obj;
-                Map<String, Object> map = new HashMap<String, Object>();
-
-                for( Iterator e = jobj.keys(); e.hasNext(); ) {
-                    key = (String) e.next();
-
-                    /* we encoutered the special class key */
-                    if( JSON_CLASS_KEY.equals(key) ) 
-                        return buildRegisteredObject(
-                            (String) jobj.get(key), jobj.get(JSON_PAYLOAD_KEY));
-
-                    /* we encountered the data key */
-                    if( JSON_PAYLOAD_KEY.equals(key) ) 
-                        return buildRegisteredObject(
-                            (String) jobj.get(JSON_CLASS_KEY), jobj.get(key));
-
-                    map.put(key, readSubObject(jobj.get(key)));
-                }
-                return map;
-            } 
-            
-            if ( obj instanceof JSONArray ) {
-
-                JSONArray jarr = (JSONArray) obj;
-                int length = jarr.length();
-                List<Object> list = new ArrayList<Object>(length);
-
-                for( int i = 0; i < length; i++ ) 
-                    list.add(readSubObject(jarr.get(i)));   
-                return list;
-                
-            }
-
-        } catch(org.json.JSONException e) {
-
-            throw new JSONException(e.toString());
-        }
-
-        return null;
-    }
-
-
-
-    /**
-     * Builds an OSRFObject map registered OSRFHash object based on the JSON object data.
-     * @param netClass The network class hint for this object.
-     * @param paylaod The actual object on the wire.
-     */
-    private OSRFObject buildRegisteredObject(
-        String netClass, Object payload) throws JSONException {
-
-        OSRFRegistry registry = OSRFRegistry.getRegistry(netClass);
-        OSRFObject obj = new OSRFObject(registry);
-        try {
-            if( payload instanceof JSONArray ) {
-                JSONArray jarr = (JSONArray) payload;
-
-                /* for each array item, instert the item into the hash.  the hash 
-                 * key is found by extracting the fields array from the registered 
-                 * object at the current array index */
-                String fields[] = registry.getFields();
-                for( int i = 0; i < jarr.length(); i++ ) {
-                    obj.put(fields[i], readSubObject(jarr.get(i)));   
-                }
-
-            } else if( payload instanceof JSONObject ) {
-
-                /* since this is a hash, simply copy the data over */
-                JSONObject jobj = (JSONObject) payload;
-                String key;
-                for( Iterator e = jobj.keys(); e.hasNext(); ) {
-                    key = (String) e.next();
-                    obj.put(key, readSubObject(jobj.get(key)));
-                }
-            }
-
-        } catch(org.json.JSONException e) {
-            throw new JSONException(e.toString());
-        }
-
-        return obj;
-    }
-}
-
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/JSONWriter.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/JSONWriter.java
deleted file mode 100644 (file)
index 7cb2cca..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-package org.opensrf.util;
-
-import java.io.*;
-import java.util.*;
-
-
-/**
- * JSONWriter
- */
-public class JSONWriter {
-
-    /** The object to serialize to JSON */
-    private Object obj;
-
-    /**
-     * @param obj The object to encode
-     */
-    public JSONWriter(Object obj) {
-        this.obj = obj;
-    }
-
-
-    /**
-     * Encodes a java object to JSON.
-     */
-    public String write() {
-        StringBuffer sb = new StringBuffer();
-        write(sb);
-        return sb.toString();
-    }
-
-
-
-    /**
-     * Encodes a java object to JSON.
-     * Maps (HashMaps, etc.) are encoded as JSON objects.  
-     * Iterable's (Lists, etc.) are encoded as JSON arrays
-     */
-    public void write(StringBuffer sb) {
-        write(obj, sb);
-    }
-
-    /**
-     * Encodes the object as JSON into the provided buffer
-     */
-    public void write(Object obj, StringBuffer sb) {
-
-        /** JSON null */
-        if(obj == null) {
-            sb.append("null");
-            return;
-        }
-
-        /** JSON string */
-        if(obj instanceof String) {
-            sb.append('"');
-            Utils.escape((String) obj, sb);
-            sb.append('"');
-            return;
-        }
-
-        /** JSON number */
-        if(obj instanceof Number) {
-            sb.append(obj.toString());
-            return;
-        }
-
-        /** JSON array */
-        if(obj instanceof Iterable) {
-            encodeJSONArray((Iterable) obj, sb);
-            return;
-        }
-
-        /** OpenSRF serializable objects */
-        if(obj instanceof OSRFSerializable) {
-            encodeOSRFSerializable((OSRFSerializable) obj, sb);
-            return;
-        }
-
-        /** JSON object */
-        if(obj instanceof Map) {
-            encodeJSONObject((Map) obj, sb);
-            return;
-        }
-
-        /** JSON boolean */
-        if(obj instanceof Boolean) {
-            sb.append((((Boolean) obj).booleanValue() ? "true" : "false"));
-            return;
-        }
-    }
-
-
-    /**
-     * Encodes a List as a JSON array
-     */
-    private void encodeJSONArray(Iterable iterable, StringBuffer sb) {
-        Iterator itr = iterable.iterator();
-        sb.append("[");
-        boolean some = false;
-
-        while(itr.hasNext()) {
-            some = true;
-            write(itr.next(), sb);
-            sb.append(',');
-        }
-
-        /* remove the trailing comma if the array has any items*/
-        if(some) 
-            sb.deleteCharAt(sb.length()-1); 
-        sb.append("]");
-    }
-
-
-    /**
-     * Encodes a Map as a JSON object
-     */
-    private void encodeJSONObject(Map map, StringBuffer sb) {
-        Iterator itr = map.keySet().iterator();
-        sb.append("{");
-        Object key = null;
-
-        while(itr.hasNext()) {
-            key = itr.next();
-            write(key, sb);
-            sb.append(':');
-            write(map.get(key), sb);
-            sb.append(',');
-        }
-
-        /* remove the trailing comma if the object has any items*/
-        if(key != null) 
-            sb.deleteCharAt(sb.length()-1); 
-        sb.append("}");
-    }
-
-
-    /**
-     * Encodes a network-serializable OpenSRF object
-     */
-    private void encodeOSRFSerializable(OSRFSerializable obj, StringBuffer sb) {
-
-        OSRFRegistry reg = obj.getRegistry();
-        String[] fields = reg.getFields();
-        Map<String, Object> map = new HashMap<String, Object>();
-        map.put(JSONReader.JSON_CLASS_KEY, reg.getNetClass());
-
-        if( reg.getWireProtocol() == OSRFRegistry.WireProtocol.ARRAY ) {
-
-            /** encode arrays as lists */
-            List<Object> list = new ArrayList<Object>(fields.length);
-            for(String s : fields)
-                list.add(obj.get(s));
-            map.put(JSONReader.JSON_PAYLOAD_KEY, list);
-
-        } else {
-
-            /** encode hashes as maps */
-            Map<String, Object> subMap = new HashMap<String, Object>();
-            for(String s : fields)
-                subMap.put(s, obj.get(s));
-            map.put(JSONReader.JSON_PAYLOAD_KEY, subMap);
-                
-        }
-
-        /** now serialize the encoded object */
-        write(map, sb);
-    }
-}
-
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/Logger.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/Logger.java
deleted file mode 100644 (file)
index 2923c23..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-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));
-    }
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/OSRFObject.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/OSRFObject.java
deleted file mode 100644 (file)
index af28f4a..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.opensrf.util;
-
-import java.util.Map;
-import java.util.HashMap;
-
-
-/**
- * Generic OpenSRF network-serializable object.  This allows
- * access to object fields.  
- */
-public class OSRFObject extends HashMap<String, Object> implements OSRFSerializable {
-    
-    /** This objects registry */
-    private OSRFRegistry registry;
-
-    public OSRFObject() {
-    }
-
-
-    /**
-     * Creates a new object with the provided registry
-     */
-    public OSRFObject(OSRFRegistry reg) {
-        this();
-        registry = reg;
-    }
-
-
-    /**
-     * Creates a new OpenSRF object based on the net class string
-     * */
-    public OSRFObject(String netClass) {
-        this(OSRFRegistry.getRegistry(netClass));
-    }
-
-
-    /**
-     * @return This object's registry
-     */
-    public OSRFRegistry getRegistry() {
-        return registry;
-    }
-
-    /**
-     * Implement get() to fulfill our contract with OSRFSerializable
-     */
-    public Object get(String field) {
-        return super.get(field);
-    }
-
-    /** Returns the string value found at the given field */
-    public String getString(String field) {
-        return (String) get(field);
-    }
-
-    /** Returns the int value found at the given field */
-    public int getInt(String field) {
-        Object o = get(field);
-        if(o instanceof String)
-            return Integer.parseInt((String) o);
-        return ((Integer) get(field)).intValue();
-    }
-}
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/OSRFRegistry.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/OSRFRegistry.java
deleted file mode 100644 (file)
index c6e6bc6..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-package org.opensrf.util;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.HashMap;
-
-
-/**
- * Manages the registration of OpenSRF network-serializable objects.  
- * A serializable object has a class "hint" (called netClass within) which
- * describes the type of object.  Each object also has a set of field names
- * for accessing/mutating object properties.  Finally, objects have a 
- * serialization wire protocol.  Currently supported protocols are HASH
- * and ARRAY.
- */
-public class OSRFRegistry implements Serializable{
-
-
-    /**
-        * 
-        */
-       private static final long serialVersionUID = 1L;
-       /**
-     * Global collection of registered net objects.  
-     * Maps netClass names to registries.
-     */
-    private static HashMap<String, OSRFRegistry> 
-        registry = new HashMap<String, OSRFRegistry>();
-
-
-    /** Serialization types for registered objects */
-    public enum WireProtocol {
-        ARRAY, HASH
-    };
-
-
-    /** Array of field names for this registered object */
-    String fields[];
-    /** The wire protocol for this object */
-    WireProtocol wireProtocol;
-    /** The network class for this object */
-    String netClass;
-
-    /**
-     * Returns the array of field names
-     */
-    public String[] getFields() {
-        return this.fields;
-    }
-
-
-    /**
-     * Registers a new object.
-     * @param netClass The net class for this object
-     * @param wireProtocol The object's wire protocol
-     * @param fields An array of field names.  For objects whose
-     * wire protocol is ARRAY, the positions of the field names 
-     * will be used as the array indices for the fields at serialization time
-     */
-    public static OSRFRegistry registerObject(String netClass, WireProtocol wireProtocol, String fields[]) {
-        OSRFRegistry r = new OSRFRegistry(netClass, wireProtocol, fields);
-        registry.put(netClass, r);
-        return r;
-    }
-
-    /**
-     * Returns the registry for the given netclass
-     * @param netClass The network class to lookup
-     */
-    public static OSRFRegistry getRegistry(String netClass) {
-        if( netClass == null ) return null;
-        return (OSRFRegistry) registry.get(netClass);
-    }
-
-
-    /**
-     * @param field The name of the field to lookup
-     * @return the index into the fields array of the given field name.
-     */
-    public int getFieldIndex(String field) {
-        for( int i = 0; i < fields.length; i++ )
-            if( fields[i].equals(field) ) 
-                return i;
-        return -1;
-    }
-
-    /** Returns the wire protocol of this object */
-    public WireProtocol getWireProtocol() {
-        return this.wireProtocol;
-    }
-
-    /** Returns the netClass ("hint") of this object */
-    public String getNetClass() {
-        return this.netClass;
-    }
-
-    /**
-     * Creates a new registry object.
-     * @param netClass The network class/hint
-     * @param wireProtocol The wire protocol
-     * @param fields The array of field names.  For array-based objects,
-     * the fields array must be sorted in accordance with the sorting
-     * of the objects in the array.
-     */ 
-    public OSRFRegistry(String netClass, WireProtocol wireProtocol, String fields[]) {
-        this.netClass = netClass;
-        this.wireProtocol = wireProtocol;
-        this.fields = fields;
-    }
-}
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/OSRFSerializable.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/OSRFSerializable.java
deleted file mode 100644 (file)
index 64b5d6f..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.opensrf.util;
-
-/**
- * All network-serializable OpenSRF object must implement this interface.
- */
-public interface OSRFSerializable {
-
-    /**
-     * Returns the object registry object for the implementing class.
-     */
-    public abstract OSRFRegistry getRegistry();
-
-    /**
-     * Returns the object found at the given field
-     */
-    public abstract Object get(String field);
-}
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/SettingsClient.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/SettingsClient.java
deleted file mode 100644 (file)
index 71e570a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.opensrf.util;
-import org.opensrf.*;
-import java.util.Map;
-
-/**
- * Connects to the OpenSRF Settings server to fetch the settings config.  
- * Provides a Config interface for fetching settings via path
- */
-public class SettingsClient extends Config {
-
-    /** Singleton SettingsClient instance */
-    private static SettingsClient client = new SettingsClient();
-
-    public SettingsClient() {
-        super("");
-    }
-
-    /**
-     * @return The global settings client instance 
-     */
-    public static SettingsClient instance() throws ConfigException {
-        if(client.getConfigObject() == null) 
-            client.fetchConfig();
-        return client;
-    }
-
-    /**
-     * Fetches the settings object from the settings server
-     */
-    private void fetchConfig() throws ConfigException {
-
-        ClientSession ses = new ClientSession("opensrf.settings");
-        try {
-
-            Request req = ses.request(
-                "opensrf.settings.host_config.get", 
-                new String[]{(String)Config.global().getFirst("/domain")});
-    
-            Result res = req.recv(12000);
-            if(res == null) {
-                /** throw exception */
-            }
-            setConfigObject((Map) res.getContent());
-
-        } catch(Exception e) {
-            throw new ConfigException("Error fetching settings config", e);
-
-        } finally {
-            ses.cleanup();
-        }
-    }
-}
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/Utils.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/Utils.java
deleted file mode 100644 (file)
index 159d254..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.opensrf.util;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * Collection of general, static utility methods
- */
-public class Utils {
-
-    /**
-     * Returns the string representation of a given file.
-     * @param filename The file to turn into a string
-     */
-    public static String fileToString(String filename) 
-            throws FileNotFoundException, IOException {
-
-        StringBuffer sb = new StringBuffer();
-        BufferedReader in = new BufferedReader(new FileReader(filename));
-        String str;
-        while ((str = in.readLine()) != null) 
-            sb.append(str);
-        in.close();
-        return sb.toString();
-    }
-
-
-    /**
-     * Escapes a string.
-     */
-    public static String escape(String string) {
-        StringBuffer sb = new StringBuffer();
-        escape(string, sb);
-        return sb.toString();
-    }
-
-    /**
-     * Escapes a string.  Turns bare newlines into \n, etc.
-     * Escapes \n, \r, \t, ", \f
-     * Encodes non-ascii characters as UTF-8: \u0000
-     * @param string The string to escape
-     * @param sb The string buffer to write the escaped string into
-     */
-    public static void escape(String string, StringBuffer sb) {
-        int len = string.length();
-        String utf;
-        char c;
-        for( int i = 0; i < len; i++ ) {
-            c = string.charAt(i);
-            switch (c) {
-                case '\\':
-                    sb.append("\\\\");
-                    break;
-                case '"':
-                    sb.append("\\\"");
-                    break;
-                case '\b':
-                    sb.append("\\b");
-                    break;
-                case '\t':
-                    sb.append("\\t");
-                    break;
-                case '\n':
-                    sb.append("\\n");
-                    break;
-                case '\f':
-                    sb.append("\\f");
-                    break;
-                case '\r':
-                    sb.append("\\r");
-                    break;
-                default:
-                    if (c < 32 || c > 126 ) { 
-                        /* escape all non-ascii or control characters as UTF-8 */
-                        utf = "000" + Integer.toHexString(c);
-                        sb.append("\\u" + utf.substring(utf.length() - 4));
-                    } else {
-                        sb.append(c);
-                    }
-            }
-        }
-    }
-
-
-    /** 
-     * Descends into the map along the given XPATH-style path 
-     * and returns the object found there.
-     * @param path The XPATH-style path to search.  Path 
-     * components are separated by '/' characters.  
-     * Example:  /opensrf/loglevel
-     * @return The found object. 
-     */
-
-    public static Object findPath(Map map, String path) {
-        String keys[] = path.split("/", -1);
-        int i = 0;
-        if(path.charAt(0) == '/') i++;
-        for(; i < keys.length - 1; i++ ) 
-            map = (Map) map.get(keys[i]);
-
-        return map.get(keys[i]);
-    }
-}
-
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/XMLFlattener.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/XMLFlattener.java
deleted file mode 100644 (file)
index 7abefe0..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-package org.opensrf.util;
-
-import javax.xml.stream.*;
-import javax.xml.stream.events.* ;
-import javax.xml.namespace.QName;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.ListIterator;
-import java.io.InputStream;
-import org.opensrf.util.JSONWriter;
-import org.opensrf.util.JSONReader;
-
-/**
- * Flattens an XML file into a properties map.  Values are stored as JSON strings or arrays.
- * An array is created if more than one value resides at the same key.
- * e.g. html.head.script = "alert('hello');"
- */
-public class XMLFlattener {
-
-    /** Flattened properties map */
-    private Map<String, String> props;
-    /** Incoming XML stream */
-    private InputStream inStream;
-    /** Runtime list of encountered elements */
-    private List<String> elementList;
-
-    /**
-     * 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 XMLFlattener(InputStream inStream) {
-        props = new HashMap<String, String>();
-        this.inStream = inStream;
-        elementList = new ArrayList<String>();
-    }
-
-    /** Turns an array of strings into a dot-separated key string */
-    private String listToString() {
-        ListIterator itr = elementList.listIterator();
-        StringBuffer sb = new StringBuffer();
-        while(itr.hasNext()) {
-            sb.append(itr.next());
-            if(itr.hasNext())
-                sb.append(".");
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Parses XML data from the provided stream.
-     */
-    public Map read() throws javax.xml.stream.XMLStreamException {
-
-        XMLInputFactory factory = XMLInputFactory.newInstance();
-
-        /** disable as many unused features as possible to speed up the parsing */
-        factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.TRUE);
-        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();
-            if(reader.isWhiteSpace()) continue;
-
-            switch(eventType) {
-
-                case XMLEvent.START_ELEMENT:
-                    elementList.add(reader.getName().toString());
-                    break;
-
-                case XMLEvent.CHARACTERS:
-                    String text = reader.getText();
-                    String key = listToString();
-
-                    if(props.containsKey(key)) {
-
-                        /* something in the map already has this key */
-
-                        Object o = null;
-                        try {
-                            o = new JSONReader(props.get(key)).read();
-                        } catch(org.opensrf.util.JSONException e){}
-
-                        if(o instanceof List) {
-                            /* if the map contains a list, append to the list and re-encode */
-                            ((List) o).add(text);
-
-                        } else {
-                            /* if the map just contains a string, start building a new list
-                             * with the old string and append the new string */
-                            List<String> arr = new ArrayList<String>();
-                            arr.add((String) o);
-                            arr.add(text);
-                            o = arr;
-                        }
-
-                        props.put(key, new JSONWriter(o).write());
-
-                    } else {
-                        props.put(key, new JSONWriter(text).write());
-                    }
-                    break;
-
-                case XMLEvent.END_ELEMENT: 
-                    elementList.remove(elementList.size()-1);
-                    break;
-            }
-        }
-
-        return props;
-    }
-}
-
-
-
-
diff --git a/Open-ILS/src/Android/opensrf/org/opensrf/util/XMLTransformer.java b/Open-ILS/src/Android/opensrf/org/opensrf/util/XMLTransformer.java
deleted file mode 100644 (file)
index f8bc0d3..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.opensrf.util;
-import javax.xml.transform.*;
-import javax.xml.transform.stream.*;
-import javax.xml.parsers.*;
-import java.io.File;
-import java.io.ByteArrayInputStream;
-import java.io.OutputStream;
-import java.io.ByteArrayOutputStream;
-
-
-/**
- * Performs XSL transformations.  
- * TODO: Add ability to pass in XSL variables
- */
-public class XMLTransformer {
-
-    /** The XML to transform */
-    private Source xmlSource;
-    /** The stylesheet to apply */
-    private Source xslSource;
-
-    public XMLTransformer(Source xmlSource, Source xslSource) {
-        this.xmlSource = xmlSource;
-        this.xslSource = xslSource;
-    }
-
-    public XMLTransformer(String xmlString, File xslFile) {
-        this(
-            new StreamSource(new ByteArrayInputStream(xmlString.getBytes())),
-            new StreamSource(xslFile));
-    }
-
-    public XMLTransformer(File xmlFile, File xslFile) {
-        this(
-            new StreamSource(xmlFile),
-            new StreamSource(xslFile));
-    }
-
-    /** 
-     * Applies the transformation and puts the result into the provided output stream
-     */
-    public void apply(OutputStream outStream) throws TransformerException, TransformerConfigurationException {
-        Result result = new StreamResult(outStream);
-        Transformer trans = TransformerFactory.newInstance().newTransformer(xslSource);
-        trans.transform(xmlSource, result);
-    }
-
-    /**
-     * Applies the transformation and return the resulting string
-     * @return The String created by the XSL transformation
-     */
-    public String apply() throws TransformerException, TransformerConfigurationException {
-        OutputStream outStream = new ByteArrayOutputStream();
-        this.apply(outStream);
-        return outStream.toString();
-    }
-}
-
-
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/ClientSession.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/ClientSession.java
new file mode 100644 (file)
index 0000000..3ed4908
--- /dev/null
@@ -0,0 +1,175 @@
+package org.opensrf;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.Random;
+import java.util.Arrays;
+
+import org.opensrf.util.*;
+import org.opensrf.net.xmpp.*;
+
+
+/**
+ * Models an OpenSRF client session.
+ */
+public class ClientSession extends Session {
+
+    /** The remote service to communicate with */
+    private String service;
+    /** OpenSRF domain */
+    private String domain;
+    /** Router name */
+    private String router;
+
+    /** 
+     * original remote node.  The current remote node will change based 
+     * on server responses.  This is used to reset the remote node to 
+     * its original state.
+     */
+    private String origRemoteNode;
+    /** The next request id */
+    private int nextId;
+    /** The requests this session has sent */
+    private Map<Integer, Request> requests;
+
+    /**
+     * Creates a new client session.  Initializes the 
+     * @param service The remote service.
+     */
+    public ClientSession(String service) throws ConfigException {
+        this(service, null);
+    }
+
+    /**
+     * Creates a new client session.  Initializes the 
+     * @param service The remote service.
+     * @param locale The locale for this session.
+     */
+    public ClientSession(String service, String locale) throws ConfigException {
+        this.service = service;
+        if(locale != null) 
+            setLocale(locale);
+
+        /** generate the remote node string */
+        domain = (String) Config.global().getFirst("/domain");
+        router = Config.global().getString("/router_name");
+        setRemoteNode(router + "@" + domain + "/" + service);
+        origRemoteNode = getRemoteNode();
+
+
+        /** create a random thread */
+        long time = new Date().getTime();
+        Random rand = new Random(time);
+        setThread(rand.nextInt()+""+rand.nextInt()+""+time+Thread.currentThread().getId());
+
+        nextId = 0;
+        requests = new HashMap<Integer, Request>();
+        cacheSession();
+    }
+
+    /**
+     * Creates a new request to send to our remote service.
+     * @param method The method API name
+     * @param params The list of method parameters
+     * @return The request object.
+     */
+    public Request request(String method, List<Object> params) throws SessionException {
+        return request(new Request(this, nextId++, method, params));
+    }
+
+    /**
+     * Creates a new request to send to our remote service.
+     * @param method The method API name
+     * @param params The list of method parameters
+     * @return The request object.
+     */
+    public Request request(String method, Object[] params) throws SessionException {
+        return request(new Request(this, nextId++, method, Arrays.asList(params)));
+    }
+
+
+    /**
+     * Creates a new request to send to our remote service.
+     * @param method The method API name
+     * @return The request object.
+     */
+    public Request request(String method) throws SessionException {
+        return request(new Request(this, nextId++, method));
+    }
+
+
+    private Request request(Request req) throws SessionException {
+        if(getConnectState() != ConnectState.CONNECTED)
+            resetRemoteId();
+        requests.put(new Integer(req.getId()), req);
+        req.send();
+        return req;
+    }
+
+
+    /**
+     * Resets the remoteNode to its original state.
+     */
+    public void resetRemoteId() {
+        setRemoteNode(origRemoteNode);
+    }
+
+
+    /**
+     * Pushes a response onto the result queue of the appropriate request.
+     * @param msg The received RESULT Message
+     */
+    public void pushResponse(Message msg) {
+
+        Request req = findRequest(msg.getId());
+        if(req == null) {
+            /** LOG that we've received a result to a non-existant request */
+            System.err.println(msg.getId() +" has no corresponding request");
+            return;
+        }
+        OSRFObject payload = (OSRFObject) msg.get("payload");
+
+        /** build a result and push it onto the request's result queue */
+        req.pushResponse(
+            new Result( 
+                payload.getString("status"), 
+                payload.getInt("statusCode"),
+                payload.get("content")
+            )
+        );
+    }
+
+    public Request findRequest(int reqId) {
+        return requests.get(new Integer(reqId));
+    }
+
+    /**
+     * Removes a request for this session's request set
+     */
+    public void cleanupRequest(int reqId) {
+        requests.remove(new Integer(reqId));
+    }
+
+     public void setRequestComplete(int reqId) {
+        Request req = findRequest(reqId);
+        if(req == null) return;
+        req.setComplete();
+    }
+
+    public static Object atomicRequest(String service, String method, Object[] params) throws MethodException {
+        try {
+            ClientSession session = new ClientSession(service);
+            Request osrfRequest = session.request(method, params);
+            Result result = osrfRequest.recv(600000);
+            if(result.getStatusCode() != 200) 
+                throw new MethodException( 
+                    "Request "+service+":"+method+":"+" failed with status code " + result.getStatusCode());
+            return result.getContent();
+        } catch(Exception e) {
+            throw new MethodException(e);
+        }
+    }
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/Message.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/Message.java
new file mode 100644 (file)
index 0000000..6bfe1ea
--- /dev/null
@@ -0,0 +1,110 @@
+package org.opensrf;
+import org.opensrf.util.*;
+
+
+public class Message implements OSRFSerializable {
+
+    /** Message types */
+    public static final String REQUEST = "REQUEST";
+    public static final String STATUS = "STATUS";
+    public static final String RESULT = "RESULT";
+    public static final String CONNECT = "CONNECT";
+    public static final String DISCONNECT = "DISCONNECT";
+
+    /** Message ID.  This number is used to relate requests to responses */
+    private int id;
+    /** type of message. */
+    private String type;
+    /** message payload */
+    private Object payload;
+    /** message locale */
+    private String locale;
+
+    /** Create a registry for the osrfMessage object */
+    private static OSRFRegistry registry = 
+        OSRFRegistry.registerObject(
+            "osrfMessage", 
+            OSRFRegistry.WireProtocol.HASH, 
+            new String[] {"threadTrace", "type", "payload", "locale"});
+
+    /**
+     * @param id This message's ID
+     * @param type The type of message
+     */
+    public Message(int id, String type) {
+        setId(id);
+        setString(type);
+    }
+
+    /**
+     * @param id This message's ID
+     * @param type The type of message
+     * @param payload The message payload
+     */
+    public Message(int id, String type, Object payload) {
+        this(id, type);
+        setPayload(payload);
+    }
+
+    /**
+     * @param id This message's ID
+     * @param type The type of message
+     * @param payload The message payload
+     * @param locale The message locale
+     */
+    public Message(int id, String type, Object payload, String locale) {
+        this(id, type, payload);
+        setPayload(payload);
+        setLocale(locale);
+    }
+
+
+    public int getId() {
+        return id;
+    }   
+    public String getType() {
+        return type;
+    }
+    public Object getPayload() {
+        return payload;
+    }
+    public String getLocale() {
+        return locale;
+    }
+    public void setId(int id) {
+        this.id = id;
+    }
+    public void setString(String type) {
+        this.type = type;
+    }
+    public void setPayload(Object p) {
+        payload = p;
+    }
+    public void setLocale(String l) {
+        locale = l;
+    }
+
+    /**
+     * Implements the generic get() API required by OSRFSerializable
+     */
+    public Object get(String field) {
+        if("threadTrace".equals(field))
+            return getId();
+        if("type".equals(field))
+            return getType().toString();
+        if("payload".equals(field))
+            return getPayload();
+        if("locale".equals(field))
+            return getLocale();
+        return null;
+    }
+
+    /**
+     * @return The osrfMessage registry.
+     */
+    public OSRFRegistry getRegistry() {
+        return registry;
+    }
+}
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/Method.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/Method.java
new file mode 100644 (file)
index 0000000..b708d4f
--- /dev/null
@@ -0,0 +1,78 @@
+package org.opensrf;
+import java.util.List;
+import java.util.ArrayList;
+import org.opensrf.util.*;
+
+
+public class Method extends OSRFObject {
+
+    /** The method API name */
+    private String name;
+    /** The ordered list of method params */
+    private List<Object> params;
+
+    /** Create a registry for the osrfMethod object */
+    private static OSRFRegistry registry = 
+        OSRFRegistry.registerObject(
+            "osrfMethod", 
+            OSRFRegistry.WireProtocol.HASH, 
+            new String[] {"method", "params"});
+
+    /**
+     * @param name The method API name 
+     */
+    public Method(String name) {
+        this.name = name;
+        this.params = new ArrayList<Object>(8);
+    }
+
+    /**
+     * @param name The method API name
+     * @param params The ordered list of params
+     */
+    public Method(String name, List<Object> params) {
+        this.name = name;
+        this.params = params;
+    }
+
+    /**
+     * @return The method API name
+     */
+    public String getName() {
+        return name;
+    }
+    /**
+     * @return The ordered list of params
+     */
+    public List<Object> getParams() {
+       return params; 
+    }
+
+    /**
+     * Pushes a new param object onto the set of params 
+     * @param p The new param to add to the method.
+     */
+    public void addParam(Object p) {
+        this.params.add(p);
+    }
+
+    /**
+     * Implements the generic get() API required by OSRFSerializable
+     */
+    public Object get(String field) {
+        if("method".equals(field))
+            return getName();
+        if("params".equals(field))
+            return getParams();
+        return null;
+    }
+
+    /**
+     * @return The osrfMethod registry.
+     */
+    public OSRFRegistry getRegistry() {
+        return registry;
+    }
+
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/MethodException.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/MethodException.java
new file mode 100644 (file)
index 0000000..f87e638
--- /dev/null
@@ -0,0 +1,14 @@
+package org.opensrf;
+
+/**
+ * Thrown when the server responds with a method exception.
+ */
+public class MethodException extends Exception {
+    public MethodException(String info) {
+        super(info);
+    }
+    public MethodException(Throwable cause) {
+        super(cause);
+    }
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/MultiSession.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/MultiSession.java
new file mode 100644 (file)
index 0000000..a312aff
--- /dev/null
@@ -0,0 +1,123 @@
+package org.opensrf;
+import java.util.List;
+import java.util.ArrayList;
+import org.opensrf.util.ConfigException;
+
+public class MultiSession {
+
+    class RequestContainer {
+        Request request;
+        int id;
+        RequestContainer(Request r) {
+            request = r; 
+        }
+    }
+
+    private boolean complete;
+    private List<RequestContainer> requests;
+    private int lastId;
+
+    public MultiSession() {
+        requests = new ArrayList<RequestContainer>();
+    }
+
+    public boolean isComplete() {
+        return complete;
+    }
+
+    public int lastId() {
+        return lastId;
+    }
+
+    /**
+     * Adds a new request to the set of requests.
+     * @param service The OpenSRF service
+     * @param method The OpenSRF method
+     * @param params The array of method params
+     * @return The request ID, which is used to map results from recv() to the original request.
+     */
+    public int request(String service, String method, Object[] params) throws SessionException, ConfigException {
+        ClientSession ses = new ClientSession(service);
+        return request(ses.request(method, params));
+    }
+
+
+    public int request(String service, String method) throws SessionException, ConfigException {
+        ClientSession ses = new ClientSession(service);
+        return request(ses.request(method));
+    }
+
+    private int request(Request req) {
+        RequestContainer c = new RequestContainer(req);
+        c.id = requests.size();
+        requests.add(c);
+        return c.id;
+    }
+
+
+    /**
+     * Calls recv on all pending requests until there is data to return.  The ID which
+     * maps the received object to the request can be retrieved by calling lastId().
+     * @param millis Number of milliseconds to wait for some data to arrive.
+     * @return The object result or null if all requests are complete
+     * @throws MethodException Thrown if no response is received within 
+     * the given timeout or the method fails.
+     */
+    public Object recv(int millis) throws MethodException {
+        if(complete) return null;
+
+        Request req = null;
+        Result res = null;
+        RequestContainer cont = null;
+
+        long duration = 0;
+        long blockTime = 100;
+
+        /* if there is only 1 outstanding request, don't poll */
+        if(requests.size() == 1)
+            blockTime = millis;
+
+        while(true) {
+            for(int i = 0; i < requests.size(); i++) {
+
+                cont = requests.get(i);
+                req = cont.request;
+
+                try {
+                    if(i == 0) {
+                        res = req.recv(blockTime);
+                    } else {
+                        res = req.recv(0);
+                    }
+                } catch(SessionException e) {
+                    throw new MethodException(e);
+                }
+
+                if(res != null) break;
+            }
+
+            if(res != null) break;
+            duration += blockTime;
+
+            if(duration >= millis) {
+                System.out.println("duration = " + duration + " millis = " + millis);
+                throw new MethodException("No request received within " + millis + " milliseconds");
+            }
+        }
+
+        if(res.getStatusCode() != 200) {
+            throw new MethodException("Request " + cont.id + " failed  with status code " + 
+                res.getStatusCode() + " and status message " + res.getStatus());
+        }
+
+        if(req.isComplete())
+            requests.remove(requests.indexOf(cont));
+
+        if(requests.size() == 0)
+            complete = true;
+
+        lastId = cont.id;
+        return res.getContent();
+    }
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/Request.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/Request.java
new file mode 100644 (file)
index 0000000..2d72e2d
--- /dev/null
@@ -0,0 +1,138 @@
+package org.opensrf;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.List;
+import java.util.Date;
+import org.opensrf.net.xmpp.XMPPException;
+import org.opensrf.util.Logger;
+
+public class Request {
+    
+    /** This request's controlling session */
+    private ClientSession session;
+    /** The method */
+    private Method method;
+    /** The ID of this request */
+    private int id;
+    /** Queue of Results */
+    private Queue<Result> resultQueue;
+    /** If true, the receive timeout for this request should be reset */
+    private boolean resetTimeout;
+
+    /** If true, the server has indicated that this request is complete. */
+    private boolean complete;
+
+    /**
+     * @param ses The controlling session for this request.
+     * @param id This request's ID.
+     * @param method The requested method.
+     */
+    public Request(ClientSession ses, int id, Method method) {
+        this.session = ses;
+        this.id = id;
+        this.method = method;
+        resultQueue = new ConcurrentLinkedQueue<Result>();
+        complete = false;
+        resetTimeout = false;
+    }
+
+    /**
+     * @param ses The controlling session for this request.
+     * @param id This request's ID.
+     * @param methodName The requested method's API name.
+     */
+    public Request(ClientSession ses, int id, String methodName) {
+        this(ses, id, new Method(methodName));
+    }
+
+    /**
+     * @param ses The controlling session for this request.
+     * @param id This request's ID.
+     * @param methodName The requested method's API name.
+     * @param params The list of request params
+     */
+    public Request(ClientSession ses, int id, String methodName, List<Object> params) {
+        this(ses, id, new Method(methodName, params));
+    }
+
+    /**
+     * Sends the request to the server.
+     */
+    public void send() throws SessionException {
+        session.send(new Message(id, Message.REQUEST, method, session.getLocale()));
+    }
+
+    /**
+     * Receives the next result for this request.  This method
+     * will wait up to the specified number of milliseconds for 
+     * a response. 
+     * @param millis Number of milliseconds to wait for a result.  If
+     * negative, this method will wait indefinitely.
+     * @return The result or null if none arrives in time
+     */
+    public Result recv(long millis) throws SessionException, MethodException {
+
+        Result result = null;
+
+        if((result = resultQueue.poll()) != null)
+            return result;
+
+        if(millis < 0 && !complete) {
+            /** wait potentially forever for a result to arrive */
+            while(!complete) {
+                session.waitForMessage(millis);
+                if((result = resultQueue.poll()) != null)
+                    return result;
+            }
+
+        } else {
+
+            while(millis >= 0 && !complete) {
+
+                /** wait up to millis milliseconds for a result.  waitForMessage() 
+                 * will return if a response to any request arrives, so we keep track
+                 * of how long we've been waiting in total for a response to 
+                 * this request */
+
+                long start = new Date().getTime();
+                session.waitForMessage(millis);
+                millis -= new Date().getTime() - start;
+                if((result = resultQueue.poll()) != null)
+                    return result;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Pushes a result onto the result queue 
+     * @param result The result to push
+     */
+    public void pushResponse(Result result) {
+        resultQueue.offer(result);
+    }
+
+    /**
+     * @return This request's ID
+     */
+    public int getId() {
+        return id;
+    }
+
+    /**
+     * Removes this request from the controlling session's request set
+     */
+    public void cleanup() {
+        session.cleanupRequest(id);
+    }
+
+    /** Sets this request as complete */
+    public void setComplete() {
+        complete = true;
+    }
+
+    public boolean isComplete() {
+        return complete;
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/Result.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/Result.java
new file mode 100644 (file)
index 0000000..80b71dd
--- /dev/null
@@ -0,0 +1,106 @@
+package org.opensrf;
+import org.opensrf.util.*;
+
+
+/**
+ * Models a single result from a method request.
+ */
+public class Result implements OSRFSerializable {
+
+    /** Method result content */
+    private Object content;
+    /** Name of the status */
+    private String status;
+    /** Status code number */
+    private int statusCode;
+
+
+    /** Register this object */
+    private static OSRFRegistry registry = 
+        OSRFRegistry.registerObject(
+            "osrfResult", 
+            OSRFRegistry.WireProtocol.HASH, 
+            new String[] {"status", "statusCode", "content"});
+
+
+    /**
+     * @param status The status message for this result
+     * @param statusCode The status code
+     * @param content The content of the result
+     */
+    public Result(String status, int statusCode, Object content) {
+        this.status = status;
+        this.statusCode = statusCode;
+        this.content = content;
+    }
+    
+    /**
+     * Get status.
+     * @return status as String.
+     */
+    public String getStatus() {
+        return status;
+    }
+    
+    /**
+     * Set status.
+     * @param status the value to set.
+     */
+    public void setStatus(String status) {
+        this.status = status;
+    }
+    
+    /**
+     * Get statusCode.
+     * @return statusCode as int.
+     */
+    public int getStatusCode() {
+        return statusCode;
+    }
+    
+    /**
+     * Set statusCode.
+     * @param statusCode the value to set.
+     */
+    public void setStatusCode(int statusCode) {
+        this.statusCode = statusCode;
+    }
+    
+    /**
+     * Get content.
+     * @return content as Object.
+     */
+    public Object getContent() {
+        return content;
+    }
+    
+    /**
+     * Set content.
+     * @param content the value to set.
+     */
+    public void setContent(Object content) {
+        this.content = content;
+    }
+
+    /**
+     * Implements the generic get() API required by OSRFSerializable
+     */
+    public Object get(String field) {
+        if("status".equals(field))
+            return getStatus();
+        if("statusCode".equals(field))
+            return getStatusCode();
+        if("content".equals(field))
+            return getContent();
+        return null;
+    }
+
+    /**
+     * @return The osrfMethod registry.
+     */
+    public OSRFRegistry getRegistry() {
+        return registry;
+    }
+
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/ServerSession.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/ServerSession.java
new file mode 100644 (file)
index 0000000..62e5133
--- /dev/null
@@ -0,0 +1,8 @@
+package org.opensrf;
+
+/**
+ * Models an OpenSRF server session.
+ */
+public class ServerSession extends Session {
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/Session.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/Session.java
new file mode 100644 (file)
index 0000000..15fd352
--- /dev/null
@@ -0,0 +1,180 @@
+package org.opensrf;
+import org.opensrf.util.JSONWriter;
+import org.opensrf.net.xmpp.*;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Arrays;
+
+public abstract class Session {
+
+    /** Represents the different connection states for a session */
+    public enum ConnectState {
+        DISCONNECTED,
+        CONNECTING,
+        CONNECTED
+    };
+
+    /** local cache of existing sessions */
+    private static Map<String, Session> 
+        sessionCache = new HashMap<String, Session>();
+
+    /** the current connection state */
+    private ConnectState connectState;
+
+    /** The address of the remote party we are communicating with */
+    private String remoteNode;
+
+    /** Session locale */
+    protected String locale;
+    /** Default session locale */
+    protected static String defaultLocale = "en-US";
+
+    /** 
+     * The thread is used to link messages to a given session. 
+     * In other words, each session has a unique thread, and all messages 
+     * in that session will carry this thread around as an indicator.
+     */
+    private String thread;
+
+    public Session() {
+        connectState = ConnectState.DISCONNECTED;
+    }
+    
+    /**
+     * Sends a Message to our remoteNode.
+     */
+    public void send(Message omsg) throws SessionException {
+
+        /** construct the XMPP message */
+        XMPPMessage xmsg = new XMPPMessage();
+        xmsg.setTo(remoteNode);
+        xmsg.setThread(thread);
+        xmsg.setBody(new JSONWriter(Arrays.asList(new Message[] {omsg})).write());
+
+        try {
+            XMPPSession.getThreadSession().send(xmsg);
+        } catch(XMPPException e) {
+            connectState = ConnectState.DISCONNECTED;
+            throw new SessionException("Error sending message to " + remoteNode, e);
+        }
+    }
+
+    /**
+     * Waits for a message to arrive over the network and passes
+     * all received messages to the stack for processing
+     * @param millis The number of milliseconds to wait for a message to arrive
+     */
+    public static void waitForMessage(long millis) throws SessionException, MethodException {
+        try {
+            Stack.processXMPPMessage(
+                XMPPSession.getThreadSession().recv(millis));
+        } catch(XMPPException e) {
+            throw new SessionException("Error waiting for message", e);
+        }
+    }
+
+    /**
+     * Removes this session from the session cache.
+     */
+    public void cleanup() {
+        sessionCache.remove(thread);
+    }
+
+    /**
+     * Searches for the cached session with the given thread.
+     * @param thread The session thread.
+     * @return The found session or null.
+     */
+    public static Session findCachedSession(String thread) {
+        return sessionCache.get(thread);
+    }
+
+    /**
+     * Puts this session into session cache.
+     */
+    protected void cacheSession() {
+        sessionCache.put(thread, this);
+    }
+
+    /**
+     * Sets the remote address
+     * @param nodeName The name of the remote node.
+     */
+    public void setRemoteNode(String nodeName) {
+        remoteNode = nodeName;
+    }
+    /**
+     * @return The remote node
+     */
+    public String getRemoteNode() {
+        return remoteNode;
+    }
+
+
+    /**
+     * Get thread.
+     * @return thread as String.
+     */
+    public String getThread() {
+        return thread;
+    }
+    
+    /**
+     * Set thread.
+     * @param thread the value to set.
+     */
+    public void setThread(String thread) {
+        this.thread = thread;
+    }
+
+    /**
+     * Get locale.
+     * @return locale as String.
+     */
+    public String getLocale() {
+        if(locale == null)
+            return defaultLocale;
+        return locale;
+    }
+    
+    /**
+     * Set locale.
+     * @param locale the value to set.
+     */
+    public void setLocale(String locale) {
+        this.locale = locale;
+    }
+
+    /**
+     * Get defaultLocale.
+     * @return defaultLocale as String.
+     */
+    public String getDefaultLocale() {
+        return defaultLocale;
+    }
+    
+    /**
+     * Set defaultLocale.
+     * @param defaultLocale the value to set.
+     */
+    public void setDefaultLocale(String defaultLocale) {
+        this.defaultLocale = defaultLocale;
+    }
+
+    
+    /**
+     * Get connectState.
+     * @return connectState as ConnectState.
+     */
+    public ConnectState getConnectState() {
+        return connectState;
+    }
+    
+    /**
+     * Set connectState.
+     * @param connectState the value to set.
+     */
+    public void setConnectState(ConnectState connectState) {
+        this.connectState = connectState;
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/SessionException.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/SessionException.java
new file mode 100644 (file)
index 0000000..bd90a76
--- /dev/null
@@ -0,0 +1,13 @@
+package org.opensrf;
+/**
+ * Used by sessions to indicate communication errors
+ */
+public class SessionException extends Exception {
+    public SessionException(String info) {
+        super(info);
+    }
+    public SessionException(String info, Throwable cause) {
+        super(info, cause);
+    }
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/Stack.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/Stack.java
new file mode 100644 (file)
index 0000000..3e7e606
--- /dev/null
@@ -0,0 +1,105 @@
+package org.opensrf;
+import org.opensrf.net.xmpp.XMPPMessage;
+import org.opensrf.util.*;
+import java.util.Date;
+import java.util.List;
+import java.util.Iterator;
+
+
+public class Stack {
+
+    public static void processXMPPMessage(XMPPMessage msg) throws MethodException {
+
+        if(msg == null) return;
+
+        //System.out.println(msg.getBody());
+
+        /** fetch this session from the cache */
+        Session ses = Session.findCachedSession(msg.getThread());
+
+        if(ses == null) {
+            /** inbound client request, create a new server session */
+            return;
+        }
+
+        /** parse the JSON message body, which should result in a list of OpenSRF messages */
+        List msgList; 
+
+        try {
+            msgList = new JSONReader(msg.getBody()).readArray();
+        } catch(JSONException e) {
+            /** XXX LOG error */
+            e.printStackTrace();
+            return;
+        }
+
+        Iterator itr = msgList.iterator();
+
+        OSRFObject obj = null;
+        long start = new Date().getTime();
+
+        /** cycle through the messages and push them up the stack */
+        while(itr.hasNext()) {
+
+            /** Construct a Message object from the parsed generic OSRFObject */
+            obj = (OSRFObject) itr.next();
+
+            processOSRFMessage(
+                ses, 
+                new Message(
+                    obj.getInt("threadTrace"),
+                    obj.getString("type"),
+                    obj.get("payload")
+                )
+            );
+        }
+
+        /** LOG the duration */
+    }
+
+    private static void processOSRFMessage(Session ses, Message msg) throws MethodException {
+
+        Logger.debug("received id=" + msg.getId() + 
+            " type=" + msg.getType() + " payload=" + msg.getPayload());
+
+        if( ses instanceof ClientSession ) 
+            processResponse((ClientSession) ses, msg);
+        else
+            processRequest((ServerSession) ses, msg);
+    }
+
+    /** 
+     * Process a server response
+     */
+    private static void processResponse(ClientSession session, Message msg) throws MethodException {
+        String type = msg.getType();
+
+        if(msg.RESULT.equals(type)) {
+            session.pushResponse(msg);
+            return;
+        }
+
+        if(msg.STATUS.equals(type)) {
+
+            OSRFObject obj = (OSRFObject) msg.getPayload();
+            Status stat = new Status(obj.getString("status"), obj.getInt("statusCode"));
+            int statusCode = stat.getStatusCode();
+            String status = stat.getStatus();
+
+            switch(statusCode) {
+                case Status.COMPLETE:
+                    session.setRequestComplete(msg.getId());
+                    break;
+                case Status.NOTFOUND: 
+                    session.setRequestComplete(msg.getId());
+                    throw new MethodException(status);
+            }
+        }
+    }
+
+    /**
+     * Process a client request
+     */
+    private static void processRequest(ServerSession session, Message msg) {
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/Status.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/Status.java
new file mode 100644 (file)
index 0000000..8026c7b
--- /dev/null
@@ -0,0 +1,63 @@
+package org.opensrf;
+import org.opensrf.util.*;
+
+public class Status {
+
+    public static final int CONTINUE            = 100;
+    public static final int OK                  = 200;
+    public static final int ACCEPTED            = 202;
+    public static final int COMPLETE            = 205;
+    public static final int REDIRECTED          = 307;
+    public static final int EST                 = 400;
+    public static final int STATUS_UNAUTHORIZED = 401;
+    public static final int FORBIDDEN           = 403;
+    public static final int NOTFOUND            = 404;
+    public static final int NOTALLOWED          = 405;
+    public static final int TIMEOUT             = 408;
+    public static final int EXPFAILED           = 417;
+    public static final int INTERNALSERVERERROR = 500;
+    public static final int NOTIMPLEMENTED      = 501;
+    public static final int VERSIONNOTSUPPORTED = 505;
+
+    private OSRFRegistry registry = OSRFRegistry.registerObject(
+        "osrfConnectStatus",
+        OSRFRegistry.WireProtocol.HASH,
+        new String[] {"status", "statusCode"});
+
+    /** The name of the status */
+    String status;
+    /** The status code */
+    int statusCode;
+
+    public Status(String status, int statusCode) {
+        this.status = status;
+        this.statusCode = statusCode;
+    }
+
+    public int getStatusCode() {
+        return statusCode;
+    }
+    public String getStatus() {
+        return status;
+    }
+
+    /**
+     * Implements the generic get() API required by OSRFSerializable
+     */
+    public Object get(String field) {
+        if("status".equals(field))
+            return getStatus();
+        if("statusCode".equals(field))
+            return new Integer(getStatusCode());
+        return null;
+    }
+
+    /**
+     * @return The osrfMessage registry.
+     */
+    public OSRFRegistry getRegistry() {
+        return registry;
+    }
+}
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/Sys.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/Sys.java
new file mode 100644 (file)
index 0000000..d65f8a4
--- /dev/null
@@ -0,0 +1,86 @@
+package org.opensrf;
+
+import org.opensrf.util.*;
+import org.opensrf.net.xmpp.*;
+import java.util.Random;
+import java.util.Date;
+import java.net.InetAddress;
+
+
+public class Sys {
+
+    private static void initLogger(Config config) {
+        if(Logger.instance() == null) {
+            try {
+                String logFile = config.getString("/logfile");
+                int logLevel = config.getInt("/loglevel");
+                Logger.init( (short) config.getInt("/loglevel"), new FileLogger(logFile));
+                /** add syslog support... */
+            } catch(Exception e) {
+                /* by default, log to stderr at WARN level */
+                Logger.init(Logger.WARN, new Logger()); 
+            }
+        }
+    }
+
+    /**
+     * Connects to the OpenSRF network so that client sessions may communicate.
+     * @param configFile The OpenSRF config file 
+     * @param configContext Where in the XML document the config chunk lives.  This
+     * allows an OpenSRF client config chunk to live in XML files where other config
+     * information lives.
+     */
+    public static void bootstrapClient(String configFile, String configContext) 
+            throws ConfigException, SessionException  {
+
+
+        /** see if the current thread already has a connection */
+        XMPPSession existing = XMPPSession.getThreadSession();
+        if(existing != null && existing.connected())
+            return;
+
+        /** create the config parser */
+        Config config = new Config(configContext);
+        config.parse(configFile);
+        Config.setConfig(config); /* set this as the global config */
+
+        initLogger(config);
+
+        /** Collect the network connection info from the config */
+        String username = config.getString("/username");
+        String passwd = config.getString("/passwd");
+        String host = (String) config.getFirst("/domain");
+        int port = config.getInt("/port");
+
+
+        /** Create a random login resource string */
+        String res = "java_";
+        try {
+            res += InetAddress.getLocalHost().getHostAddress();
+        } catch(java.net.UnknownHostException e) {}
+        res += "_"+Math.abs(new Random(new Date().getTime()).nextInt()) 
+            + "_t"+ Thread.currentThread().getId();
+
+
+
+        try {
+
+            /** Connect to the Jabber network */
+            Logger.info("attempting to create XMPP session "+username+"@"+host+"/"+res);
+            XMPPSession xses = new XMPPSession(host, port);
+            xses.connect(username, passwd, res);
+            XMPPSession.setThreadSession(xses);
+
+        } catch(XMPPException e) {
+            throw new SessionException("Unable to bootstrap client", e);
+        }
+    }
+
+    /**
+     * Shuts down the connection to the opensrf network
+     */
+    public static void shutdown() {
+        XMPPSession.getThreadSession().disconnect();
+    }
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/GatewayRequest.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/GatewayRequest.java
new file mode 100644 (file)
index 0000000..61d7306
--- /dev/null
@@ -0,0 +1,140 @@
+package org.opensrf.net.http;
+
+import android.util.Log;
+import org.json.JSONObject;
+import org.opensrf.*;
+import org.opensrf.util.*;
+
+import java.io.IOException;
+import java.io.BufferedInputStream;
+import java.io.OutputStreamWriter;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URI;
+import java.net.HttpURLConnection;
+import java.lang.StringBuffer;
+import java.util.List;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class GatewayRequest extends HttpRequest {
+
+    private boolean readComplete;
+    private String TAG = GatewayRequest.class.getName();
+
+    public GatewayRequest(HttpConnection conn, String service, Method method) {
+        super(conn, service, method);
+        readComplete = false;
+    }
+
+    public GatewayRequest send() {
+        try {
+
+            String postData = compilePostData(service, method);
+
+            urlConn = (HttpURLConnection) httpConn.url.openConnection();
+            urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
+            urlConn.setDoInput(true);
+            urlConn.setDoOutput(true);
+
+            
+            
+            OutputStreamWriter wr = new OutputStreamWriter(urlConn.getOutputStream());
+            wr.write(postData);
+            wr.flush();
+            wr.close();
+
+        } catch (java.io.IOException ex) {
+            failed = true;
+            failure = ex;
+        }
+
+        return this;
+    }
+
+    public Object recv() {
+
+        if (readComplete) 
+            return nextResponse();
+
+        try {
+
+            InputStream netStream = new BufferedInputStream(urlConn.getInputStream());
+            StringBuffer readBuf = new StringBuffer();
+
+            int bytesRead = 0;
+            byte[] buffer = new byte[1024];
+
+            while ((bytesRead = netStream.read(buffer)) != -1) {
+                readBuf.append(new String(buffer, 0, bytesRead));
+            }
+            
+            netStream.close();
+            urlConn = null;
+
+            Map<String,?> result = null;
+
+            //System.out.println("osrf: Received " +  readBuf.toString());
+            //Log.d(TAG, "received:" +  readBuf.toString());
+            try {
+                result = (Map<String, ?>) new JSONReader(readBuf.toString()).readObject();
+            } catch (org.opensrf.util.JSONException ex) {
+                ex.printStackTrace();
+                return null;
+            }
+            //System.out.println("osrf: Converted object " + result);
+            Log.d(TAG, "service:" + this.service
+                    + " method:" + this.method.getName()
+                    + " result:" + new JSONObject(result).toString());
+            String status = result.get("status").toString();
+            if (!"200".equals(status)) {
+                failed = true;
+                // failure = <some new exception>
+            }
+
+             // gateway always returns a wrapper array with the full results set
+             responseList = (List) result.get("payload"); 
+
+            // System.out.println("Response list : " + responseList);
+        } catch (java.io.IOException ex) { 
+            failed = true;
+            failure = ex;
+        }
+
+        readComplete = true;
+        return nextResponse();
+    }
+
+    private String compilePostData(String service, Method method) {
+        URI uri = null;
+        StringBuffer postData = new StringBuffer();
+
+        postData.append("service=");
+        postData.append(service);
+        postData.append("&method=");
+        postData.append(method.getName());
+
+        List params = method.getParams();
+        Iterator itr = params.iterator();
+
+        while (itr.hasNext()) {
+            postData.append("&param=");
+            postData.append(new JSONWriter(itr.next()).write());
+        }
+
+        try {
+            // not using URLEncoder because it replaces ' ' with '+'.
+            uri = new URI("http", "", null, postData.toString(), null);
+        } catch (java.net.URISyntaxException ex) {
+            ex.printStackTrace(); 
+        }
+
+        return uri.getRawQuery();
+    }
+}
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/HttpConnection.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/HttpConnection.java
new file mode 100644 (file)
index 0000000..32fdebc
--- /dev/null
@@ -0,0 +1,97 @@
+package org.opensrf.net.http;
+
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import org.opensrf.*;
+import org.opensrf.util.*;
+
+
+/**
+ * Manages connection parameters and thread limiting for opensrf json gateway connections.
+ */
+
+public class HttpConnection {
+
+    /** Compiled URL object */
+    protected URL url;
+    /** Number of threads currently communicating with the server */
+    protected int activeThreads;
+    /** Queue of pending async requests */
+    protected Queue<HttpRequest> pendingThreadQueue;
+    /** maximum number of actively communicating threads allowed */
+    protected int maxThreads = 10;
+
+    public HttpConnection(String fullUrl) throws java.net.MalformedURLException {
+        activeThreads = 0;
+        pendingThreadQueue = new ConcurrentLinkedQueue();
+        url = new URL(fullUrl);
+    }
+
+    public int getMaxThreads() {
+        return maxThreads;
+    }
+
+    /** 
+     * Set the maximum number of actively communicating threads allowed 
+     */
+    public void setMaxThreads(int max) {
+        maxThreads = max;
+    }
+
+    /**
+     * Launches or queues an asynchronous request.
+     *
+     * If the maximum active thread count has not been reached,
+     * start a new thread and use it to send and receive the request.
+     * The response is passed to the request's HttpRequestHandler
+     * onComplete().  After complete, if the number of active threads
+     * is still lower than the max, one request will be pulled (if 
+     * present) from the async queue and fired.
+     *
+     * If there are too many active threads, the main request is
+     * pushed onto the async queue for later processing
+     */
+    protected void manageAsyncRequest(final HttpRequest request) {
+
+        if (activeThreads >= maxThreads) {
+            pendingThreadQueue.offer(request);
+            return;
+        }
+
+        activeThreads++;
+
+         //Send the request receive the response, fire off the next 
+         //thread if necessary, then pass the result to the handler
+        Runnable r = new Runnable() {
+            public void run() {
+
+                Object response;
+                request.send();
+
+                while ((response = request.recv()) != null) {
+                    if (request.handler != null) 
+                        request.handler.onResponse(request, response);
+                }
+
+                if (request.handler != null)
+                    request.handler.onComplete(request);
+
+                activeThreads--;
+
+                if (activeThreads < maxThreads) {
+                    try {
+                        manageAsyncRequest(pendingThreadQueue.remove());
+                    } catch (java.util.NoSuchElementException ex) {
+                        // may have been gobbled by another thread
+                    }
+                }
+            }
+        };
+
+        new Thread(r).start();
+    }
+}
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/HttpRequest.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/HttpRequest.java
new file mode 100644 (file)
index 0000000..8af4623
--- /dev/null
@@ -0,0 +1,70 @@
+package org.opensrf.net.http;
+import org.opensrf.*;
+import org.opensrf.util.*;
+
+import java.util.List;
+import java.util.LinkedList;
+import java.net.HttpURLConnection;
+
+public abstract class HttpRequest {
+
+    protected String service;
+    protected Method method;
+    protected HttpURLConnection urlConn;
+    protected HttpConnection httpConn;
+    protected HttpRequestHandler handler;
+    protected List<Object> responseList;
+    protected Exception failure;
+    protected boolean failed;
+    protected boolean complete;
+
+    public HttpRequest() {
+        failed = false;
+        complete = false;
+        handler = null;
+        urlConn = null;
+    }
+
+    public HttpRequest(HttpConnection conn, String service, Method method) {
+        this();
+        this.httpConn = conn;
+        this.service = service;
+        this.method = method;
+    }
+
+    public void sendAsync(final HttpRequestHandler handler) {
+        this.handler = handler;
+        httpConn.manageAsyncRequest(this);
+    }
+
+    protected void pushResponse(Object response) {
+        if (responseList == null)
+            responseList = new LinkedList<Object>();
+        responseList.add(response);
+    }
+
+    protected List responses() {
+        return responseList;
+    }
+    
+    protected Object nextResponse() {
+        if (complete || failed) return null;
+        if (responseList.size() > 0)
+            return responseList.remove(0);
+        return null;
+    }
+
+    public Exception getFailure() {
+        return failure;
+    }
+
+    public abstract HttpRequest send();
+
+    public abstract Object recv();
+    
+    public boolean failed(){
+       return failed;
+    }
+}
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/HttpRequestHandler.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/net/http/HttpRequestHandler.java
new file mode 100644 (file)
index 0000000..9c0f9e5
--- /dev/null
@@ -0,0 +1,25 @@
+package org.opensrf.net.http;
+
+import java.util.List;
+
+/*
+ * Handler for async gateway responses.
+ */
+public abstract class HttpRequestHandler {
+
+    /**
+     * Called when all responses have been received.
+     *
+     * If discardResponses() returns true, will be passed null.
+     */
+    public void onComplete(HttpRequest request) {
+    }
+
+    /**
+     * Called with each response received from the server.
+     * 
+     * @param payload the value returned from the server.
+     */
+    public void onResponse(HttpRequest request, Object response) {
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPException.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPException.java
new file mode 100644 (file)
index 0000000..8c20ab7
--- /dev/null
@@ -0,0 +1,10 @@
+package org.opensrf.net.xmpp;
+
+/**
+ * Used for XMPP stream/authentication errors
+ */
+public class XMPPException extends Exception {
+    public XMPPException(String info) {
+        super(info);
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPMessage.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPMessage.java
new file mode 100644 (file)
index 0000000..b6e2c76
--- /dev/null
@@ -0,0 +1,101 @@
+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("&lt;");
+                    break;
+                case '>': 
+                    sb.append("&gt;");
+                    break;
+                case '&': 
+                    sb.append("&amp;");
+                    break;
+                default:
+                    sb.append(c);
+            }
+        }
+    }
+}
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPReader.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPReader.java
new file mode 100644 (file)
index 0000000..406298a
--- /dev/null
@@ -0,0 +1,293 @@
+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;
+        }
+    }
+}
+
+
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPSession.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/net/xmpp/XMPPSession.java
new file mode 100644 (file)
index 0000000..f9be7d2
--- /dev/null
@@ -0,0 +1,263 @@
+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) {}
+    }
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/MathBench.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/MathBench.java
new file mode 100644 (file)
index 0000000..b6e67f9
--- /dev/null
@@ -0,0 +1,79 @@
+package org.opensrf.test;
+import org.opensrf.*;
+import org.opensrf.util.*;
+import java.util.Date;
+import java.util.List;
+import java.util.ArrayList;
+import java.io.PrintStream;
+
+
+public class MathBench {
+
+    public static void main(String args[]) throws Exception {
+
+        PrintStream out = System.out;
+
+        if(args.length < 2) {
+            out.println("usage: java org.opensrf.test.MathBench <osrfConfig> <numIterations>");
+            return;
+        }
+
+        /** connect to the opensrf network */
+        Sys.bootstrapClient(args[0], "/config/opensrf");
+
+        /** how many iterations */
+        int count = Integer.parseInt(args[1]);
+
+        /** create the client session */
+        ClientSession session = new ClientSession("opensrf.math");
+
+        /** params are 1,2 */
+        List<Object> params = new ArrayList<Object>();
+        params.add(new Integer(1));
+        params.add(new Integer(2));
+
+        Request request;
+        Result result;
+        long start;
+        double total = 0;
+
+        for(int i = 0; i < count; i++) {
+
+            start = new Date().getTime();
+
+            /** create (and send) the request */
+            request = session.request("add", params);
+
+            /** wait up to 3 seconds for a response */
+            result = request.recv(3000);
+
+            /** collect the round-trip time */
+            total += new Date().getTime() - start;
+
+            if(result.getStatusCode() == Status.OK) {
+                out.print("+");
+            } else {
+                out.println("\nrequest failed");
+                out.println("status = " + result.getStatus());
+                out.println("status code = " + result.getStatusCode());
+            }
+
+            /** remove this request from the session's request set */
+            request.cleanup();
+
+            if((i+1) % 100 == 0) /** print 100 responses per line */
+                out.println(" [" + (i+1) + "]");
+        }
+
+        out.println("\nAverage request time is " + (total/count) + " ms");
+        
+        /** remove this session from the global session cache */
+        session.cleanup();
+
+        /** disconnect from the opensrf network */
+        Sys.shutdown();
+    }
+}
+
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestCache.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestCache.java
new file mode 100644 (file)
index 0000000..d555444
--- /dev/null
@@ -0,0 +1,24 @@
+package org.opensrf.test;
+import org.opensrf.util.Cache;
+
+public class TestCache {
+    public static void main(String args[]) throws Exception {
+
+        /**
+         * args is a list of string like so:  server:port server2:port server3:port ...
+         */
+
+        Cache.initCache(args);
+        Cache cache = new Cache();
+
+        cache.set("key1", "HI, MA!");
+        cache.set("key2", "HI, MA! 2");
+        cache.set("key3", "HI, MA! 3");
+
+        System.out.println("got key1 = " + (String) cache.get("key1"));
+        System.out.println("got key2 = " + (String) cache.get("key2"));
+        System.out.println("got key3 = " + (String) cache.get("key3"));
+    }
+}
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestClient.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestClient.java
new file mode 100644 (file)
index 0000000..a1136cd
--- /dev/null
@@ -0,0 +1,80 @@
+package org.opensrf.test;
+import org.opensrf.*;
+import org.opensrf.util.*;
+import java.util.Map;
+import java.util.Date;
+import java.util.List;
+import java.util.ArrayList;
+import java.io.PrintStream;
+
+public class TestClient {
+
+    public static void main(String args[]) throws Exception {
+
+        /** which opensrf service are we sending our request to */
+        String service; 
+        /** which opensrf method we're calling */
+        String method;
+        /** method params, captures from command-line args */
+        List<Object> params;
+        /** knows how to read JSON */
+        JSONReader reader;
+        /** opensrf request */
+        Request request;
+        /** request result */
+        Result result;
+        /** start time for the request */
+        long start;
+        /** for brevity */
+        PrintStream out = System.out;
+
+        if(args.length < 3) {
+            out.println( "usage: org.opensrf.test.TestClient "+
+                "<osrfConfigFile> <service> <method> [<JSONparam1>, <JSONparam2>]");
+            return;
+        }
+
+        /** connect to the opensrf network,  default config context 
+         * for opensrf_core.xml is /config/opensrf */
+        Sys.bootstrapClient(args[0], "/config/opensrf");
+
+        /* grab the server, method, and any params from the command line */
+        service = args[1];
+        method = args[2];
+        params = new ArrayList<Object>();
+        for(int i = 3; i < args.length; i++) 
+            params.add(new JSONReader(args[i]).read());
+
+
+        /** build the client session */
+        ClientSession session = new ClientSession(service);
+
+        /** kick off the timer */
+        start = new Date().getTime();
+
+        /** Create the request object from the session, method and params */
+        request = session.request(method, params);
+
+        while( (result = request.recv(60000)) != null ) { 
+            /** loop over the results and print the JSON version of the content */
+
+            if(result.getStatusCode() != 200) { 
+                /** make sure the request succeeded */
+                out.println("status = " + result.getStatus());
+                out.println("status code = " + result.getStatusCode());
+                continue;
+            }
+
+            /** JSON-ify the resulting object and print it */
+            out.println("\nresult JSON: " + new JSONWriter(result.getContent()).write());
+        }
+        
+        /** How long did the request take? */
+        out.println("Request round trip took: " + (new Date().getTime() - start) + " ms.");
+
+        Sys.shutdown();
+    }
+}
+
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestConfig.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestConfig.java
new file mode 100644 (file)
index 0000000..f65a84f
--- /dev/null
@@ -0,0 +1,16 @@
+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]));
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestJSON.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestJSON.java
new file mode 100644 (file)
index 0000000..b19d408
--- /dev/null
@@ -0,0 +1,51 @@
+package org.opensrf.test;
+
+import org.opensrf.*;
+import org.opensrf.util.*;
+import java.util.*;
+
+public class TestJSON {
+
+    public static void main(String args[]) throws Exception {
+        
+        Map<String,Object> map = new HashMap<String,Object>();
+        map.put("key1", "value1");
+        map.put("key2", "value2");
+        map.put("key3", "value3");
+        map.put("key4", "athe\u0301s");
+        map.put("key5", null);
+
+        List<Object> list = new ArrayList<Object>(16);
+        list.add(new Integer(1));
+        list.add(new Boolean(true));
+        list.add("WATER");
+        list.add(null);
+        map.put("key6", list);
+
+        System.out.println(new JSONWriter(map).write() + "\n");
+
+        String[] fields = {"isnew", "name", "shortname", "ill_address"};
+        OSRFRegistry.registerObject("aou", OSRFRegistry.WireProtocol.ARRAY, fields);
+
+        OSRFObject obj = new OSRFObject(OSRFRegistry.getRegistry("aou"));
+        obj.put("name", "athens clarke county");
+        obj.put("ill_address", new Integer(1));
+        obj.put("shortname", "ARL-ATH");
+
+        map.put("key7", obj);
+        list.add(obj);
+        System.out.println(new JSONWriter(map).write() + "\n");
+
+
+        Message m = new Message(1, Message.REQUEST);
+        Method method = new Method("opensrf.settings.host_config.get");
+        method.addParam("app07.dev.gapines.org");
+        m.setPayload(method);
+
+        String s = new JSONWriter(m).write();
+        System.out.println(s + "\n");
+
+        Object o = new JSONReader(s).read();
+        System.out.println("Read+Wrote: " + new JSONWriter(o).write());
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestLog.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestLog.java
new file mode 100644 (file)
index 0000000..1d60242
--- /dev/null
@@ -0,0 +1,15 @@
+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");
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestMultiSession.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestMultiSession.java
new file mode 100644 (file)
index 0000000..bb0f1a1
--- /dev/null
@@ -0,0 +1,26 @@
+package org.opensrf.test;
+import org.opensrf.*;
+import org.opensrf.util.*;
+
+public class TestMultiSession {
+    public static void main(String[] args) {
+        try {
+            String config = args[0];
+
+            Sys.bootstrapClient(config, "/config/opensrf");
+            MultiSession ses = new MultiSession();
+
+            for(int i = 0; i < 40; i++) {
+                ses.request("opensrf.settings", "opensrf.system.time");
+            }
+
+            while(!ses.isComplete()) 
+                System.out.println("result = " + ses.recv(5000) + " and id = " + ses.lastId());
+
+            System.out.println("done");
+            Sys.shutdown();
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestSettings.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestSettings.java
new file mode 100644 (file)
index 0000000..116bbe1
--- /dev/null
@@ -0,0 +1,14 @@
+package org.opensrf.test;
+import org.opensrf.*;
+import org.opensrf.util.*;
+
+public class TestSettings {
+    public static void main(String args[]) throws Exception {
+        Sys.bootstrapClient(args[0], "/config/opensrf");
+        SettingsClient client = SettingsClient.instance();
+        String lang = client.getString("/apps/opensrf.settings/language");
+        String impl = client.getString("/apps/opensrf.settings/implementation");
+        System.out.println("opensrf.settings language = " + lang);
+        System.out.println("opensrf.settings implementation = " + impl);
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestThread.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestThread.java
new file mode 100644 (file)
index 0000000..bb4cf06
--- /dev/null
@@ -0,0 +1,68 @@
+package org.opensrf.test;
+import org.opensrf.*;
+import org.opensrf.util.*;
+import java.util.Map;
+import java.util.Date;
+import java.util.List;
+import java.util.ArrayList;
+import java.io.PrintStream;
+
+/**
+ * Connects to the opensrf network once per thread and runs
+ * and runs a series of request acccross all launched threads.
+ * The purpose is to verify that the java threaded client api 
+ * is functioning as expected
+ */
+public class TestThread implements Runnable {
+
+    String args[];
+
+    public TestThread(String args[]) {
+        this.args = args;
+    }
+
+    public void run() {
+
+        try {
+
+            Sys.bootstrapClient(args[0], "/config/opensrf");
+            ClientSession session = new ClientSession(args[3]);
+    
+            List params = new ArrayList<Object>();
+            for(int i = 5; i < args.length; i++) 
+                params.add(new JSONReader(args[3]).read());
+    
+            for(int i = 0; i < Integer.parseInt(args[2]); i++) {
+                System.out.println("thread " + Thread.currentThread().getId()+" sending request " + i);
+                Request request = session.request(args[4], params);
+                Result result = request.recv(3000);
+                if(result != null) {
+                    System.out.println("thread " + Thread.currentThread().getId()+ 
+                        " got result JSON: " + new JSONWriter(result.getContent()).write());
+                } else {
+                    System.out.println("* thread " + Thread.currentThread().getId()+ " got NO result");
+                }
+            }
+    
+            Sys.shutdown();
+        } catch(Exception e) {
+            System.err.println(e);
+        }
+    }
+
+    public static void main(String args[]) throws Exception {
+
+        if(args.length < 5) {
+            System.out.println( "usage: org.opensrf.test.TestClient "+
+                "<osrfConfigFile> <numthreads> <numiter> <service> <method> [<JSONparam1>, <JSONparam2>]");
+            return;
+        }
+
+        int numThreads = Integer.parseInt(args[1]);
+        for(int i = 0; i < numThreads; i++) 
+            new Thread(new TestThread(args)).start();
+    }
+}
+
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestXMLFlattener.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestXMLFlattener.java
new file mode 100644 (file)
index 0000000..c1fa394
--- /dev/null
@@ -0,0 +1,11 @@
+package org.opensrf.test;
+import org.opensrf.util.XMLFlattener;
+import java.io.FileInputStream;
+
+public class TestXMLFlattener {
+    public static void main(String args[]) throws Exception {
+        FileInputStream fis = new FileInputStream(args[0]);
+        XMLFlattener f = new XMLFlattener(fis);
+        System.out.println(f.read());
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestXMLTransformer.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestXMLTransformer.java
new file mode 100644 (file)
index 0000000..9768372
--- /dev/null
@@ -0,0 +1,22 @@
+package org.opensrf.test;
+import org.opensrf.util.XMLTransformer;
+import java.io.File;
+
+public class TestXMLTransformer {
+    /**
+     * arg[0] path to an XML file
+     * arg[1] path to the XSL file to apply
+     */
+    public static void main(String[] args) {
+        try {
+            File xmlFile = new File(args[0]);
+            File xslFile = new File(args[1]);
+            XMLTransformer t = new XMLTransformer(xmlFile, xslFile);
+            System.out.println(t.apply());
+        } catch(Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestXMPP.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/test/TestXMPP.java
new file mode 100644 (file)
index 0000000..2fba67f
--- /dev/null
@@ -0,0 +1,63 @@
+package org.opensrf.test;
+
+import org.opensrf.net.xmpp.XMPPReader;
+import org.opensrf.net.xmpp.XMPPMessage;
+import org.opensrf.net.xmpp.XMPPSession;
+
+public class TestXMPP {
+
+    /**
+     * Connects to the jabber server and waits for inbound messages.
+     * If a recipient is provided, a small message is sent to the recipient.
+     */
+    public static void main(String args[]) throws Exception {
+
+        String host;
+        int port;
+        String username;
+        String password;
+        String resource;
+        String recipient;
+
+        try {
+            host = args[0];
+            port = Integer.parseInt(args[1]);
+            username = args[2];
+            password = args[3];
+            resource = args[4];
+
+        } catch(ArrayIndexOutOfBoundsException e) {
+            System.err.println("usage: org.opensrf.test.TestXMPP <host> <port> <username> <password> <resource> [<recipient>]");
+            return;
+        }
+
+        XMPPSession session = new XMPPSession(host, port);
+        session.connect(username, password, resource);
+
+        XMPPMessage msg;
+
+        if( args.length == 6 ) {
+
+            /** they specified a recipient */
+
+            recipient = args[5];
+            msg = new XMPPMessage();
+            msg.setTo(recipient);
+            msg.setThread("test-thread");
+            msg.setBody("Hello, from java-xmpp");
+            System.out.println("Sending message to " + recipient);
+            session.send(msg);
+        }
+
+        while(true) {
+            System.out.println("waiting for message...");
+            msg = session.recv(-1); /* wait forever for a message to arrive */
+            System.out.println("got message: " + msg.toXML());
+        }
+    }
+}
+
+
+
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/Cache.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/Cache.java
new file mode 100644 (file)
index 0000000..5303688
--- /dev/null
@@ -0,0 +1,38 @@
+package org.opensrf.util;
+import com.danga.MemCached.*;
+import java.util.List;
+
+/**
+ * Memcache client
+ */
+public class Cache extends MemCachedClient {
+
+    public Cache() {
+        super();
+        setCompressThreshold(4096); /* ?? */
+    }
+
+    /**
+     * Initializes the cache client
+     * @param serverList Array of server:port strings specifying the
+     * set of memcache servers this client will talk to
+     */
+    public static void initCache(String[] serverList) {
+        SockIOPool pool = SockIOPool.getInstance();
+        pool.setServers(serverList);
+        pool.initialize();      
+        com.danga.MemCached.Logger logger = 
+            com.danga.MemCached.Logger.getLogger(MemCachedClient.class.getName());
+        logger.setLevel(logger.LEVEL_ERROR);
+    }
+
+    /**
+     * Initializes the cache client
+     * @param serverList List of server:port strings specifying the
+     * set of memcache servers this client will talk to
+     */
+    public static void initCache(List<String> serverList) {
+        initCache(serverList.toArray(new String[]{}));
+    }
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/Config.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/Config.java
new file mode 100644 (file)
index 0000000..ddac9c0
--- /dev/null
@@ -0,0 +1,139 @@
+package org.opensrf.util;
+
+import org.json.*;
+import java.util.Map;
+import java.util.List;
+
+
+/**
+ * Config reader and accesor module.  This module reads an XML config file,
+ * then loads the file into an internal config, whose values may be accessed
+ * by xpath-style lookup paths.
+ */
+public class Config {
+
+    /** The globl config instance */
+    private static Config config;
+    /** The object form of the parsed config */
+    private Map configObject;
+    /** 
+     * The log parsing context.  This is used as a prefix to the
+     * config item search path.  This allows config XML chunks to 
+     * be inserted into arbitrary XML files.
+     */
+    private String context;
+
+    public static Config global() {
+        return config;
+    }
+
+
+    /**
+     * @param context The config context
+     */
+    public Config(String context) {
+        this.context = context;
+    }
+
+    /**
+     * Sets the global config object.
+     * @param c The config object to use.
+     */
+    public static void setGlobalConfig(Config c) {
+        config = c;
+    }
+
+    /**
+     * Parses an XML config file.
+     * @param filename The path to the file to parse.
+     */
+    public void parse(String filename) throws ConfigException {
+        try {
+            String xml = Utils.fileToString(filename);
+            JSONObject jobj = XML.toJSONObject(xml);
+            configObject = (Map) new JSONReader(jobj.toString()).readObject();
+        } catch(Exception e) {
+            throw new ConfigException("Error parsing config", e);
+        }
+    }
+
+    public static void setConfig(Config conf) {
+        config = conf;
+    }
+
+    public void setConfigObject(Map config) {
+        this.configObject = config;
+    }
+
+    protected Map getConfigObject() {
+        return this.configObject;
+    }
+
+
+    /**
+     * Returns the configuration value found at the requested path.
+     * @param path The search path
+     * @return The config value, or null if no value exists at the given path.  
+     * @throws ConfigException thrown if nothing is found at the path
+     */
+    public String getString(String path) throws ConfigException {
+        try {
+            return (String) get(path);
+        } catch(Exception e) {
+            throw new 
+                ConfigException("No config string found at " + path);
+        }
+    }
+
+    /**
+     * Gets the int value at the given path
+     * @param path The search path
+     */
+    public int getInt(String path) throws ConfigException {
+        try {
+            return Integer.parseInt(getString(path));
+        } catch(Exception e) {
+            throw new
+                ConfigException("No config int found at " + path);
+        }
+    }
+
+    /**
+     * Returns the configuration object found at the requested path.
+     * @param path The search path
+     * @return The config value
+     * @throws ConfigException thrown if nothing is found at the path
+     */
+    public Object get(String path) throws ConfigException {
+        try {
+            Object obj = Utils.findPath(configObject, context + path);
+            if(obj == null)
+                throw new ConfigException("");
+            return obj;
+        } catch(Exception e) {
+            e.printStackTrace();
+            throw new ConfigException("No config object found at " + path);
+        }
+    }
+
+    /**
+     * Returns the first item in the list found at the given path.  If
+     * no list is found, ConfigException is thrown.
+     * @param path The search path
+     */
+    public Object getFirst(String path) throws ConfigException {
+        Object obj = get(path); 
+        if(obj instanceof List) 
+            return ((List) obj).get(0);
+        return obj;
+    }
+
+
+    /**
+     * Returns the config as a JSON string
+     */
+    public String toString() {
+        return new JSONWriter(configObject).write();
+    }
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/ConfigException.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/ConfigException.java
new file mode 100644 (file)
index 0000000..c1c491e
--- /dev/null
@@ -0,0 +1,14 @@
+package org.opensrf.util;
+
+/**
+ * Thrown by the Config module when a user requests a configuration
+ * item that does not exist
+ */
+public class ConfigException extends Exception {
+    public ConfigException(String info) {
+        super(info);
+    }
+    public ConfigException(String info, Throwable t) {
+        super(info, t);
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/FileLogger.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/FileLogger.java
new file mode 100644 (file)
index 0000000..9eb838d
--- /dev/null
@@ -0,0 +1,44 @@
+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) {}
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/JSONException.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/JSONException.java
new file mode 100644 (file)
index 0000000..ec28e1d
--- /dev/null
@@ -0,0 +1,9 @@
+package org.opensrf.util;
+/**
+ * Used to indicate JSON parsing errors
+ */
+public class JSONException extends Exception {
+    public JSONException(String s) {
+        super(s);
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/JSONReader.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/JSONReader.java
new file mode 100644 (file)
index 0000000..55eb5c0
--- /dev/null
@@ -0,0 +1,176 @@
+package org.opensrf.util;
+
+import java.io.*;
+import java.util.*;
+
+import org.json.JSONTokener;
+import org.json.JSONObject;
+import org.json.JSONArray;
+
+
+/**
+ * JSON utilities.
+ */
+public class JSONReader {
+
+    /** Special OpenSRF serializable object netClass key */
+    public static final String JSON_CLASS_KEY = "__c";
+
+    /** Special OpenSRF serializable object payload key */
+    public static final String JSON_PAYLOAD_KEY = "__p";
+
+    /** The JSON string to parser */
+    private String json;
+
+    /**
+     * @param json The JSON to parse
+     */
+    public JSONReader(String json) {
+        this.json = json;
+    }
+
+    /**
+     * Parses JSON and creates an object.
+     * @return The resulting object which may be a List, 
+     * Map, Number, String, Boolean, or null
+     */
+    public Object read() throws JSONException {
+        JSONTokener tk = new JSONTokener(json);
+        try {
+            return readSubObject(tk.nextValue());
+        } catch(org.json.JSONException e) {
+            throw new JSONException(e.toString());
+        }
+    }
+
+    /**
+     * Assumes that a JSON array will be read.  Returns
+     * the resulting array as a list.
+     */
+    public List<?> readArray() throws JSONException {
+        Object o = read();
+        try {
+            return (List<?>) o;
+        } catch(Exception e) {
+            throw new JSONException("readArray(): JSON cast exception");
+        }
+    }
+
+    /**
+     * Assumes that a JSON object will be read.  Returns 
+     * the resulting object as a map.
+     */
+    public Map<?,?> readObject() throws JSONException {
+        Object o = read();
+        try {
+            return (Map<?,?>) o;
+        } catch(Exception e) {
+            throw new JSONException("readObject(): JSON cast exception");
+        }
+    }
+
+
+    /**
+     * Recurse through the object and turn items into maps, lists, etc.
+     */
+    private Object readSubObject(Object obj) throws JSONException {
+
+        if( obj == null || 
+            obj instanceof String || 
+            obj instanceof Number ||
+            obj instanceof Boolean)
+                return obj;
+
+        try {
+
+            if( obj instanceof JSONObject ) {
+
+                /* read objects */
+                String key;
+                JSONObject jobj = (JSONObject) obj;
+                Map<String, Object> map = new HashMap<String, Object>();
+
+                for( Iterator e = jobj.keys(); e.hasNext(); ) {
+                    key = (String) e.next();
+
+                    /* we encoutered the special class key */
+                    if( JSON_CLASS_KEY.equals(key) ) 
+                        return buildRegisteredObject(
+                            (String) jobj.get(key), jobj.get(JSON_PAYLOAD_KEY));
+
+                    /* we encountered the data key */
+                    if( JSON_PAYLOAD_KEY.equals(key) ) 
+                        return buildRegisteredObject(
+                            (String) jobj.get(JSON_CLASS_KEY), jobj.get(key));
+
+                    map.put(key, readSubObject(jobj.get(key)));
+                }
+                return map;
+            } 
+            
+            if ( obj instanceof JSONArray ) {
+
+                JSONArray jarr = (JSONArray) obj;
+                int length = jarr.length();
+                List<Object> list = new ArrayList<Object>(length);
+
+                for( int i = 0; i < length; i++ ) 
+                    list.add(readSubObject(jarr.get(i)));   
+                return list;
+                
+            }
+
+        } catch(org.json.JSONException e) {
+
+            throw new JSONException(e.toString());
+        }
+
+        return null;
+    }
+
+
+
+    /**
+     * Builds an OSRFObject map registered OSRFHash object based on the JSON object data.
+     * @param netClass The network class hint for this object.
+     * @param paylaod The actual object on the wire.
+     */
+    private OSRFObject buildRegisteredObject(
+        String netClass, Object payload) throws JSONException {
+
+        OSRFRegistry registry = OSRFRegistry.getRegistry(netClass);
+        OSRFObject obj = new OSRFObject(registry);
+        try {
+            if( payload instanceof JSONArray ) {
+                JSONArray jarr = (JSONArray) payload;
+
+                /* for each array item, instert the item into the hash.  the hash 
+                 * key is found by extracting the fields array from the registered 
+                 * object at the current array index */
+                String fields[] = registry.getFields();
+                for( int i = 0; i < jarr.length(); i++ ) {
+                    obj.put(fields[i], readSubObject(jarr.get(i)));   
+                }
+
+            } else if( payload instanceof JSONObject ) {
+
+                /* since this is a hash, simply copy the data over */
+                JSONObject jobj = (JSONObject) payload;
+                String key;
+                for( Iterator e = jobj.keys(); e.hasNext(); ) {
+                    key = (String) e.next();
+                    obj.put(key, readSubObject(jobj.get(key)));
+                }
+            }
+
+        } catch(org.json.JSONException e) {
+            throw new JSONException(e.toString());
+        }
+
+        return obj;
+    }
+}
+
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/JSONWriter.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/JSONWriter.java
new file mode 100644 (file)
index 0000000..7cb2cca
--- /dev/null
@@ -0,0 +1,172 @@
+package org.opensrf.util;
+
+import java.io.*;
+import java.util.*;
+
+
+/**
+ * JSONWriter
+ */
+public class JSONWriter {
+
+    /** The object to serialize to JSON */
+    private Object obj;
+
+    /**
+     * @param obj The object to encode
+     */
+    public JSONWriter(Object obj) {
+        this.obj = obj;
+    }
+
+
+    /**
+     * Encodes a java object to JSON.
+     */
+    public String write() {
+        StringBuffer sb = new StringBuffer();
+        write(sb);
+        return sb.toString();
+    }
+
+
+
+    /**
+     * Encodes a java object to JSON.
+     * Maps (HashMaps, etc.) are encoded as JSON objects.  
+     * Iterable's (Lists, etc.) are encoded as JSON arrays
+     */
+    public void write(StringBuffer sb) {
+        write(obj, sb);
+    }
+
+    /**
+     * Encodes the object as JSON into the provided buffer
+     */
+    public void write(Object obj, StringBuffer sb) {
+
+        /** JSON null */
+        if(obj == null) {
+            sb.append("null");
+            return;
+        }
+
+        /** JSON string */
+        if(obj instanceof String) {
+            sb.append('"');
+            Utils.escape((String) obj, sb);
+            sb.append('"');
+            return;
+        }
+
+        /** JSON number */
+        if(obj instanceof Number) {
+            sb.append(obj.toString());
+            return;
+        }
+
+        /** JSON array */
+        if(obj instanceof Iterable) {
+            encodeJSONArray((Iterable) obj, sb);
+            return;
+        }
+
+        /** OpenSRF serializable objects */
+        if(obj instanceof OSRFSerializable) {
+            encodeOSRFSerializable((OSRFSerializable) obj, sb);
+            return;
+        }
+
+        /** JSON object */
+        if(obj instanceof Map) {
+            encodeJSONObject((Map) obj, sb);
+            return;
+        }
+
+        /** JSON boolean */
+        if(obj instanceof Boolean) {
+            sb.append((((Boolean) obj).booleanValue() ? "true" : "false"));
+            return;
+        }
+    }
+
+
+    /**
+     * Encodes a List as a JSON array
+     */
+    private void encodeJSONArray(Iterable iterable, StringBuffer sb) {
+        Iterator itr = iterable.iterator();
+        sb.append("[");
+        boolean some = false;
+
+        while(itr.hasNext()) {
+            some = true;
+            write(itr.next(), sb);
+            sb.append(',');
+        }
+
+        /* remove the trailing comma if the array has any items*/
+        if(some) 
+            sb.deleteCharAt(sb.length()-1); 
+        sb.append("]");
+    }
+
+
+    /**
+     * Encodes a Map as a JSON object
+     */
+    private void encodeJSONObject(Map map, StringBuffer sb) {
+        Iterator itr = map.keySet().iterator();
+        sb.append("{");
+        Object key = null;
+
+        while(itr.hasNext()) {
+            key = itr.next();
+            write(key, sb);
+            sb.append(':');
+            write(map.get(key), sb);
+            sb.append(',');
+        }
+
+        /* remove the trailing comma if the object has any items*/
+        if(key != null) 
+            sb.deleteCharAt(sb.length()-1); 
+        sb.append("}");
+    }
+
+
+    /**
+     * Encodes a network-serializable OpenSRF object
+     */
+    private void encodeOSRFSerializable(OSRFSerializable obj, StringBuffer sb) {
+
+        OSRFRegistry reg = obj.getRegistry();
+        String[] fields = reg.getFields();
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put(JSONReader.JSON_CLASS_KEY, reg.getNetClass());
+
+        if( reg.getWireProtocol() == OSRFRegistry.WireProtocol.ARRAY ) {
+
+            /** encode arrays as lists */
+            List<Object> list = new ArrayList<Object>(fields.length);
+            for(String s : fields)
+                list.add(obj.get(s));
+            map.put(JSONReader.JSON_PAYLOAD_KEY, list);
+
+        } else {
+
+            /** encode hashes as maps */
+            Map<String, Object> subMap = new HashMap<String, Object>();
+            for(String s : fields)
+                subMap.put(s, obj.get(s));
+            map.put(JSONReader.JSON_PAYLOAD_KEY, subMap);
+                
+        }
+
+        /** now serialize the encoded object */
+        write(map, sb);
+    }
+}
+
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/Logger.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/Logger.java
new file mode 100644 (file)
index 0000000..2923c23
--- /dev/null
@@ -0,0 +1,144 @@
+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));
+    }
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/OSRFObject.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/OSRFObject.java
new file mode 100644 (file)
index 0000000..af28f4a
--- /dev/null
@@ -0,0 +1,63 @@
+package org.opensrf.util;
+
+import java.util.Map;
+import java.util.HashMap;
+
+
+/**
+ * Generic OpenSRF network-serializable object.  This allows
+ * access to object fields.  
+ */
+public class OSRFObject extends HashMap<String, Object> implements OSRFSerializable {
+    
+    /** This objects registry */
+    private OSRFRegistry registry;
+
+    public OSRFObject() {
+    }
+
+
+    /**
+     * Creates a new object with the provided registry
+     */
+    public OSRFObject(OSRFRegistry reg) {
+        this();
+        registry = reg;
+    }
+
+
+    /**
+     * Creates a new OpenSRF object based on the net class string
+     * */
+    public OSRFObject(String netClass) {
+        this(OSRFRegistry.getRegistry(netClass));
+    }
+
+
+    /**
+     * @return This object's registry
+     */
+    public OSRFRegistry getRegistry() {
+        return registry;
+    }
+
+    /**
+     * Implement get() to fulfill our contract with OSRFSerializable
+     */
+    public Object get(String field) {
+        return super.get(field);
+    }
+
+    /** Returns the string value found at the given field */
+    public String getString(String field) {
+        return (String) get(field);
+    }
+
+    /** Returns the int value found at the given field */
+    public int getInt(String field) {
+        Object o = get(field);
+        if(o instanceof String)
+            return Integer.parseInt((String) o);
+        return ((Integer) get(field)).intValue();
+    }
+}
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/OSRFRegistry.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/OSRFRegistry.java
new file mode 100644 (file)
index 0000000..c6e6bc6
--- /dev/null
@@ -0,0 +1,112 @@
+package org.opensrf.util;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.HashMap;
+
+
+/**
+ * Manages the registration of OpenSRF network-serializable objects.  
+ * A serializable object has a class "hint" (called netClass within) which
+ * describes the type of object.  Each object also has a set of field names
+ * for accessing/mutating object properties.  Finally, objects have a 
+ * serialization wire protocol.  Currently supported protocols are HASH
+ * and ARRAY.
+ */
+public class OSRFRegistry implements Serializable{
+
+
+    /**
+        * 
+        */
+       private static final long serialVersionUID = 1L;
+       /**
+     * Global collection of registered net objects.  
+     * Maps netClass names to registries.
+     */
+    private static HashMap<String, OSRFRegistry> 
+        registry = new HashMap<String, OSRFRegistry>();
+
+
+    /** Serialization types for registered objects */
+    public enum WireProtocol {
+        ARRAY, HASH
+    };
+
+
+    /** Array of field names for this registered object */
+    String fields[];
+    /** The wire protocol for this object */
+    WireProtocol wireProtocol;
+    /** The network class for this object */
+    String netClass;
+
+    /**
+     * Returns the array of field names
+     */
+    public String[] getFields() {
+        return this.fields;
+    }
+
+
+    /**
+     * Registers a new object.
+     * @param netClass The net class for this object
+     * @param wireProtocol The object's wire protocol
+     * @param fields An array of field names.  For objects whose
+     * wire protocol is ARRAY, the positions of the field names 
+     * will be used as the array indices for the fields at serialization time
+     */
+    public static OSRFRegistry registerObject(String netClass, WireProtocol wireProtocol, String fields[]) {
+        OSRFRegistry r = new OSRFRegistry(netClass, wireProtocol, fields);
+        registry.put(netClass, r);
+        return r;
+    }
+
+    /**
+     * Returns the registry for the given netclass
+     * @param netClass The network class to lookup
+     */
+    public static OSRFRegistry getRegistry(String netClass) {
+        if( netClass == null ) return null;
+        return (OSRFRegistry) registry.get(netClass);
+    }
+
+
+    /**
+     * @param field The name of the field to lookup
+     * @return the index into the fields array of the given field name.
+     */
+    public int getFieldIndex(String field) {
+        for( int i = 0; i < fields.length; i++ )
+            if( fields[i].equals(field) ) 
+                return i;
+        return -1;
+    }
+
+    /** Returns the wire protocol of this object */
+    public WireProtocol getWireProtocol() {
+        return this.wireProtocol;
+    }
+
+    /** Returns the netClass ("hint") of this object */
+    public String getNetClass() {
+        return this.netClass;
+    }
+
+    /**
+     * Creates a new registry object.
+     * @param netClass The network class/hint
+     * @param wireProtocol The wire protocol
+     * @param fields The array of field names.  For array-based objects,
+     * the fields array must be sorted in accordance with the sorting
+     * of the objects in the array.
+     */ 
+    public OSRFRegistry(String netClass, WireProtocol wireProtocol, String fields[]) {
+        this.netClass = netClass;
+        this.wireProtocol = wireProtocol;
+        this.fields = fields;
+    }
+}
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/OSRFSerializable.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/OSRFSerializable.java
new file mode 100644 (file)
index 0000000..64b5d6f
--- /dev/null
@@ -0,0 +1,19 @@
+package org.opensrf.util;
+
+/**
+ * All network-serializable OpenSRF object must implement this interface.
+ */
+public interface OSRFSerializable {
+
+    /**
+     * Returns the object registry object for the implementing class.
+     */
+    public abstract OSRFRegistry getRegistry();
+
+    /**
+     * Returns the object found at the given field
+     */
+    public abstract Object get(String field);
+}
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/SettingsClient.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/SettingsClient.java
new file mode 100644 (file)
index 0000000..71e570a
--- /dev/null
@@ -0,0 +1,53 @@
+package org.opensrf.util;
+import org.opensrf.*;
+import java.util.Map;
+
+/**
+ * Connects to the OpenSRF Settings server to fetch the settings config.  
+ * Provides a Config interface for fetching settings via path
+ */
+public class SettingsClient extends Config {
+
+    /** Singleton SettingsClient instance */
+    private static SettingsClient client = new SettingsClient();
+
+    public SettingsClient() {
+        super("");
+    }
+
+    /**
+     * @return The global settings client instance 
+     */
+    public static SettingsClient instance() throws ConfigException {
+        if(client.getConfigObject() == null) 
+            client.fetchConfig();
+        return client;
+    }
+
+    /**
+     * Fetches the settings object from the settings server
+     */
+    private void fetchConfig() throws ConfigException {
+
+        ClientSession ses = new ClientSession("opensrf.settings");
+        try {
+
+            Request req = ses.request(
+                "opensrf.settings.host_config.get", 
+                new String[]{(String)Config.global().getFirst("/domain")});
+    
+            Result res = req.recv(12000);
+            if(res == null) {
+                /** throw exception */
+            }
+            setConfigObject((Map) res.getContent());
+
+        } catch(Exception e) {
+            throw new ConfigException("Error fetching settings config", e);
+
+        } finally {
+            ses.cleanup();
+        }
+    }
+}
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/Utils.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/Utils.java
new file mode 100644 (file)
index 0000000..159d254
--- /dev/null
@@ -0,0 +1,106 @@
+package org.opensrf.util;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Collection of general, static utility methods
+ */
+public class Utils {
+
+    /**
+     * Returns the string representation of a given file.
+     * @param filename The file to turn into a string
+     */
+    public static String fileToString(String filename) 
+            throws FileNotFoundException, IOException {
+
+        StringBuffer sb = new StringBuffer();
+        BufferedReader in = new BufferedReader(new FileReader(filename));
+        String str;
+        while ((str = in.readLine()) != null) 
+            sb.append(str);
+        in.close();
+        return sb.toString();
+    }
+
+
+    /**
+     * Escapes a string.
+     */
+    public static String escape(String string) {
+        StringBuffer sb = new StringBuffer();
+        escape(string, sb);
+        return sb.toString();
+    }
+
+    /**
+     * Escapes a string.  Turns bare newlines into \n, etc.
+     * Escapes \n, \r, \t, ", \f
+     * Encodes non-ascii characters as UTF-8: \u0000
+     * @param string The string to escape
+     * @param sb The string buffer to write the escaped string into
+     */
+    public static void escape(String string, StringBuffer sb) {
+        int len = string.length();
+        String utf;
+        char c;
+        for( int i = 0; i < len; i++ ) {
+            c = string.charAt(i);
+            switch (c) {
+                case '\\':
+                    sb.append("\\\\");
+                    break;
+                case '"':
+                    sb.append("\\\"");
+                    break;
+                case '\b':
+                    sb.append("\\b");
+                    break;
+                case '\t':
+                    sb.append("\\t");
+                    break;
+                case '\n':
+                    sb.append("\\n");
+                    break;
+                case '\f':
+                    sb.append("\\f");
+                    break;
+                case '\r':
+                    sb.append("\\r");
+                    break;
+                default:
+                    if (c < 32 || c > 126 ) { 
+                        /* escape all non-ascii or control characters as UTF-8 */
+                        utf = "000" + Integer.toHexString(c);
+                        sb.append("\\u" + utf.substring(utf.length() - 4));
+                    } else {
+                        sb.append(c);
+                    }
+            }
+        }
+    }
+
+
+    /** 
+     * Descends into the map along the given XPATH-style path 
+     * and returns the object found there.
+     * @param path The XPATH-style path to search.  Path 
+     * components are separated by '/' characters.  
+     * Example:  /opensrf/loglevel
+     * @return The found object. 
+     */
+
+    public static Object findPath(Map map, String path) {
+        String keys[] = path.split("/", -1);
+        int i = 0;
+        if(path.charAt(0) == '/') i++;
+        for(; i < keys.length - 1; i++ ) 
+            map = (Map) map.get(keys[i]);
+
+        return map.get(keys[i]);
+    }
+}
+
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/XMLFlattener.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/XMLFlattener.java
new file mode 100644 (file)
index 0000000..7abefe0
--- /dev/null
@@ -0,0 +1,128 @@
+package org.opensrf.util;
+
+import javax.xml.stream.*;
+import javax.xml.stream.events.* ;
+import javax.xml.namespace.QName;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.ListIterator;
+import java.io.InputStream;
+import org.opensrf.util.JSONWriter;
+import org.opensrf.util.JSONReader;
+
+/**
+ * Flattens an XML file into a properties map.  Values are stored as JSON strings or arrays.
+ * An array is created if more than one value resides at the same key.
+ * e.g. html.head.script = "alert('hello');"
+ */
+public class XMLFlattener {
+
+    /** Flattened properties map */
+    private Map<String, String> props;
+    /** Incoming XML stream */
+    private InputStream inStream;
+    /** Runtime list of encountered elements */
+    private List<String> elementList;
+
+    /**
+     * 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 XMLFlattener(InputStream inStream) {
+        props = new HashMap<String, String>();
+        this.inStream = inStream;
+        elementList = new ArrayList<String>();
+    }
+
+    /** Turns an array of strings into a dot-separated key string */
+    private String listToString() {
+        ListIterator itr = elementList.listIterator();
+        StringBuffer sb = new StringBuffer();
+        while(itr.hasNext()) {
+            sb.append(itr.next());
+            if(itr.hasNext())
+                sb.append(".");
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Parses XML data from the provided stream.
+     */
+    public Map read() throws javax.xml.stream.XMLStreamException {
+
+        XMLInputFactory factory = XMLInputFactory.newInstance();
+
+        /** disable as many unused features as possible to speed up the parsing */
+        factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.TRUE);
+        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();
+            if(reader.isWhiteSpace()) continue;
+
+            switch(eventType) {
+
+                case XMLEvent.START_ELEMENT:
+                    elementList.add(reader.getName().toString());
+                    break;
+
+                case XMLEvent.CHARACTERS:
+                    String text = reader.getText();
+                    String key = listToString();
+
+                    if(props.containsKey(key)) {
+
+                        /* something in the map already has this key */
+
+                        Object o = null;
+                        try {
+                            o = new JSONReader(props.get(key)).read();
+                        } catch(org.opensrf.util.JSONException e){}
+
+                        if(o instanceof List) {
+                            /* if the map contains a list, append to the list and re-encode */
+                            ((List) o).add(text);
+
+                        } else {
+                            /* if the map just contains a string, start building a new list
+                             * with the old string and append the new string */
+                            List<String> arr = new ArrayList<String>();
+                            arr.add((String) o);
+                            arr.add(text);
+                            o = arr;
+                        }
+
+                        props.put(key, new JSONWriter(o).write());
+
+                    } else {
+                        props.put(key, new JSONWriter(text).write());
+                    }
+                    break;
+
+                case XMLEvent.END_ELEMENT: 
+                    elementList.remove(elementList.size()-1);
+                    break;
+            }
+        }
+
+        return props;
+    }
+}
+
+
+
+
diff --git a/Open-ILS/src/Android/opensrf/src/org/opensrf/util/XMLTransformer.java b/Open-ILS/src/Android/opensrf/src/org/opensrf/util/XMLTransformer.java
new file mode 100644 (file)
index 0000000..f8bc0d3
--- /dev/null
@@ -0,0 +1,59 @@
+package org.opensrf.util;
+import javax.xml.transform.*;
+import javax.xml.transform.stream.*;
+import javax.xml.parsers.*;
+import java.io.File;
+import java.io.ByteArrayInputStream;
+import java.io.OutputStream;
+import java.io.ByteArrayOutputStream;
+
+
+/**
+ * Performs XSL transformations.  
+ * TODO: Add ability to pass in XSL variables
+ */
+public class XMLTransformer {
+
+    /** The XML to transform */
+    private Source xmlSource;
+    /** The stylesheet to apply */
+    private Source xslSource;
+
+    public XMLTransformer(Source xmlSource, Source xslSource) {
+        this.xmlSource = xmlSource;
+        this.xslSource = xslSource;
+    }
+
+    public XMLTransformer(String xmlString, File xslFile) {
+        this(
+            new StreamSource(new ByteArrayInputStream(xmlString.getBytes())),
+            new StreamSource(xslFile));
+    }
+
+    public XMLTransformer(File xmlFile, File xslFile) {
+        this(
+            new StreamSource(xmlFile),
+            new StreamSource(xslFile));
+    }
+
+    /** 
+     * Applies the transformation and puts the result into the provided output stream
+     */
+    public void apply(OutputStream outStream) throws TransformerException, TransformerConfigurationException {
+        Result result = new StreamResult(outStream);
+        Transformer trans = TransformerFactory.newInstance().newTransformer(xslSource);
+        trans.transform(xmlSource, result);
+    }
+
+    /**
+     * Applies the transformation and return the resulting string
+     * @return The String created by the XSL transformation
+     */
+    public String apply() throws TransformerException, TransformerConfigurationException {
+        OutputStream outStream = new ByteArrayOutputStream();
+        this.apply(outStream);
+        return outStream.toString();
+    }
+}
+
+