Package er.ajax.json.serializer

Source Code of er.ajax.json.serializer.NSArraySerializer

package er.ajax.json.serializer;

import java.util.Enumeration;

import org.jabsorb.JSONSerializer;
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.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.webobjects.eocontrol._EOCheapCopyArray;
import com.webobjects.eocontrol._EOCheapCopyMutableArray;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSKeyValueCoding;
import com.webobjects.foundation.NSMutableArray;

/**
* Serialises NSArrays
*
* TODO: if this serialises a superclass does it need to also specify the subclasses?
*/
public class NSArraySerializer extends AbstractSerializer {
  /**
   * Unique serialisation id.
   */
  private final static long serialVersionUID = 2;

  /**
   * Classes that this can serialise.
   */
  private static Class[] _serializableClasses = new Class[] { NSArray.class, NSMutableArray.class, _EOCheapCopyArray.class, _EOCheapCopyMutableArray.class };

  /**
   * Classes that this can serialise to.
   */
  private static Class[] _JSONClasses = new Class[] { JSONObject.class };

  @Override
  public boolean canSerialize(Class clazz, Class jsonClazz) {
    return (super.canSerialize(clazz, jsonClazz) || ((jsonClazz == null || jsonClazz == JSONObject.class) && NSArray.class.isAssignableFrom(clazz)));
  }

  public Class[] getJSONClasses() {
    return _JSONClasses;
  }

  public Class[] getSerializableClasses() {
    return _serializableClasses;
  }

  public Object marshall(SerializerState state, Object p, Object o) throws MarshallException {
    NSArray nsarray = (NSArray) o;
    JSONObject obj = new JSONObject();
    JSONArray arr = new JSONArray();

    // TODO: this same block is done everywhere.
    // Have a single function to do it.
    if (ser.getMarshallClassHints()) {
      try {
        obj.put("javaClass", o.getClass().getName());
      }
      catch (JSONException e) {
        throw new MarshallException("javaClass not found!");
      }
    }
    try {
      obj.put("nsarray", arr);
      state.push(o, arr, "nsarray");
    }
    catch (JSONException e) {
      throw new MarshallException("Error setting nsarray: " + e);
    }
    int index = 0;
    try {
      Enumeration e = nsarray.objectEnumerator();
      while (e.hasMoreElements()) {
        Object json = ser.marshall(state, arr, e.nextElement(), Integer.valueOf(index));
        if (JSONSerializer.CIRC_REF_OR_DUPLICATE != json) {
          arr.put(json);
        }
        else {
          // put a slot where the object would go, so it can be fixed up properly in the fix up phase
          arr.put(JSONObject.NULL);
        }
        index++;
      }
    }
    catch (MarshallException e) {
      throw (MarshallException) new MarshallException("element " + index).initCause(e);
    }
    finally {
      state.pop();
    }
    return obj;
  }

  // TODO: try unMarshall and unMarshall share 90% code. Put in into an
  // intermediate function.
  // TODO: Also cache the result somehow so that an unmarshall
  // following a tryUnmarshall doesn't do the same work twice!
  public ObjectMatch tryUnmarshall(SerializerState state, Class clazz, Object o) throws UnmarshallException {
    JSONObject jso = (JSONObject) o;
    String java_class;
    try {
      java_class = jso.getString("javaClass");
    }
    catch (JSONException e) {
      throw new UnmarshallException("Could not read javaClass", e);
    }
    if (java_class == null) {
      throw new UnmarshallException("no type hint");
    }
   
    Class klass;
    try {
      klass = Class.forName(java_class);
    } catch (ClassNotFoundException cnfe) {
      throw new UnmarshallException("Could not find class named: " + java_class);
    }
    if (!NSArray.class.isAssignableFrom(klass)) {
      throw new UnmarshallException("not an NSArray");
    }
   
    JSONArray jsonNSArray;
    try {
      jsonNSArray = jso.getJSONArray("nsarray");
    }
    catch (JSONException e) {
      throw new UnmarshallException("Could not read nsarray: " + e.getMessage(), e);
    }
    if (jsonNSArray == null) {
      throw new UnmarshallException("nsarray missing");
    }
    int i = 0;
    ObjectMatch m = new ObjectMatch(-1);
    state.setSerialized(o, m);
    try {
      for (; i < jsonNSArray.length(); i++) {
        m.setMismatch(ser.tryUnmarshall(state, null, jsonNSArray.get(i)).max(m).getMismatch());
      }
    }
    catch (UnmarshallException e) {
      throw new UnmarshallException("element " + i + " " + e.getMessage(), e);
    }
    catch (JSONException e) {
      throw new UnmarshallException("element " + i + " " + e.getMessage(), e);
    }
    return m;
  }

  public Object unmarshall(SerializerState state, Class clazz, Object o) throws UnmarshallException {
    JSONObject jso = (JSONObject) o;
    String java_class;
    try {
      java_class = jso.getString("javaClass");
    }
    catch (JSONException e) {
      throw new UnmarshallException("Could not read javaClass", e);
    }
    if (java_class == null) {
      throw new UnmarshallException("no type hint");
    }
    NSMutableArray al = new NSMutableArray();
    boolean immutableClone = true;
   
    Class klass;
    try {
      klass = Class.forName(java_class);
    } catch (ClassNotFoundException cnfe) {
      throw new UnmarshallException("Could not find class named: " + java_class);
    }

    if (NSMutableArray.class.isAssignableFrom(klass)){
      immutableClone = false;
    } else if (!NSArray.class.isAssignableFrom(klass)) {
      throw new UnmarshallException("not an NSArray");
    }

    JSONArray jsonNSArray;
    try {
      jsonNSArray = jso.getJSONArray("nsarray");
    }
    catch (JSONException e) {
      throw new UnmarshallException("Could not read nsarray: " + e.getMessage(), e);
    }
    if (jsonNSArray == null) {
      throw new UnmarshallException("nsarray missing");
    }
    int i = 0;
    try {
      for (; i < jsonNSArray.length(); i++) {
        Object obj = ser.unmarshall(state, null, jsonNSArray.get(i));
        if (obj != null) {
          al.addObject(obj);
        }
        else {
          al.addObject(NSKeyValueCoding.NullValue);
        }
      }
      NSArray finalArray = al;
      if (immutableClone) {
        finalArray = al.immutableClone();
      }
      state.setSerialized(o, finalArray);
      return finalArray;
    }
    catch (UnmarshallException e) {
      throw new UnmarshallException("element " + i + " " + e.getMessage(), e);
    }
    catch (JSONException e) {
      throw new UnmarshallException("element " + i + " " + e.getMessage(), e);
    }
  }

}
TOP

Related Classes of er.ajax.json.serializer.NSArraySerializer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.