Package org.jboss.serial.objectmetamodel

Source Code of org.jboss.serial.objectmetamodel.ObjectDescriptorFactory

/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.serial.objectmetamodel;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import org.apache.log4j.Logger;
import org.jboss.serial.classmetamodel.ClassMetaData;
import org.jboss.serial.classmetamodel.ClassMetamodelFactory;
import org.jboss.serial.classmetamodel.StreamingClass;
import org.jboss.serial.exception.SerializationException;
import org.jboss.serial.finalcontainers.BooleanContainer;
import org.jboss.serial.finalcontainers.ByteContainer;
import org.jboss.serial.finalcontainers.CharacterContainer;
import org.jboss.serial.finalcontainers.DoubleContainer;
import org.jboss.serial.finalcontainers.FloatContainer;
import org.jboss.serial.finalcontainers.IntegerContainer;
import org.jboss.serial.finalcontainers.LongContainer;
import org.jboss.serial.finalcontainers.ShortContainer;
import org.jboss.serial.objectmetamodel.ObjectsCache.JBossSeralizationInputInterface;
import org.jboss.serial.objectmetamodel.ObjectsCache.JBossSeralizationOutputInterface;
import org.jboss.serial.persister.ClassReferencePersister;
import org.jboss.serial.persister.PersistResolver;
import org.jboss.serial.persister.Persister;
import org.jboss.serial.util.ClassMetaConsts;
import org.jboss.serial.util.StringUtil;


/**
* @author clebert suconic
*/
public class ObjectDescriptorFactory implements ClassMetaConsts
{
  private static final Logger log = Logger.getLogger(ObjectDescriptorFactory.class);
     private static final boolean isDebug = log.isDebugEnabled();

    static Object objectFromDescription(final ObjectsCache cache,
                      ObjectsCache.JBossSeralizationInputInterface input)
            throws IOException
    {
        Object description = null;

        byte byteIdentify = (byte)cache.getInput().readByte();

        if (byteIdentify==DataContainerConstants.RESET)
        {
          cache.reset();
          return objectFromDescription(cache,input);
        }
        if (byteIdentify==DataContainerConstants.NULLREF)
        {
          return null;
        }
        else
        if (byteIdentify==DataContainerConstants.NEWDEF)
        {
          if (isDebug)
          {
            log.debug("objectFromDescription::reading new definition");
          }
            return readObjectDescriptionFromStreaming(cache,input.readObjectReference(),input);
        }
        else if (byteIdentify==DataContainerConstants.SMARTCLONE_DEF)
        {
          int reference=input.readObjectReference();
          if (isDebug)
          {
            log.debug("objectFromDescription::reading reference from safeClone=" + reference);
          }
        if (cache.getSafeToReuse()==null)
        {
          throw new IOException("SafeClone repository mismatch");
        }
        description = cache.getSafeToReuse().findReference(reference);
        if (description==null)
        {
          throw new IOException("SafeClone repository mismatch - didn't find reference " + reference);
        }
        return description;
         
        }
        else if (byteIdentify==DataContainerConstants.OBJECTREF)
        {
          int reference=input.readObjectReference();
          if (isDebug)
          {
            log.debug("objectFromDescription::reading circular definition reference=" + reference);
          }

          if (description==null)
            {
                description = cache.findObjectInCacheRead(reference);
            }

            if (description==null)
            {
                throw new SerializationException("Object reference " + reference + " was not found");
            }

            return description;
        }
        else
        {
          return input.readImmutable(byteIdentify,cache);
        }

    }

   


