package org.opensrf;
+import org.opensrf.util.*;
-public class Message {
+public class Message implements OSRFSerializable {
/** Message types */
public enum Type {
/** message payload */
private Object payload;
+ /** Go ahead and register the Message object */
+ private static OSRFRegistry registry =
+ OSRFRegistry.registerObject(
+ "osrfMessage",
+ OSRFRegistry.WireProtocol.HASH,
+ new String[] {"threadTrace", "type", "payload"});
+
/**
* @param id This message's ID
* @param type The type of message
setId(id);
setType(type);
}
+
public int getId() {
return id;
}
public void setPayload(Object p) {
payload = p;
}
+
+ /**
+ * 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();
+ return null;
+ }
+
+ public OSRFRegistry getRegistry() {
+ return registry;
+ }
}
package org.opensrf;
import java.util.List;
import java.util.ArrayList;
+import org.opensrf.util.*;
-public class Method {
+public class Method implements OSRFSerializable {
private String name;
private List<Object> params;
+ /** Register this object */
+ private static OSRFRegistry registry =
+ OSRFRegistry.registerObject(
+ "osrfMethod",
+ OSRFRegistry.WireProtocol.HASH,
+ new String[] {"method", "params"});
+
+
public Method(String name) {
this.name = name;
this.params = new ArrayList<Object>(8);
* Pushes a new param object onto the set of params
* @param p The new param to add to the method.
*/
- public void pushParam(Object p) {
+ 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;
+ }
+
+ public OSRFRegistry getRegistry() {
+ return registry;
+ }
+
}
package org.opensrf;
+import org.opensrf.util.*;
/**
/** Status code number */
private int statusCode;
+
+ /** Register this object */
+ private static OSRFRegistry registry =
+ OSRFRegistry.registerObject(
+ "osrfResult",
+ OSRFRegistry.WireProtocol.HASH,
+ new String[] {"status", "statusCode", "content"});
+
+
public Result(String status, int statusCode, Object content) {
this.status = status;
this.statusCode = statusCode;
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;
+ }
+
+ public OSRFRegistry getRegistry() {
+ return registry;
+ }
+
}
package org.opensrf.test;
-import org.opensrf.util.JSON;
+import org.opensrf.*;
+import org.opensrf.util.*;
import java.util.*;
public class TestJSON {
list.add(null);
map.put("key6", list);
- System.out.println(JSON.toJSON(map));
+ System.out.println(JSON.toJSON(map) + "\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(JSON.toJSON(map) + "\n");
+
+
+ Message m = new Message(1, Message.Type.REQUEST);
+ Method method = new Method("opensrf.settings.host_config.get");
+ method.addParam("app07.dev.gapines.org");
+ m.setPayload(method);
+
+ System.out.println(JSON.toJSON(m) + "\n");
}
}
*/
public class JSON {
+ /** 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";
return;
}
+ /** OpenSRF serializable objects */
+ if(obj instanceof OSRFSerializable) {
+ encodeOSRFSerializable((OSRFSerializable) obj, sb);
+ return;
+ }
+
/** JSON object */
if(obj instanceof Map) {
encodeJSONObject((Map) obj, sb);
sb.deleteCharAt(sb.length()-1);
sb.append("}");
}
+
+
+ /**
+ * Encodes a network-serializable OpenSRF object
+ */
+ private static void encodeOSRFSerializable(OSRFSerializable obj, StringBuffer sb) {
+
+ OSRFRegistry reg = obj.getRegistry();
+ String[] fields = reg.getFields();
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put(JSON_CLASS_KEY, reg.getNetClass());
+
+ if( reg.getWireProtocol() == OSRFRegistry.WireProtocol.ARRAY ) {
+
+ List<Object> list = new ArrayList<Object>(fields.length);
+ for(String s : fields)
+ list.add(obj.get(s));
+ map.put(JSON_PAYLOAD_KEY, list);
+
+ } else {
+ //map.put(JSON_PAYLOAD_KEY, new HashMap<String, Object>(obj));
+ Map<String, Object> subMap = new HashMap<String, Object>();
+ for(String s : fields)
+ map.put(s, obj.get(s));
+
+ }
+
+ /** now serialize the encoded object */
+ toJSON(map, sb);
+ }
}
--- /dev/null
+package org.opensrf.util;
+
+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;
+ }
+
+
+ /**
+ * @return This object's registry
+ */
+ public OSRFRegistry getRegistry() {
+ return registry;
+ }
+
+
+ /**
+ * Gets the object at the given fields. We override this here
+ * as part of the contract with OSRFSerializable
+ * @param field the field name to get.
+ * @return The object contained at the given field.
+ */
+ public Object get(String field) {
+ return super.get(field);
+ }
+}
--- /dev/null
+package org.opensrf.util;
+
+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 {
+
+
+ /**
+ * 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;
+ }
+
+ public WireProtocol getWireProtocol() {
+ return this.wireProtocol;
+ }
+
+ public String getNetClass() {
+ return this.netClass;
+ }
+
+ /**
+ * Creates a new registry object */
+ public OSRFRegistry(String netClass, WireProtocol wireProtocol, String fields[]) {
+ this.netClass = netClass;
+ this.wireProtocol = wireProtocol;
+ this.fields = fields;
+ }
+}
+
+
--- /dev/null
+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();
+
+ public abstract Object get(String field);
+}
+
+