package er.ajax.json.serializer; import java.util.Enumeration; import java.util.Iterator; import org.jabsorb.serializer.AbstractSerializer; import org.jabsorb.serializer.MarshallException; import org.jabsorb.serializer.ObjectMatch; import org.jabsorb.serializer.SerializerState; import org.jabsorb.serializer.UnmarshallException; import org.json.JSONException; import org.json.JSONObject; import com.webobjects.foundation.NSMutableSet; import com.webobjects.foundation.NSSet; /** * Transforms NSSets between JavaScript and Java. * * @author Jean-François Veillette <jfveillette@os.ca> * @version $, $Date $ <br> * © 2005 OS Communications Informatiques, inc. Tous droits réservés. */ class NSSetSerializer extends AbstractSerializer { /** * Do I need to update serialVersionUID? * See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the * <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a> */ private static final long serialVersionUID = 1L; private static Class[] _serializableClasses = new Class[] { NSSet.class, NSMutableSet.class }; private static Class[] _JSONClasses = new Class[] { JSONObject.class }; public Class[] getSerializableClasses() { return _serializableClasses; } public Class[] getJSONClasses() { return _JSONClasses; } @Override public boolean canSerialize(Class clazz, Class jsonClazz) { return (super.canSerialize(clazz, jsonClazz) || ((jsonClazz == null || jsonClazz == JSONObject.class) && NSSet.class.isAssignableFrom(clazz))); } public ObjectMatch tryUnmarshall(SerializerState state, Class clazz, Object o) throws UnmarshallException { try { JSONObject jso = (JSONObject) o; String java_class = jso.getString("javaClass"); if (java_class == null) { throw new UnmarshallException("no type hint"); } if (!(java_class.equals("com.webobjects.foundation.NSSet") || java_class.equals("com.webobjects.foundation.NSMutableSet"))) { throw new UnmarshallException("not a Set"); } JSONObject jsonset = jso.getJSONObject("set"); if (jsonset == null) { throw new UnmarshallException("set missing"); } ObjectMatch m = new ObjectMatch(-1); Iterator i = jsonset.keys(); String key = null; try { while (i.hasNext()) { key = (String) i.next(); m = ser.tryUnmarshall(state, null, jsonset.get(key)).max(m); } } catch (UnmarshallException e) { throw new UnmarshallException("key " + key + " " + e.getMessage()); } return m; } catch (JSONException e) { throw new UnmarshallException("Failed to unmarshall NSSet.", e); } } public Object unmarshall(SerializerState state, Class clazz, Object o) throws UnmarshallException { try { JSONObject jso = (JSONObject) o; String java_class = jso.getString("javaClass"); if (java_class == null) { throw new UnmarshallException("no type hint"); } NSMutableSet abset = null; if (java_class.equals("com.webobjects.foundation.NSSet") || java_class.equals("com.webobjects.foundation.NSMutableSet")) { abset = new NSMutableSet(); } else { throw new UnmarshallException("not a Set"); } JSONObject jsonset = jso.getJSONObject("set"); if (jsonset == null) { throw new UnmarshallException("set missing"); } Iterator i = jsonset.keys(); String key = null; try { while (i.hasNext()) { key = (String) i.next(); Object setElement = jsonset.get(key); Object unmarshalledObject = ser.unmarshall(state, null, setElement); abset.addObject(unmarshalledObject); } } catch (UnmarshallException e) { throw new UnmarshallException("key " + i + e.getMessage()); } return abset; } catch (JSONException e) { throw new UnmarshallException("Failed to unmarshall NSSet.", e); } } public Object marshall(SerializerState state, Object p, Object o) throws MarshallException { try { NSSet set = (NSSet) o; JSONObject obj = new JSONObject(); JSONObject setdata = new JSONObject(); obj.put("javaClass", o.getClass().getName()); obj.put("set", setdata); String key = null; try { int index = 0; Enumeration i = set.objectEnumerator(); while (i.hasMoreElements()) { Object value = i.nextElement(); setdata.put(key, ser.marshall(state, o, value, Integer.valueOf(index))); index++; } } catch (MarshallException e) { throw new MarshallException("set key " + key + e.getMessage()); } return obj; } catch (JSONException e) { throw new MarshallException("Failed to marshall NSSet.", e); } } }