Package nexj.core.rpc.json

Source Code of nexj.core.rpc.json.JSONMarshaller

package nexj.core.rpc.json;

import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
import java.util.SimpleTimeZone;
import java.util.TimeZone;

import nexj.core.meta.Primitive;
import nexj.core.meta.PrivilegeSet;
import nexj.core.persistence.OID;
import nexj.core.persistence.OIDHolder;
import nexj.core.rpc.CharacterStreamMarshaller;
import nexj.core.rpc.ErrorLocationHolder;
import nexj.core.rpc.MarshallerException;
import nexj.core.rpc.Request;
import nexj.core.rpc.Response;
import nexj.core.rpc.TransferObject;
import nexj.core.runtime.Context;
import nexj.core.runtime.ContextAware;
import nexj.core.scripting.ConstPair;
import nexj.core.scripting.PCodeFunction;
import nexj.core.scripting.PCodeMacro;
import nexj.core.scripting.Pair;
import nexj.core.scripting.Symbol;
import nexj.core.util.Binary;
import nexj.core.util.ErrorCode;
import nexj.core.util.ExceptionHolder;
import nexj.core.util.HashTab;
import nexj.core.util.IdentityHashTab;
import nexj.core.util.Lookup;
import nexj.core.util.ObjUtil;
import nexj.core.util.PagedArrayList;
import nexj.core.util.PagedBinary;
import nexj.core.util.PropertyIterator;
import nexj.core.util.StringId;
import nexj.core.util.TZ;

/**
* JSON format object marshaller.
*/
public class JSONMarshaller implements CharacterStreamMarshaller, ContextAware
{
   // constants

