// Path: src/main/java/org/jacis/exception/ReadOnlyException.java
// @JacisApi
// public class ReadOnlyException extends IllegalStateException {
// 
//   private static final long serialVersionUID = 1L;
// 
//   public ReadOnlyException(String s) {
//     super(s);
//   }
// }
// 
// Path: src/main/java/org/jacis/plugin/readonly/object/AbstractReadOnlyModeSupportingObject.java
// @JacisApi
// public abstract class AbstractReadOnlyModeSupportingObject implements JacisReadonlyModeSupport {
// 
//   public static final boolean WRITE_ACCESS_MODE_SINGLE_THREAD = true;
// 
//   /** The thread currently permitted to modify the object (if any) */
//   private transient Thread threadWithWriteAccess = null;
// 
//   protected AbstractReadOnlyModeSupportingObject() {
//     threadWithWriteAccess = Thread.currentThread(); // when creating the object its writable
//   }
// 
//   @Override
//   protected Object clone() {
//     try {
//       return super.clone();
//     } catch (CloneNotSupportedException e) {
//       throw new InternalError("Could not clone " + this.getClass().getName());
//     }
//   }
// 
//   @Override
//   public void switchToReadOnlyMode() {
//     threadWithWriteAccess = null;
//   }
// 
//   @Override
//   public void switchToReadWriteMode() {
//     threadWithWriteAccess = Thread.currentThread();
//   }
// 
//   @Override
//   public boolean isReadOnly() {
//     return threadWithWriteAccess == null;
//   }
// 
//   @Override
//   public boolean isWritable() {
//     if (isSingleThreadedWriteAccessRequirred()) {
//       return Thread.currentThread().equals(threadWithWriteAccess);
//     } else {
//       return threadWithWriteAccess != null;
//     }
//   }
// 
//   /**
//    * This method should be called prior to all modifying accesses to the object (e.g. in al setter-methods).
//    * The method will check if the current thread has write access to the object and will throw a {@link ReadOnlyException} otherwise.
//    * 
//    * @throws ReadOnlyException thrown if the current thread has no write access to the object.
//    */
//   protected void checkWritable() throws ReadOnlyException {
//     if (threadWithWriteAccess == null) {
//       throw new ReadOnlyException("Object currently in read only mode! Accessing Thread: " + Thread.currentThread() + ". Object: " + this);
//     } else if (isSingleThreadedWriteAccessRequirred() && !threadWithWriteAccess.equals(Thread.currentThread())) {
//       throw new ReadOnlyException("Object currently only writable for thread " + threadWithWriteAccess + "! Accessing Thread: " + Thread.currentThread() + ". Object: " + this);
//     }
//   }
// 
//   /**
//    * Overwrite this method and return false if write access should not be restricted to a single thread.
//    * 
//    * @return if single threaded write access is required (default: true)
//    */
//   protected boolean isSingleThreadedWriteAccessRequirred() {
//     return WRITE_ACCESS_MODE_SINGLE_THREAD;
//   }
// 
// }


import org.jacis.plugin.readonly.object.AbstractReadOnlyModeSupportingObject;
import org.jacis.JacisApi;
import org.jacis.exception.ReadOnlyException;
/*
 * Copyright (c) 2016. Jan Wiemer
 */

package org.jacis.plugin.dirtycheck.object;


/**
 * Abstract base class for objects supporting switching them between the usual read-write mode and a read-only mode
 * (see {@link AbstractReadOnlyModeSupportingObject})
 * and tracking if the object is dirty by tracking if the {@link #checkWritable()} method has been called.
 *
 * @author Jan Wiemer
 */
@JacisApi
public abstract class AbstractReadOnlyModeAndDirtyCheckSupportingObject extends AbstractReadOnlyModeSupportingObject implements JacisDirtyTrackingObject {

  private boolean dirty = false;

  /** @return if the object is dirty */
  @Override
  public boolean isDirty() {
    return dirty;
  }

