// Path: src/main/java/org/jacis/plugin/readonly/DefaultJacisStoreEntryReadOnlyModeAdapter.java
// public class DefaultJacisStoreEntryReadOnlyModeAdapter<V> implements JacisStoreEntryReadOnlyModeAdapter<V> {
// 
//   @Override
//   public boolean isApplicableTo(V value) {
//     return value instanceof JacisReadonlyModeSupport;
//   }
// 
//   @Override
//   public boolean isReadOnly(V value) {
//     return ((JacisReadonlyModeSupport) value).isReadOnly();
//   }
// 
//   @Override
//   public V switchToReadOnlyMode(V value) {
//     ((JacisReadonlyModeSupport) value).switchToReadOnlyMode();
//     return value;
//   }
// 
//   @Override
//   public V switchToReadWriteMode(V value) {
//     ((JacisReadonlyModeSupport) value).switchToReadWriteMode();
//     return value;
//   }
// 
//   @Override
//   public String toString() {
//     return getClass().getSimpleName();
//   }
// }
// 
// Path: src/main/java/org/jacis/plugin/readonly/JacisStoreEntryReadOnlyModeAdapter.java
// @JacisApi
// public interface JacisStoreEntryReadOnlyModeAdapter<V> {
// 
//   /**
//    * Returns if this adapter can switch the read / write mode for the passed object
//    *
//    * @param value The object to check.
//    * @return if this adapter can switch the read / write mode for the passed object
//    */
//   boolean isApplicableTo(V value);
// 
//   /**
//    * Returns if the passed object is in read-only mode
//    *
//    * @param value The object to check.
//    * @return if the passed object is in read-only mode
//    */
//   boolean isReadOnly(V value);
// 
//   /**
//    * Switch the read / write mode for the passed object to read-only mode
//    * Note that the calling methods will work with the returned value.
//    * Therefore the implementation of the method may return another instance than the passed (e.g. a proxy).
//    *
//    * @param value The object to switch to read-only mode
//    * @return the object with the switched mode.
//    */
//   V switchToReadOnlyMode(V value);
// 
//   /**
//    * Switch the read / write mode for the passed object to read-write mode
//    * Note that the calling methods will work with the returned value.
//    * Therefore the implementation of the method may return another instance than the passed (e.g. a proxy).
//    *
//    * @param value The object to switch to read-write mode
//    * @return the object with the switched mode.
//    */
//   V switchToReadWriteMode(V value);
// 
// }


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.jacis.JacisApi;
import org.jacis.plugin.readonly.DefaultJacisStoreEntryReadOnlyModeAdapter;
import org.jacis.plugin.readonly.JacisStoreEntryReadOnlyModeAdapter;

/*
 * Copyright (c) 2016. Jan Wiemer
 */

package org.jacis.plugin.objectadapter.cloning;



/**
 * Implementation of the {@link AbstractJacisCloningObjectAdapter} cloning the objects based on Java serialization.
 * If the object is an instance of the {@link JacisCloneable} interface the {@link JacisCloneable#clone()} method
 * declared in this interface is used to clone the object.
 * Otherwise the object may be cloneable (overwrites the {@link Object#clone()} methods)
 * but does not implement the {@link JacisCloneable} interface.
 * In this case the {@link Object#clone()} method is called by reflection.
 *
 * @param <V> The object type (note that in this case the committed values and the values in the transactional view have the same type)
 * @author Jan Wiemer
 */
@JacisApi
public class JacisCloningObjectAdapter<V> extends AbstractJacisCloningObjectAdapter<V> {

  /**
   * Create a cloning object adapter with the passed read only mode adapter.
   * 
   * @param readOnlyModeAdapters Adapter to switch an object between read-only and read-write mode (if supported).
   */

// Path: src/main/java/org/jacis/plugin/readonly/DefaultJacisStoreEntryReadOnlyModeAdapter.java
// public class DefaultJacisStoreEntryReadOnlyModeAdapter<V> implements JacisStoreEntryReadOnlyModeAdapter<V> {
// 
//   @Override
//   public boolean isApplicableTo(V value) {
//     return value instanceof JacisReadonlyModeSupport;
//   }
// 
//   @Override
//   public boolean isReadOnly(V value) {
//     return ((JacisReadonlyModeSupport) value).isReadOnly();
//   }
// 
//   @Override
//   public V switchToReadOnlyMode(V value) {
//     ((JacisReadonlyModeSupport) value).switchToReadOnlyMode();
//     return value;
//   }
// 
//   @Override
//   public V switchToReadWriteMode(V value) {
//     ((JacisReadonlyModeSupport) value).switchToReadWriteMode();
//     return value;
//   }
// 
//   @Override
//   public String toString() {
//     return getClass().getSimpleName();
//   }
// }
// 
// Path: src/main/java/org/jacis/plugin/readonly/JacisStoreEntryReadOnlyModeAdapter.java
// @JacisApi
// public interface JacisStoreEntryReadOnlyModeAdapter<V> {
// 
//   /**
//    * Returns if this adapter can switch the read / write mode for the passed object
//    *
//    * @param value The object to check.
//    * @return if this adapter can switch the read / write mode for the passed object
//    */
//   boolean isApplicableTo(V value);
// 
//   /**
//    * Returns if the passed object is in read-only mode
//    *
//    * @param value The object to check.
//    * @return if the passed object is in read-only mode
//    */
//   boolean isReadOnly(V value);
// 
//   /**
//    * Switch the read / write mode for the passed object to read-only mode
//    * Note that the calling methods will work with the returned value.
//    * Therefore the implementation of the method may return another instance than the passed (e.g. a proxy).
//    *
//    * @param value The object to switch to read-only mode
//    * @return the object with the switched mode.
//    */
//   V switchToReadOnlyMode(V value);
// 
//   /**
//    * Switch the read / write mode for the passed object to read-write mode
//    * Note that the calling methods will work with the returned value.
//    * Therefore the implementation of the method may return another instance than the passed (e.g. a proxy).
//    *
//    * @param value The object to switch to read-write mode
//    * @return the object with the switched mode.
//    */
//   V switchToReadWriteMode(V value);
// 
// }


// Path: src/main/java/org/jacis/plugin/objectadapter/cloning/JacisCloningObjectAdapter.java
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.jacis.JacisApi;
import org.jacis.plugin.readonly.DefaultJacisStoreEntryReadOnlyModeAdapter;
import org.jacis.plugin.readonly.JacisStoreEntryReadOnlyModeAdapter;

/*
 * Copyright (c) 2016. Jan Wiemer
 */

package org.jacis.plugin.objectadapter.cloning;



/**
 * Implementation of the {@link AbstractJacisCloningObjectAdapter} cloning the objects based on Java serialization.
 * If the object is an instance of the {@link JacisCloneable} interface the {@link JacisCloneable#clone()} method
 * declared in this interface is used to clone the object.
 * Otherwise the object may be cloneable (overwrites the {@link Object#clone()} methods)
 * but does not implement the {@link JacisCloneable} interface.
 * In this case the {@link Object#clone()} method is called by reflection.
 *
 * @param <V> The object type (note that in this case the committed values and the values in the transactional view have the same type)
 * @author Jan Wiemer
 */
@JacisApi
public class JacisCloningObjectAdapter<V> extends AbstractJacisCloningObjectAdapter<V> {

  /**
   * Create a cloning object adapter with the passed read only mode adapter.
   * 
   * @param readOnlyModeAdapters Adapter to switch an object between read-only and read-write mode (if supported).
   */

  public JacisCloningObjectAdapter(JacisStoreEntryReadOnlyModeAdapter<V> readOnlyModeAdapters) {
