/**
 * An implementation of {@link DataSerializerHook} which constructs any of the {@link
 * com.hazelcast.nio.serialization.DataSerializable} objects for the hibernate module
 */
public class HibernateDataSerializerHook implements DataSerializerHook {

  /** The factory id for this class */
  public static final int F_ID =
      FactoryIdHelper.getFactoryId(FactoryIdHelper.HIBERNATE_DS_FACTORY, F_ID_OFFSET_HIBERNATE);
  /** @see Value */
  public static final int VALUE = 0;
  /** @see ExpiryMarker */
  public static final int EXPIRY_MARKER = 1;
  /** @see LockEntryProcessor */
  public static final int LOCK = 2;
  /** @see UnlockEntryProcessor */
  public static final int UNLOCK = 3;
  /** @see UpdateEntryProcessor */
  public static final int UPDATE = 4;
  /** @see Invalidation */
  public static final int INVALIDATION = 5;
  /** @see Timestamp */
  public static final int TIMESTAMP = 6;

  @Override
  public int getFactoryId() {
    return F_ID;
  }

  @Override
  public DataSerializableFactory createFactory() {
    return new Factory();
  }

  private static class Factory implements DataSerializableFactory {
    @Override
    public IdentifiedDataSerializable create(int typeId) {
      IdentifiedDataSerializable result;
      switch (typeId) {
        case VALUE:
          result = new Value();
          break;
        case EXPIRY_MARKER:
          result = new ExpiryMarker();
          break;
        case LOCK:
          result = new LockEntryProcessor();
          break;
        case UNLOCK:
          result = new UnlockEntryProcessor();
          break;
        case UPDATE:
          result = new UpdateEntryProcessor();
          break;
        case INVALIDATION:
          result = new Invalidation();
          break;
        case TIMESTAMP:
          result = new Timestamp();
          break;
        default:
          result = null;
      }
      return result;
    }
  }
}
/**
 * {@link CacheDataSerializerHook} contains all the ID hooks for {@link IdentifiedDataSerializable}
 * classes used inside the JCache framework.
 *
 * <p>CacheProxy operations are mapped here. This factory class is used by internal serialization
 * system to create {@link IdentifiedDataSerializable} classes without using reflection.
 */
public final class CacheDataSerializerHook implements DataSerializerHook {

  public static final int F_ID =
      FactoryIdHelper.getFactoryId(CACHE_DS_FACTORY, CACHE_DS_FACTORY_ID);
  public static final short GET = 1;
  public static final short CONTAINS_KEY = 2;
  public static final short PUT = 3;
  public static final short PUT_IF_ABSENT = 4;
  public static final short REMOVE = 5;
  public static final short GET_AND_REMOVE = 6;
  public static final short REPLACE = 7;
  public static final short GET_AND_REPLACE = 8;
  public static final short PUT_BACKUP = 9;
  public static final short PUT_ALL_BACKUP = 10;
  public static final short REMOVE_BACKUP = 11;
  public static final short CLEAR_BACKUP = 12;
  public static final short SIZE = 13;
  public static final short SIZE_FACTORY = 14;
  public static final short CLEAR = 15;
  public static final short CLEAR_FACTORY = 16;
  public static final short GET_ALL = 17;
  public static final short GET_ALL_FACTORY = 18;
  public static final short LOAD_ALL = 19;
  public static final short LOAD_ALL_FACTORY = 20;
  public static final short EXPIRY_POLICY = 21;
  public static final short KEY_ITERATOR = 22;
  public static final short KEY_ITERATION_RESULT = 23;
  public static final short ENTRY_PROCESSOR = 24;
  public static final short CLEAR_RESPONSE = 25;
  public static final short CREATE_CONFIG = 26;
  public static final short GET_CONFIG = 27;
  public static final short MANAGEMENT_CONFIG = 28;
  public static final short LISTENER_REGISTRATION = 29;
  public static final short DESTROY_CACHE = 30;
  public static final short CACHE_EVENT_DATA = 31;
  public static final short CACHE_EVENT_DATA_SET = 32;
  public static final short BACKUP_ENTRY_PROCESSOR = 33;
  public static final short REMOVE_ALL = 34;
  public static final short REMOVE_ALL_BACKUP = 35;
  public static final short REMOVE_ALL_FACTORY = 36;
  public static final short PUT_ALL = 37;
  public static final short MERGE = 38;
  public static final short INVALIDATION_MESSAGE = 39;
  public static final short BATCH_INVALIDATION_MESSAGE = 40;
  public static final short ENTRY_ITERATOR = 41;
  public static final short ENTRY_ITERATION_RESULT = 42;
  public static final short CACHE_PARTITION_LOST_EVENT_FILTER = 43;
  public static final short DEFAULT_CACHE_ENTRY_VIEW = 44;
  public static final short CACHE_REPLICATION = 45;
  public static final short CACHE_POST_JOIN = 46;
  public static final short CACHE_DATA_RECORD = 47;
  public static final short CACHE_OBJECT_RECORD = 48;
  public static final short CACHE_PARTITION_EVENT_DATA = 49;

  public static final short CACHE_INVALIDATION_METADATA = 50;
  public static final short CACHE_INVALIDATION_METADATA_RESPONSE = 51;
  public static final short CACHE_ASSIGN_AND_GET_UUIDS = 52;
  public static final short CACHE_ASSIGN_AND_GET_UUIDS_FACTORY = 53;
  public static final short CACHE_NEAR_CACHE_STATE_HOLDER = 54;
  public static final short CACHE_EVENT_LISTENER_ADAPTOR = 55;