  @Override
// Path: src/main/java/org/jacis/exception/ReadOnlyException.java
// @JacisApi
// public class ReadOnlyException extends IllegalStateException {
// 
//   private static final long serialVersionUID = 1L;
// 
//   public ReadOnlyException(String s) {
//     super(s);
//   }
// }
// 
// Path: src/main/java/org/jacis/plugin/readonly/object/AbstractReadOnlyModeSupportingObject.java
// @JacisApi
// public abstract class AbstractReadOnlyModeSupportingObject implements JacisReadonlyModeSupport {
// 
//   public static final boolean WRITE_ACCESS_MODE_SINGLE_THREAD = true;
// 
//   /** The thread currently permitted to modify the object (if any) */
//   private transient Thread threadWithWriteAccess = null;
// 
//   protected AbstractReadOnlyModeSupportingObject() {
//     threadWithWriteAccess = Thread.currentThread(); // when creating the object its writable
//   }
// 
//   @Override
//   protected Object clone() {
//     try {
//       return super.clone();
//     } catch (CloneNotSupportedException e) {
//       throw new InternalError("Could not clone " + this.getClass().getName());
//     }
//   }
// 
//   @Override
//   public void switchToReadOnlyMode() {
//     threadWithWriteAccess = null;
//   }
// 
//   @Override
//   public void switchToReadWriteMode() {
//     threadWithWriteAccess = Thread.currentThread();
//   }
// 
//   @Override
//   public boolean isReadOnly() {
//     return threadWithWriteAccess == null;
//   }
// 
//   @Override
//   public boolean isWritable() {
//     if (isSingleThreadedWriteAccessRequirred()) {
//       return Thread.currentThread().equals(threadWithWriteAccess);
//     } else {
//       return threadWithWriteAccess != null;
//     }
//   }
// 
//   /**
//    * This method should be called prior to all modifying accesses to the object (e.g. in al setter-methods).
//    * The method will check if the current thread has write access to the object and will throw a {@link ReadOnlyException} otherwise.
//    * 
//    * @throws ReadOnlyException thrown if the current thread has no write access to the object.
//    */
//   protected void checkWritable() throws ReadOnlyException {
//     if (threadWithWriteAccess == null) {
//       throw new ReadOnlyException("Object currently in read only mode! Accessing Thread: " + Thread.currentThread() + ". Object: " + this);
//     } else if (isSingleThreadedWriteAccessRequirred() && !threadWithWriteAccess.equals(Thread.currentThread())) {
//       throw new ReadOnlyException("Object currently only writable for thread " + threadWithWriteAccess + "! Accessing Thread: " + Thread.currentThread() + ". Object: " + this);
//     }
//   }
// 
//   /**
//    * Overwrite this method and return false if write access should not be restricted to a single thread.
//    * 
//    * @return if single threaded write access is required (default: true)
//    */
//   protected boolean isSingleThreadedWriteAccessRequirred() {
//     return WRITE_ACCESS_MODE_SINGLE_THREAD;
//   }
// 
// }


// Path: src/main/java/org/jacis/plugin/dirtycheck/object/AbstractReadOnlyModeAndDirtyCheckSupportingObject.java
import org.jacis.plugin.readonly.object.AbstractReadOnlyModeSupportingObject;
import org.jacis.JacisApi;
import org.jacis.exception.ReadOnlyException;

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

package org.jacis.plugin.dirtycheck.object;


/**
 * Abstract base class for objects supporting switching them between the usual read-write mode and a read-only mode
 * (see {@link AbstractReadOnlyModeSupportingObject})
 * and tracking if the object is dirty by tracking if the {@link #checkWritable()} method has been called.
 *
 * @author Jan Wiemer
 */
@JacisApi
public abstract class AbstractReadOnlyModeAndDirtyCheckSupportingObject extends AbstractReadOnlyModeSupportingObject implements JacisDirtyTrackingObject {

  private boolean dirty = false;

  /** @return if the object is dirty */
  @Override
  public boolean isDirty() {
    return dirty;
  }

  @Override
  protected void checkWritable() throws ReadOnlyException {