  /** First level of a describe object, will look if it's a newDef, or if it's already loaded.
     *  If the object was never loaded before, it will call readObjectDescriptionFromStreaming.
     *  If it was already loaded, it will just return from objectCache */
    static void describeObject(final ObjectsCache cache,
                                            Object obj) throws IOException
    {

        ObjectsCache.JBossSeralizationOutputInterface outputParent = cache.getOutput();
       
      if (obj==null)
      {
        outputParent.writeByte(DataContainerConstants.NULLREF);
        return;
      }
        if (obj!=null && ClassMetamodelFactory.isImmutable(obj.getClass()))
        {
          outputParent.saveImmutable(cache,obj);
          return;
        }

        if (isDebug)
        {
      if (obj==null)
          {
        log.debug("obj==null",new Exception());
          }
        }
        if (isDebug)
        {
          log.debug("describeObject for class=" + obj.getClass().getName());
        }

        ClassMetaData metaData = null;
        if (obj instanceof Class)
        {
          metaData = ClassMetamodelFactory.getClassMetaData((Class)obj,cache.isCheckSerializableClass());
        }
        else
        {
             metaData = ClassMetamodelFactory.getClassMetaData(obj.getClass(),cache.isCheckSerializableClass());
            if (metaData.getWriteReplaceMethod()!=null)
            {
              if (isDebug)
              {
                log.debug("describeObject::Calling writeReplace for " + metaData.getClazz().getName());
              }
              try {
                Object orig = obj;
            obj = metaData.getWriteReplaceMethod().invoke(obj,EMPTY_OBJECT_ARRAY);
            if (obj!=null && obj!=orig && obj.getClass()!=metaData.getClazz())
            {
              if (isDebug)
              {
                log.debug("originalObject=" + orig.getClass().getName() + " substituted by " + obj.getClass().getName());
              }
              describeObject(cache,obj);
              return;
            }
            metaData = ClassMetamodelFactory.getClassMetaData(obj.getClass(),cache.isCheckSerializableClass());
          } catch (Exception e) {
            IOException io = new IOException("Metadata Serialization Error");
            io.initCause(e);
            throw io;
          }
            }
        }

        if (cache.getSubstitution()!=null)
        {
          if (isDebug)
          {
            log.debug("describeObject::checking substitution on interface");
          }
          Object orig = obj;
            obj = cache.getSubstitution().replaceObject(obj);
      if (obj!=null && obj!=orig && obj.getClass()!=metaData.getClazz())
      {
            if (isDebug)
            {
              log.debug("describeObject::on check interface, original object[" + orig.getClass().getName() +"] was replaced by [" + obj.getClass().getName() + "]");
            }
        describeObject(cache,obj);
        return;
      }
        }
       

        int description = 0;

        if (cache.getSafeToReuse()!=null)
        {
            description = cache.getSafeToReuse().storeSafe(obj);
            if (description!=0)
            {
              if (isDebug)
              {
                log.debug("describeObject::a safeClone reference " + description);
              }
                outputParent.writeByte(DataContainerConstants.SMARTCLONE_DEF);
              cache.getOutput().addObjectReference(description);
                return;
            }
           
        }

        description = cache.findIdInCacheWrite(obj);

        if (description != 0)
        {
          if (isDebug)
          {
            log.debug("describeObject::a circular reference " + description);
          }
            outputParent.writeByte(DataContainerConstants.OBJECTREF);
            cache.getOutput().addObjectReference(description);
            return;
        } else
        {
          description = cache.putObjectInCacheWrite(obj);
          if (isDebug)
          {
            log.debug("describeObject::a new reference " + description);
          }
            outputParent.writeByte(DataContainerConstants.NEWDEF);
            cache.getOutput().addObjectReference(description);
           
            int cacheId = cache.findIdInCacheWrite(metaData);
            if (cacheId==0)
            {
              cacheId = cache.putObjectInCacheWrite(metaData);
              outputParent.writeByte(DataContainerConstants.NEWDEF);
              outputParent.addObjectReference(cacheId);
              StreamingClass.saveStream(metaData,outputParent);
            }
            else
            {
              outputParent.writeByte(DataContainerConstants.OBJECTREF);
              outputParent.addObjectReference(cacheId);
            }
           
            Persister persister = PersistResolver.resolvePersister(obj,metaData);

            outputParent.writeByte(persister.getId());
            persister.writeData(metaData, cache.getOutput(), obj, cache.getSubstitution());

            return;
        }
    }

    /* private static Object readImmutable(byte byteDescription,ObjectsCache cache, JBossSeralizationInputInterface input) throws IOException {
   
      Object retObject=null;
      switch (byteDescription)
      {
      case DataContainerConstants.STRING:
        retObject = StringUtil.readString(input,cache.getStringBuffer());break;
      case DataContainerConstants.BYTE:
        retObject = new Byte(input.readByte());break;
      case DataContainerConstants.CHARACTER:
        retObject = new Character(input.readChar());break;
      case DataContainerConstants.SHORT:
        retObject = new Short(input.readShort());break;
      case DataContainerConstants.INTEGER:
        retObject = new Integer(input.readInt());break;
      case DataContainerConstants.LONG:
        retObject = new Long(input.readLong());break;
      case DataContainerConstants.DOUBLE:
        retObject = new Double(input.readDouble());break;
      case DataContainerConstants.FLOAT:
        retObject = new Float(input.readFloat());break;
      case DataContainerConstants.BOOLEAN:
        retObject = new Boolean(input.readBoolean());break;
      }
     
      if (isDebug)
      {
        log.debug("byteDescription=" + byteDescription);
        log.debug("readImmutable return=" + retObject + " class=" + retObject.getClass().getName());
      }
     
      return retObject;
  } */

