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 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.util.ClassMetaConsts;


/**
* @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
  {
      if (cache.getSubstitution() != null)
      {
        return cache.getSubstitution().replaceObject(objectFromDescriptionInternal(cache, input));
      }
      else
      {
        return objectFromDescriptionInternal(cache, input);
      }
  }

    
     private static Object objectFromDescriptionInternal(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);
        }
        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 cache.getObjectDescriptorStrategy().readObjectSpecialCase(input, cache, byteIdentify);
        }

    }

   


  /** 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();
         ObjectDescriptorStrategy objectDescriptorStrategy = cache.getObjectDescriptorStrategy();

        if (objectDescriptorStrategy.writeObjectSpecialCase(outputParent, cache, obj))
        {
           return;
        }

        ClassMetaData metaData = getMetaData(obj, cache);
       
        if (objectDescriptorStrategy.writeDuplicateObject(outputParent, cache, obj, metaData))
        {
           return;
        }
       
        Object originalObject = obj;
        Object newObject = obj;
       
        do
        {
           obj = newObject;
           metaData = getMetaData(obj, cache);
           newObject = objectDescriptorStrategy.replaceObjectByClass(cache, obj, metaData);
          
           if (objectDescriptorStrategy.writeObjectSpecialCase(outputParent, cache, newObject))
           {
              return;
           }
        }
         while (!objectDescriptorStrategy.doneReplacing(cache, newObject, obj, metaData));

        obj = newObject;
        metaData = getMetaData(obj, cache);
       
        if (cache.getSubstitution()!=null)
        {
            if (isDebug)
            {
                log.debug("describeObject::checking substitution on interface");
            }
            Object orig = obj;
            obj = cache.getSubstitution().replaceObject(obj);
            if (obj!=orig)
            {
                if (isDebug)
                {
                    log.debug("describeObject::on check interface, original object[" + orig.getClass().getName() +"] was replaced by [" + obj.getClass().getName() + "]");
                }
                if (objectDescriptorStrategy.writeObjectSpecialCase(outputParent, cache, obj))
                {
                   return;
                }
               
                metaData = getMetaData(obj, cache);
            }
        }
       
        if (isDebug)
        {
      if (obj==null)
          {
        log.debug("obj==null",new Exception());
          }
        }
        if (isDebug)
        {
          log.debug("describeObject for class=" + obj.getClass().getName());
        }

        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, metaData.isImmutable());

        if (description != 0) // Shouldn't happen.
        {
          if (isDebug)
          {
            log.debug("describeObject::a circular reference " + description);
          }
            outputParent.writeByte(DataContainerConstants.OBJECTREF);
            cache.getOutput().addObjectReference(description);
            return;
        } else
        {
          
            ClassMetaData originalMetaData = metaData;
            if (obj != originalObject)
            {
               originalMetaData = getMetaData(originalObject, cache);
            }
          description = cache.putObjectInCacheWrite(originalObject, originalMetaData.isImmutable());
          if (isDebug)
          {
            log.debug("describeObject::a new reference " + description);
          }
            outputParent.writeByte(DataContainerConstants.NEWDEF);
            cache.getOutput().addObjectReference(description);
            cache.getClassDescriptorStrategy().writeClassDescription(obj, metaData, cache, description);
            cache.getObjectDescriptorStrategy().writeObject(outputParent, cache, metaData, obj);

            return;
        }
    }

  private static Object readObjectDescriptionFromStreaming(final ObjectsCache cache,
                                                             ObjectsCache.JBossSeralizationInputInterface input) throws IOException
    {
      int reference = input.readObjectReference();
      StreamingClass streamingClass = cache.getClassDescriptorStrategy().readClassDescription(cache, input, cache.getClassResolver(), null);
        return cache.getObjectDescriptorStrategy().readObject(input, cache, streamingClass, reference);
    }
 
  private static ClassMetaData getMetaData(Object obj, ObjectsCache cache) throws IOException
  {
       if (obj instanceof Class)
       {
          return ClassMetamodelFactory.getClassMetaData((Class)obj,false);
       }
       else
       {
          return ClassMetamodelFactory.getClassMetaData(obj.getClass(),cache.isCheckSerializableClass());
       }
  }
}
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.