/*
 * JBoss, the OpenSource J2EE webOS
 * 
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.cache.statetransfer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.CacheSPI;
import org.jboss.cache.Fqn;
import org.jboss.cache.Version;

import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * Factory class able to create {@link StateTransferGenerator} and
 * {@link StateTransferIntegrator} instances.
 *
 * @author <a href="brian.stansberry@jboss.com">Brian Stansberry</a>
 * @version $Revision: 6120 $
 */
public abstract class StateTransferFactory
{
   private static final short RV_200 = Version.getVersionShort("2.0.0");
   private static final Log log = LogFactory.getLog(StateTransferFactory.class);

   /**
    * Gets the StateTransferGenerator able to handle the given cache instance.
    *
    * @param cache the cache
    * @return the {@link StateTransferGenerator}
    * @throws IllegalStateException if the cache's ReplicationVersion is < 2.0.0
    */
   public static StateTransferGenerator getStateTransferGenerator(CacheSPI cache)
   {
      short version = cache.getConfiguration().getReplicationVersion();

      // Compiler won't let me use a switch

      if (version < RV_200 && version > 0) // <= 0 is actually a version > 15.31.63
         throw new IllegalStateException("State transfer with cache replication version < 2.0.0 not supported");
      else
         return new DefaultStateTransferGenerator(cache); // current default
   }

   public static StateTransferIntegrator getStateTransferIntegrator(ObjectInputStream in, Fqn fqn, CacheSPI cache)
         throws Exception
   {
      short version;
      try
      {
         version = (Short) cache.getMarshaller().objectFromObjectStream(in);
      }
      catch (IOException io)
      {
         // something is wrong with this stream, close it
         try
         {
            in.close();
         }
         catch (IOException e)
         {
            if (log.isWarnEnabled()) log.warn("Unable to close stream!", e);
         }
         throw new IllegalStateException("Stream corrupted ", io);
      }

      // Compiler won't let me use a switch

      if (version < RV_200 && version > 0) // <= 0 is actually a version > 15.31.63
         throw new IllegalStateException("State transfer with cache replication version < 2.0.0 not supported");
      else
         return new DefaultStateTransferIntegrator(fqn, cache); // current default
   }
}
