Keyシリアライザ
Enumに続いて、com.google.appengine.api.datastore.Keyのシリアライザも実装。
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.google.appengine.api.datastore.Key; import com.google.appengine.api.datastore.KeyFactory; /** * Keyのシリアライザ */ public class KeySerializer extends AbstractSerializer { /** UID */ private static final long serialVersionUID = 4989497558259776800L; @Override @SuppressWarnings("unchecked") public boolean canSerialize(Class clazz, Class jsonClazz) { return Key.class == clazz && (jsonClazz == null || jsonClazz == JSONObject.class); } @Override @SuppressWarnings("unchecked") public Class[] getJSONClasses() { return new Class[] {Key.class}; } @Override @SuppressWarnings("unchecked") public Class[] getSerializableClasses() { return new Class[] {}; } @Override public Object marshall(SerializerState state, Object p, Object o) throws MarshallException { if (o instanceof Key) { return marshall( (Key) o ); } else { throw new MarshallException("cannot marshall using class " + o.getClass()); } } JSONObject marshall( Key k ) throws MarshallException { JSONObject obj = new JSONObject(); try { obj.put("javaClass", Key.class.getName()); if ( k.getName() != null ) { obj.put("name", k.getName()); } else { obj.put("id", k.getId()); } obj.put("kind", k.getKind()); if ( k.getParent() != null ) obj.put("parent", marshall( k.getParent() )); } catch (JSONException e) { throw new MarshallException(e.getMessage(), e); } return obj; } @Override @SuppressWarnings("unchecked") public ObjectMatch tryUnmarshall( SerializerState state, Class clazz, Object o) throws UnmarshallException { JSONObject jso = (JSONObject) o; try { Class<?> cl = Class.forName(jso.getString("javaClass")); if ( cl != Key.class ) { throw new UnmarshallException("not a key."); } if ( !jso.has("kind") ) throw new UnmarshallException("not a key."); if ( !jso.has("name") && !jso.has("id") ) { throw new UnmarshallException("not a key."); } state.setSerialized(o, ObjectMatch.OKAY); return ObjectMatch.OKAY; } catch (Exception e) { throw new UnmarshallException("not a key.", e); } } @Override @SuppressWarnings("unchecked") public Object unmarshall(SerializerState state, Class clazz, Object o) throws UnmarshallException { JSONObject jso = (JSONObject) o; try { Object returnValue = unmarshall( jso ); state.setSerialized(o, returnValue); return returnValue; } catch (Exception e) { throw new UnmarshallException("not enum", e); } } Key unmarshall( JSONObject jso ) throws MarshallException { try { String kind = jso.getString("kind"); Key parent = jso.has("parent") ? unmarshall( jso.getJSONObject("parent")) : null; if ( jso.has("name") ) { if ( parent != null ) { return KeyFactory.createKey( parent, kind, jso.getString("name")); } else { return KeyFactory.createKey( kind, jso.getString("name")); } } else { if ( parent != null ) { return KeyFactory.createKey( parent, kind, jso.getLong("id")); } else { return KeyFactory.createKey( kind, jso.getLong("id")); } } } catch (JSONException e) { throw new MarshallException(e.getMessage(), e); } } }
有効化は例によって、JSONRPCBridgeにインスタンスを設定してやればOKです。
JSONRPCBridge bridge = JSONRPCBridge.getGlobalBridge();
bridge.registerSerializer( new KeySerializer() );