  private static final int LEN = CACHE_EVENT_LISTENER_ADAPTOR + 1;

  public int getFactoryId() {
    return F_ID;
  }

  public DataSerializableFactory createFactory() {
    ConstructorFunction<Integer, IdentifiedDataSerializable>[] constructors =
        new ConstructorFunction[LEN];
    constructors[GET] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheGetOperation();
          }
        };
    constructors[CONTAINS_KEY] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheContainsKeyOperation();
          }
        };
    constructors[PUT] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CachePutOperation();
          }
        };
    constructors[PUT_IF_ABSENT] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CachePutIfAbsentOperation();
          }
        };
    constructors[REMOVE] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheRemoveOperation();
          }
        };
    constructors[GET_AND_REMOVE] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheGetAndRemoveOperation();
          }
        };
    constructors[REPLACE] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheReplaceOperation();
          }
        };
    constructors[GET_AND_REPLACE] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheGetAndReplaceOperation();
          }
        };
    constructors[PUT_BACKUP] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CachePutBackupOperation();
          }
        };
    constructors[PUT_ALL_BACKUP] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CachePutAllBackupOperation();
          }
        };
    constructors[REMOVE_BACKUP] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheRemoveBackupOperation();
          }
        };
    constructors[SIZE] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheSizeOperation();
          }
        };
    constructors[SIZE_FACTORY] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheSizeOperationFactory();
          }
        };
    constructors[CLEAR_FACTORY] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheClearOperationFactory();
          }
        };
    constructors[GET_ALL] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheGetAllOperation();
          }
        };
    constructors[GET_ALL_FACTORY] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheGetAllOperationFactory();
          }
        };
    constructors[LOAD_ALL] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheLoadAllOperation();
          }
        };
    constructors[LOAD_ALL_FACTORY] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheLoadAllOperationFactory();
          }
        };
    constructors[EXPIRY_POLICY] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          @Override
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new HazelcastExpiryPolicy();
          }
        };
    constructors[KEY_ITERATOR] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheKeyIteratorOperation();
          }
        };
    constructors[KEY_ITERATION_RESULT] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheKeyIterationResult();
          }
        };
    constructors[ENTRY_PROCESSOR] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheEntryProcessorOperation();
          }
        };
    constructors[CLEAR_RESPONSE] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheClearResponse();
          }
        };
    constructors[CREATE_CONFIG] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheCreateConfigOperation();
          }
        };
    constructors[GET_CONFIG] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheGetConfigOperation();
          }
        };
    constructors[MANAGEMENT_CONFIG] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheManagementConfigOperation();
          }
        };
    constructors[LISTENER_REGISTRATION] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheListenerRegistrationOperation();
          }
        };
    constructors[DESTROY_CACHE] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheDestroyOperation();
          }
        };
    constructors[CACHE_EVENT_DATA] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheEventDataImpl();
          }
        };
    constructors[CACHE_EVENT_DATA_SET] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheEventSet();
          }
        };
    constructors[BACKUP_ENTRY_PROCESSOR] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          @Override
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheBackupEntryProcessorOperation();
          }
        };
    constructors[CLEAR] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheClearOperation();
          }
        };
    constructors[CLEAR_BACKUP] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheClearBackupOperation();
          }
        };
    constructors[REMOVE_ALL] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheRemoveAllOperation();
          }
        };
    constructors[REMOVE_ALL_BACKUP] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheRemoveAllBackupOperation();
          }
        };
    constructors[REMOVE_ALL_FACTORY] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheRemoveAllOperationFactory();
          }
        };
    constructors[PUT_ALL] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CachePutAllOperation();
          }
        };
    constructors[MERGE] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheMergeOperation();
          }
        };
    constructors[ENTRY_ITERATOR] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheEntryIteratorOperation();
          }
        };
    constructors[ENTRY_ITERATION_RESULT] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheEntryIterationResult();
          }
        };
    constructors[CACHE_PARTITION_LOST_EVENT_FILTER] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CachePartitionLostEventFilter();
          }
        };
    constructors[DEFAULT_CACHE_ENTRY_VIEW] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new DefaultCacheEntryView();
          }
        };
    constructors[CACHE_REPLICATION] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheReplicationOperation();
          }
        };
    constructors[CACHE_POST_JOIN] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new PostJoinCacheOperation();
          }
        };
    constructors[CACHE_DATA_RECORD] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheDataRecord();
          }
        };
    constructors[CACHE_OBJECT_RECORD] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheObjectRecord();
          }
        };
    constructors[CACHE_PARTITION_EVENT_DATA] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CachePartitionEventData();
          }
        };
    constructors[CACHE_INVALIDATION_METADATA] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheGetInvalidationMetaDataOperation();
          }
        };
    constructors[CACHE_INVALIDATION_METADATA_RESPONSE] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheGetInvalidationMetaDataOperation.MetaDataResponse();
          }
        };
    constructors[CACHE_ASSIGN_AND_GET_UUIDS] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheAssignAndGetUuidsOperation();
          }
        };
    constructors[CACHE_ASSIGN_AND_GET_UUIDS_FACTORY] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheAssignAndGetUuidsOperationFactory();
          }
        };
    constructors[CACHE_NEAR_CACHE_STATE_HOLDER] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheNearCacheStateHolder();
          }
        };
    constructors[CACHE_EVENT_LISTENER_ADAPTOR] =
        new ConstructorFunction<Integer, IdentifiedDataSerializable>() {
          public IdentifiedDataSerializable createNew(Integer arg) {
            return new CacheEventListenerAdaptor();
          }
        };

    return new ArrayDataSerializableFactory(constructors);
  }
}