    /* private static void saveImmutable(ObjectsCache cache, Object obj, JBossSeralizationOutputInterface output) throws IOException {
      if (isDebug)
      {
        log.debug("saveImmutable::obj=" +obj + " class=" + obj.getClass().getName());
      }
        if (obj instanceof String)
        {
          output.writeByte(DataContainerConstants.STRING);
          StringUtil.saveString(output,(String)obj,cache.getStringBuffer());
        } else
        if (obj instanceof Byte)
        {
          output.writeByte(DataContainerConstants.BYTE);
          output.writeByte(((Byte)obj).byteValue());
        } else
        if (obj instanceof Character)
        {
          output.writeByte(DataContainerConstants.CHARACTER);
          output.writeChar(((Character)obj).charValue());
        } else
        if (obj instanceof Short)
        {
          output.writeByte(DataContainerConstants.SHORT);
          output.writeShort(((Short)obj).shortValue());
        } else
        if (obj instanceof Integer)
        {
          output.writeByte(DataContainerConstants.INTEGER);
          output.writeInt(((Integer)obj).intValue());
        } else
        if (obj instanceof Long)
        {
          output.writeByte(DataContainerConstants.LONG);
          output.writeLong(((Long)obj).longValue());
        } else
        if (obj instanceof Double)
        {
          output.writeByte(DataContainerConstants.DOUBLE);
          output.writeDouble(((Double)obj).doubleValue());
        } else
        if (obj instanceof Float)
        {
          output.writeByte(DataContainerConstants.FLOAT);
          output.writeFloat(((Float)obj).floatValue());
        } else
        if (obj instanceof BooleanContainer || obj instanceof Boolean)
        {
          output.writeByte(DataContainerConstants.BOOLEAN);
          output.writeBoolean(((Boolean)obj).booleanValue());
        } else
        {
            throw new SerializationException("I don't know how to write type " + obj.getClass().getName() + " yet");
        }
     
  } */


  private static Object readObjectDescriptionFromStreaming(final ObjectsCache cache,
                                        final int reference, ObjectsCache.JBossSeralizationInputInterface input) throws IOException
    {
      byte defClass = input.readByte();
      StreamingClass streamingClass = null;
      if (defClass==DataContainerConstants.NEWDEF)
      {
        int referenceId = input.readObjectReference();
        streamingClass = StreamingClass.readStream(input,cache.getClassResolver(),cache.getLoader());
        cache.putObjectInCacheRead(referenceId,streamingClass);
      }
      else
      {
        int referenceId = input.readObjectReference();
        streamingClass = (StreamingClass)cache.findObjectInCacheRead(referenceId);
        if (streamingClass==null)
        {
          throw new IOException("Didn't find StreamingClass circular refernce id=" + referenceId);
        }
       
      }

        ClassMetaData metaData = streamingClass.getMetadata();

        if (isDebug)
        {
          log.debug("Reading object for id=" + reference + " classLoader=" + cache.getLoader() + " className = " + metaData.getClassName());
        }
       
        byte persisterId = input.readByte();
        Persister persister = PersistResolver.resolvePersister(persisterId);
        //Persister persister = PersistResolver.resolvePersister(description.getMetaData().getClazz(),
        //        description.getMetaData(),description.getMetaData().isArray());

        /*ObjectDescription description = new ObjectDescription();
        description.setMetaData(ClassMetamodelFactory.getClassMetaData(reference.getClassName(),cache.getLoader(),false));
        cache.putObjectInCache(reference,description); */


        Object value = persister.readData(cache.getLoader(), streamingClass, metaData, reference, cache, cache.getInput(), cache.getSubstitution());

        if (!(persister instanceof ClassReferencePersister)) //JBSER-83
        {
          if (cache.getSubstitution()!=null)
          {
              value = cache.getSubstitution().replaceObject(value);
          }
 
          try
          {
              if (metaData.getReadResolveMethod()!=null)
              {
                if (isDebug)
                {
                  log.debug("readObjectDescriptionFromStreaming::calling readResolve for className = " + metaData.getClassName());
                }
                  value = metaData.getReadResolveMethod().invoke(value,new Object[]{});
                  cache.reassignObjectInCacheRead(reference,value);
              }
          }
          catch (IllegalAccessException e)
          {
              throw new SerializationException(e);
          }
          catch (InvocationTargetException e)
          {
              throw new SerializationException(e);
          }
        }

        return value;
    }

}
TOP

Related Classes of org.jboss.serial.objectmetamodel.ObjectDescriptorFactory

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.