   /**
    * The exception marshaller.
    */
   protected final static Marshaller EXCEPTION_MSH = new Marshaller()
   {
      public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
      {
         Throwable t = (Throwable)obj;

         writer.openObject();

         if (obj instanceof ErrorCode)
         {
            ErrorCode e = (ErrorCode)obj;

            writer.writeObjectKey(JSON.EXCEPTION);
            writer.writeString(e.getErrorCode());

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_ERR_MSG);
            writer.writeString((msh.getContext() == null) ? t.getLocalizedMessage() :
               msh.getContext().formatString(e.getErrorCode(), e.getErrorArgs()));

            Object[] argArray = e.getErrorArgs();
            int nLen = (argArray == null) ? 0 : argArray.length;

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_ERR_ARGS);

            if (nLen == 0)
            {
               writer.writeNull();
            }
            else
            {
               writer.openArray();
               msh.marshal(argArray[0]);

               for (int i = 1; i < nLen; i++)
               {
                  writer.writeSeparator();
                  msh.marshal(argArray[i]);
               }

               writer.closeArray();
            }
         }
         else
         {
            writer.writeObjectKey(JSON.EXCEPTION);
            writer.writeString("err." + t.getClass().getName());

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_ERR_MSG);
            writer.writeString(t.getLocalizedMessage());

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_ERR_ARGS);
            writer.writeNull();
         }

         if (obj instanceof ErrorLocationHolder)
         {
            ErrorLocationHolder h = (ErrorLocationHolder)obj;
            String sName = h.getClassName();

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_CLASS);

            if (sName == null)
            {
               writer.writeNull();
            }
            else
            {
               writer.writeString(sName);
            }

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_OID);

            OIDHolder oidHolder = h.getOIDHolder();

            if (oidHolder == null || oidHolder.getOID() == null)
            {
               writer.writeNull();
            }
            else
            {
               writer.writeBase64(oidHolder.getOID().toBinary());
            }

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_ORDINAL);
            writer.write(String.valueOf(h.getOrdinal()));

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_ATTRS);

            int nCount = h.getAttributeCount();

            if (nCount == 0)
            {
               writer.writeNull();
               writer.writeSeparator();
               writer.writeObjectKey(JSON.EXCEPTION_ATTR_EXCEPTIONS);
               writer.writeNull();
            }
            else
            {
               writer.openArray();

               for (Iterator itr = h.getAttributeIterator(); itr.hasNext();)
               {
                  writer.writeString((String)itr.next());

                  if (itr.hasNext())
                  {
                     writer.writeSeparator();
                  }
               }

               writer.closeArray();

               writer.writeSeparator();
               writer.writeObjectKey(JSON.EXCEPTION_ATTR_EXCEPTIONS);

               writer.openArray();

               for (Iterator itr = h.getAttributeIterator(); itr.hasNext();)
               {
                  msh.marshal(h.findException((String)itr.next()));

                  if (itr.hasNext())
                  {
                     writer.writeSeparator();
                  }
               }

               writer.closeArray();
            }
         }
         else
         {
            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_CLASS);
            writer.writeNull();

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_OID);
            writer.writeNull();

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_ORDINAL);
            writer.writeNull();

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_ATTRS);
            writer.writeNull();

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_ATTR_EXCEPTIONS);
            writer.writeNull();
         }

         if (obj instanceof ExceptionHolder)
         {
            ExceptionHolder h = (ExceptionHolder)obj;

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_EXCEPTIONS);

            boolean bNull = true;

            for (Iterator itr = h.getExceptionIterator(); itr.hasNext();)
            {
               Throwable cause = (Throwable)itr.next();

               if (!ObjUtil.isSystem(cause))
               {
                  if (bNull)
                  {
                     bNull = false;
                     writer.openArray();
                  }
                  else
                  {
                     writer.writeSeparator();
                  }

                  marshal(cause, msh, writer);
               }
            }

            if (bNull)
            {
               writer.writeNull();
            }
            else
            {
               writer.closeArray();
            }
         }
         else
         {
            Throwable cause = t.getCause();

            writer.writeSeparator();
            writer.writeObjectKey(JSON.EXCEPTION_EXCEPTIONS);

            if (cause == null || ObjUtil.isSystem(cause))
            {
               writer.writeNull();
            }
            else
            {
               marshal(cause, msh, writer);
            }
         }

         writer.closeObject();
      }
   };

   /**
    * The Symbol Marshaller
    */
   protected final static Marshaller SYMBOL_MSH = new Marshaller()
   {
      public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
      {
         writer.writeObject(JSON.SYMBOL, ((Symbol)obj).getName());
      }
   };

   /**
    * The marshaller map, class to marshaller implementation.
    */
   protected final static Lookup s_mshMap = new HashTab(35); // of type Marshaller[Class]

   static
   {
      // BigDecimal, Byte, Double, Float, Integer, Long, Short
      s_mshMap.put(Integer.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeNumber((Integer)obj);
         }
      });

      s_mshMap.put(Long.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeNumber((Long)obj);
         }
      });

      s_mshMap.put(Float.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeNumber((Float)obj);
         }
      });

      s_mshMap.put(Double.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeNumber((Double)obj);
         }
      });

      s_mshMap.put(BigDecimal.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeNumber((BigDecimal)obj);
         }
      });

      s_mshMap.put(Short.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeNumber((Short)obj);
         }
      });

      // java.util.Date, sql.Time, sql.Date, sql.Timestamp
      s_mshMap.put(java.sql.Timestamp.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.openObject();
            writer.writeObjectKey(JSON.TIMESTAMP);
            writer.write(String.valueOf(((java.util.Date)obj).getTime()));
            writer.closeObject();
         }
      });

      s_mshMap.put(java.util.Date.class, s_mshMap.get(java.sql.Timestamp.class));
      s_mshMap.put(java.sql.Date.class, s_mshMap.get(java.sql.Timestamp.class));
      s_mshMap.put(java.sql.Time.class, s_mshMap.get(java.sql.Timestamp.class));

      s_mshMap.put(Boolean.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeBoolean(((Boolean)obj).booleanValue());
         }
      });

      s_mshMap.put(String.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeString((String)obj);
         }
      });

      s_mshMap.put(StringId.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            String sStringID = ((StringId)obj).toString();

            if (sStringID == null)
            {
               sStringID = "";
            }

            writer.writeObject(JSON.STRING_ID, sStringID);
         }
      });

      s_mshMap.put(Character.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeObject(JSON.CHARACTER, ((Character)obj).charValue());
         }
      });

      // Binary, PagedBinary
      s_mshMap.put(Binary.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeObject(JSON.BINARY, (Binary)obj);
         }
      });
      s_mshMap.put(PagedBinary.class, s_mshMap.get(Binary.class));

      s_mshMap.put(Locale.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeObject(JSON.LOCALE, obj.toString());
         }
      });

      // TimeZone, TZ, SimpleTimeZone
      s_mshMap.put(TimeZone.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeObject(JSON.TIMEZONE, ((TimeZone)obj).getID());
         }
      });
      s_mshMap.put(TZ.UTC.getClass(), s_mshMap.get(TimeZone.class));
      s_mshMap.put(SimpleTimeZone.class, s_mshMap.get(TimeZone.class));

      //ArrayList, PagedArrayList
      s_mshMap.put(ArrayList.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.openArray();

            ArrayList list = (ArrayList)obj;
            int nCount = list.size();

            if (nCount == 0)
            {
               writer.closeArray();

               return;
            }

            msh.marshal(list.get(0));

            for (int i = 1; i < nCount; i++)
            {
               writer.writeSeparator();
               msh.marshal(list.get(i));
            }

            writer.closeArray();
         }
      });

      s_mshMap.put(PagedArrayList.class, s_mshMap.get(ArrayList.class));

      s_mshMap.put(TransferObject.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            TransferObject tobj = (TransferObject)obj;

            writer.openObject();

            writer.writeObjectKey(JSON.TRANSFER_OBJECT);
            writer.writeString(tobj.getClassName());

            writer.writeSeparator();
            writer.writeObjectKey(JSON.TRANSFER_OBJECT_OID);

            String sOID = (String)msh.m_objectMap.get(obj);

            if (sOID != null)
            {
               // TO found in marshalled object map
               writer.writeString(sOID);
               writer.closeObject();

               return;
            }

            OID oid = tobj.getOID();

            if (oid == null)
            {
               sOID = "@" + msh.m_objectMap.size();
            }
            else
            {
               sOID = oid.toBinary().toBase64();
            }

            msh.m_objectMap.put(obj, sOID);

            writer.writeString(sOID);

            if (tobj.getEventName() != null)
            {
               writer.writeSeparator();
               writer.writeObjectKey(JSON.TRANSFER_OBJECT_EVENT);
               writer.writeString(tobj.getEventName());
            }

            if (tobj.getVersion() != 0)
            {
               writer.writeSeparator();
               writer.writeObjectKey(JSON.TRANSFER_OBJECT_VERSION);
               writer.writeNumber(Primitive.createInteger(tobj.getVersion()));
            }

            for (PropertyIterator itr = tobj.getIterator(); itr.hasNext();)
            {
               writer.writeSeparator();
               writer.writeObjectKey((String)itr.next());
               msh.marshal(itr.getValue());
            }

            writer.closeObject();
         }
      });

      s_mshMap.put(OID.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.openObject();
            writer.writeObjectKey(JSON.OID);

            writer.writeBase64(((OID)obj).toBinary());

            writer.closeObject();
         }
      });

      s_mshMap.put(Symbol.class, SYMBOL_MSH);

      //Pair, ConstPair
      s_mshMap.put(Pair.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            Pair pair = (Pair)obj;
            int nCount = 1;

            for (;;)
            {
               Object head = pair.getHead();

               writer.openObject();
               writer.writeObjectKey(JSON.PAIR);

               // optimized for nested Pair and Symbol
               if (head instanceof Pair)
               {
                  marshal(head, msh, writer);
               }
               else if (head instanceof Symbol)
               {
                  SYMBOL_MSH.marshal(head, msh, writer);
               }
               else if (head != null)
               {
                  msh.marshal(head);
               }
               else
               {
                  writer.writeNull();
               }

               Object tail = pair.getTail();

               if (tail == null)
               {
                  break;
               }

               writer.writeSeparator();
               writer.writeObjectKey(JSON.PAIR_TAIL);

               if (tail instanceof Pair)
               {
                  pair = (Pair)tail;
                  nCount++;
               }
               else
               {
                  msh.marshal(tail);

                  break;
               }
            }

            for (; nCount > 0; nCount--)
            {
               writer.closeObject();
            }
         }
      });

      s_mshMap.put(ConstPair.class, s_mshMap.get(Pair.class));

      s_mshMap.put(byte[].class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeObject(JSON.BYTE_ARRAY, new Binary((byte[])obj));
         }
      });

      s_mshMap.put(char[].class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeObject(JSON.CHAR_ARRAY, new String((char[])obj));
         }
      });

      s_mshMap.put(String[].class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            String[] stringArray = (String[])obj;
            int nCount = stringArray.length;

            writer.openObject();
            writer.writeObjectKey(JSON.STRING_ARRAY);

            writer.openArray();

            if (nCount == 0)
            {
               writer.closeArray();

               return;
            }

            writer.writeString(stringArray[0]);

            for (int i = 1; i < nCount; i++)
            {
               writer.writeSeparator();
               writer.writeString(stringArray[i]);
            }

            writer.closeArray();
            writer.closeObject();
         }
      });

      s_mshMap.put(Object[].class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            Object[] objArray = (Object[])obj;
            int nCount = objArray.length;

            writer.openObject();
            writer.writeObjectKey(JSON.OBJECT_ARRAY);

            writer.openArray();

            if (nCount == 0)
            {
               writer.closeArray();

               return;
            }

            msh.marshal(objArray[0]);

            for (int i = 1; i < nCount; i++)
            {
               writer.writeSeparator();
               msh.marshal(objArray[i]);
            }

            writer.closeArray();
            writer.closeObject();
         }
      });

      s_mshMap.put(PrivilegeSet.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            writer.writeObject(JSON.PRIVILEGE_SET, (PrivilegeSet)obj);
         }
      });

      //PCodeFunction, PCodeMacro
      s_mshMap.put(PCodeFunction.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            PCodeFunction fun = ((PCodeFunction)obj).getCleanCopy();

            writer.openObject();

            if (obj instanceof PCodeMacro)
            {
               writer.writeObjectKey(JSON.MACRO);
               writer.writeBoolean(true);
               writer.writeSeparator();
            }

            writer.writeObjectKey(JSON.FUNCTION);

            if (fun.code == null)
            {
               writer.writeNull();
            }
            else
            {
               writer.writeString(new String(fun.code));
            }

            writer.writeSeparator();
            writer.writeObjectKey(JSON.FUNCTION_CONSTANTS);

            if (fun.constants == null)
            {
               writer.writeNull();
            }
            else
            {
               writer.openArray();
               msh.marshal(fun.constants[0]);

               int nCount = fun.constants.length;

               for (int i = 1; i < nCount; i++)
               {
                  writer.writeSeparator();
                  msh.marshal(fun.constants[i]);
               }

               writer.closeArray();
            }

            writer.closeObject();
         }
      });

      s_mshMap.put(PCodeMacro.class, s_mshMap.get(PCodeFunction.class));

      s_mshMap.put(Request.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            Request req = (Request)obj;

            writer.openObject();

            if (req.getNamespace() != null)
            {
               writer.writeObjectKey(JSON.REQUEST_NAMESPACE);
               writer.writeString(req.getNamespace());
               writer.writeSeparator();
            }

            if (req.getVersion() != null)
            {
               writer.writeObjectKey(JSON.REQUEST_VERSION);
               writer.writeString(req.getVersion());
               writer.writeSeparator();
            }

            if (req.isAsync())
            {
               writer.writeObjectKey(JSON.REQUEST_ASYNC);
               writer.writeBoolean(req.isAsync());
               writer.writeSeparator();
            }

            if (!req.isCommit())
            {
               writer.writeObjectKey(JSON.REQUEST_COMMIT);
               writer.writeBoolean(req.isCommit());
               writer.writeSeparator();
            }

            if (req.getLocale() != null)
            {
               writer.writeObjectKey(JSON.REQUEST_LOCALE);
               writer.writeString(req.getLocale().toString());
               writer.writeSeparator();
            }

            if (req.getTimeZone() != null)
            {
               writer.writeObjectKey(JSON.REQUEST_TIMEZONE);
               writer.writeString(req.getTimeZone().getID());
               writer.writeSeparator();
            }

            if (req.getCorrelator() != null)
            {
               writer.writeObjectKey(JSON.REQUEST_CORRELATOR);
               msh.marshal(req.getCorrelator());
               writer.writeSeparator();
            }

            writer.writeObjectKey(JSON.REQUEST);
            writer.openArray();

            for (int i = 0, n = req.getInvocationCount(); i < n; ++i)
            {
               Request.Invocation invocation = req.getInvocation(i);

               if (i != 0)
               {
                  writer.writeSeparator();
               }

               writer.openObject();
               writer.writeObjectKey(JSON.INVOCATION_OBJECT);
               msh.marshal(invocation.getObject());

               if (invocation.getEventName() != null)
               {
                  writer.writeSeparator();
                  writer.writeObjectKey(JSON.INVOCATION_EVENT);
                  msh.marshal(invocation.getEventName());
               }

               Object[] argArray = invocation.getArguments();

               if (argArray != null)
               {
                  writer.writeSeparator();
                  writer.writeObjectKey(JSON.INVOCATION_ARGUMENTS);
                  writer.openArray();

                  for (int k = 0; k < argArray.length; ++k)
                  {
                     if (k != 0)
                     {
                        writer.writeSeparator();
                     }

                     msh.marshal(argArray[k]);
                  }

                  writer.closeArray();
               }

               if (invocation.getAttributes() != null)
               {
                  writer.writeSeparator();
                  writer.writeObjectKey(JSON.INVOCATION_ATTRIBUTES);
                  msh.marshal(invocation.getAttributes());
               }

               writer.closeObject();
            }

            writer.closeArray();

            int n = req.getFilterCount();

            if (n != 0)
            {
               writer.writeSeparator();
               writer.writeObjectKey(JSON.REQUEST_FILTERS);
               writer.openArray();

               for (int i = 0; i < n; ++i)
               {
                  if (i != 0)
                  {
                     writer.writeSeparator();
                  }

                  msh.marshal(req.getFilter(i));
               }

               writer.closeArray();
            }

            writer.closeObject();
         }
      });

      s_mshMap.put(Response.class, new Marshaller()
      {
         public void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException
         {
            Response resp = (Response)obj;

            writer.openObject();
            writer.writeObjectKey(JSON.RESPONSE_RESULTS);

            int n = resp.getResultCount();

            if (n == 0)
            {
               writer.writeNull();
            }
            else
            {
               writer.openArray();
               msh.marshal(resp.getResult(0));

               for (int i = 1; i < n; ++i)
               {
                  writer.writeSeparator();
                  msh.marshal(resp.getResult(i));
               }

               writer.closeArray();
            }

            writer.writeSeparator();

            writer.writeObjectKey(JSON.RESPONSE_EVENTS);
            n = resp.getEventCount();

            if (n == 0)
            {
               writer.writeNull();
            }
            else
            {
               writer.openArray();
               msh.marshal(resp.getEvent(0));

               for (int i = 1; i < n; ++i)
               {
                  writer.writeSeparator();
                  msh.marshal(resp.getEvent(i));
               }

               writer.closeArray();
            }

            writer.closeObject();
         }
      });
   }

   // associations

   /**
    * The object reference map.
    */
   protected Lookup m_objectMap;

   /**
    * The character stream writer.
    */
   protected JSONWriter m_writer;

   /**
    * The runtime context.
    */
   protected Context m_context;

   // constructors

   /**
    * Creates a JSON marshaller with a given runtime context.
    *
    * @param context The runtime context.
    */
   public JSONMarshaller(Context context)
   {
      m_context = context;
   }

   // operations

   /**
    * Sets the runtime context.
    *
    * @param context The context to set.
    */
   public void setContext(Context context)
   {
      m_context = context;
   }

   /**
    * @return The runtime context.
    */
   public Context getContext()
   {
      return m_context;
   }

   /**
    * Marshals an object to the output stream.
    *
    * @param obj The object to marshal.
    */
   protected void marshal(Object obj) throws IOException
   {
      if (obj == null)
      {
         m_writer.writeNull();

         return;
      }

      Marshaller msh = (Marshaller)s_mshMap.get(obj.getClass());

      if (msh == null)
      {
         if (obj instanceof Throwable)
         {
            msh = EXCEPTION_MSH;
         }
         else
         {
            throw new JSONMarshallerException("err.rpc.mshType", new Object[] { obj.getClass().getName() });
         }
      }

      msh.marshal(obj, this, m_writer);
   }

   /**
    * Serializes an object to a character stream.
    *
    * @param obj The object to serialize.
    * @param writer The character stream writer.
    */
   public void serialize(Object obj, Writer writer) throws IOException, MarshallerException
   {
      m_writer = (writer instanceof JSONWriter) ? (JSONWriter)writer : new JSONWriter(writer);
      m_objectMap = new IdentityHashTab();

      marshal(obj);

      // clear memory
      m_objectMap = null;
   }

   /**
    * Interface implemented by JSON marshallers.
    */
   protected interface Marshaller
   {
      /**
       * Marshals an object of a specific type to the output stream.
       *
       * @param obj The object to marshal.
       * @param msh The JSON marshaller.
       * @param writer The JSON writer
       * @throws IOException If an I/O error occurs.
       */
      void marshal(Object obj, JSONMarshaller msh, JSONWriter writer) throws IOException;
   }
}
TOP

Related Classes of nexj.core.rpc.json.JSONMarshaller

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.