/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package javax.jdo.spi;

import javax.jdo.PersistenceManager;

/**
 * A class that can be managed by a binary-compatible JDO implementation must implement this
 * interface.
 *
 * <p>This interface defines methods that allow the implementation to manage the instances. It also
 * defines methods that allow a JDO aware application to examine the runtime state of instances. For
 * example, an application can discover whether the instance is persistent, transactional, dirty,
 * new, deleted, or detached; and to get its associated PersistenceManager, object identity, and
 * version if it has one.
 *
 * <p>In the Reference Implementation, the JDO Enhancer modifies the class to implement
 * PersistenceCapable prior to loading the class into the runtime environment. The Reference
 * Enhancer also adds code to implement the methods defined by PersistenceCapable.
 *
 * <p>The extra methods in the PersistenceCapable interface might be generated by pre-processing a
 * .java file, or might be generated from a tool directly. The exact technique for generating the
 * extra methods is not specified by JDO.
 *
 * <p>The PersistenceCapable interface is designed to avoid name conflicts in the scope of
 * user-defined classes. All of its declared method names are prefixed with 'jdo'.
 *
 * @version 2.0
 */
public interface PersistenceCapable {
  /**
   * If jdoFlags is set to READ_WRITE_OK, then the fields in the default fetch group can be accessed
   * for read or write without notifying the StateManager.
   */
  static final byte READ_WRITE_OK = 0;

  /**
   * If jdoFlags is set to LOAD_REQUIRED, then the fields in the default fetch group cannot be
   * accessed for read or write without notifying the StateManager.
   */
  static final byte LOAD_REQUIRED = 1;

  /**
   * If jdoFlags is set to READ_OK, then the fields in the default fetch group can be accessed for
   * read without notifying the StateManager.
   */
  static final byte READ_OK = -1;

  /**
   * If jdoFieldFlags for a field includes CHECK_READ, then the field has been enhanced to call the
   * jdoStateManager on read if the jdoFlags setting is not READ_OK or READ_WRITE_OK.
   */
  static final byte CHECK_READ = 1;

  /**
   * If jdoFieldFlags for a field includes MEDIATE_READ, then the field has been enhanced to always
   * call the jdoStateManager on all reads.
   */
  static final byte MEDIATE_READ = 2;

  /**
   * If jdoFieldFlags for a field includes CHECK_WRITE, then the field has been enhanced to call the
   * jdoStateManager on write if the jdoFlags setting is not READ_WRITE_OK;.
   */
  static final byte CHECK_WRITE = 4;

  /**
   * If jdoFieldFlags for a field includes MEDIATE_WRITE, then the field has been enhanced to always
   * call the jdoStateManager on all writes.
   */
  static final byte MEDIATE_WRITE = 8;

  /**
   * If jdoFieldFlags for a field includes SERIALIZABLE, then the field is not declared as
   * TRANSIENT.
   */
  static final byte SERIALIZABLE = 16;

  /**
   * Return the associated PersistenceManager if there is one. Transactional and persistent
   * instances return the associated PersistenceManager.
   *
   * <p>Transient non-transactional instances return null.
   *
   * <p>This method always delegates to the StateManager if it is non-null.
   *
   * @return the PersistenceManager associated with this instance.
   */
  PersistenceManager jdoGetPersistenceManager();

  /**
   * This method sets the StateManager instance that manages the state of this instance. This method
   * is normally used by the StateManager during the process of making an instance persistent,
   * transient, or transactional.
   *
   * <p>The caller of this method must have JDOPermission for the instance, if the instance is not
   * already owned by a StateManager. If the parameter is null, and the StateManager approves the
   * change, then the jdoFlags field will be reset to READ_WRITE_OK. If the parameter is not null,
   * and the security manager approves the change, then the jdoFlags field will be reset to
   * LOAD_REQUIRED.
   *
   * @param sm The StateManager which will own this instance, or null to reset the instance to
   *     transient state
   * @throws SecurityException if the caller does not have JDOPermission
   * @see JDOPermission
   */
  void jdoReplaceStateManager(StateManager sm) throws SecurityException;

  /**
   * The owning StateManager uses this method to ask the instance to provide the value of the single
   * field identified by fieldNumber.
   *
   * @param fieldNumber the field whose value is to be provided by a callback to the StateManager's
   *     providedXXXField method
   */
  void jdoProvideField(int fieldNumber);

  /**
   * The owning StateManager uses this method to ask the instance to provide the values of the
   * multiple fields identified by fieldNumbers.
   *
   * @param fieldNumbers the fields whose values are to be provided by multiple callbacks to the
   *     StateManager's providedXXXField method
   */
  void jdoProvideFields(int[] fieldNumbers);

  /**
   * The owning StateManager uses this method to ask the instance to replace the value of the single
   * field identified by number.
   *
   * @param fieldNumber the field whose value is to be replaced by a callback to the StateManager's
   *     replacingXXXField method
   */
  void jdoReplaceField(int fieldNumber);

  /**
   * The owning StateManager uses this method to ask the instance to replace the values of the
   * multiple fields identified by number.
   *
   * @param fieldNumbers the fields whose values are to be replaced by multiple callbacks to the
   *     StateManager's replacingXXXField method
   */
  void jdoReplaceFields(int[] fieldNumbers);

  /**
   * The owning StateManager uses this method to ask the instance to replace the value of the flags
   * by calling back the StateManager replacingFlags method.
   */
  void jdoReplaceFlags();

  /**
   * Copy field values from another instance of the same class to this instance.
   *
   * <p>This method will throw an exception if the other instance is not managed by the same
   * StateManager as this instance.
   *
   * @param other the PC instance from which field values are to be copied
   * @param fieldNumbers the field numbers to be copied into this instance
   */
  void jdoCopyFields(Object other, int[] fieldNumbers);

  /**
   * Explicitly mark this instance and this field dirty. Normally, PersistenceCapable classes are
   * able to detect changes made to their fields. However, if a reference to an array is given to a
   * method outside the class, and the array is modified, then the persistent instance is not aware
   * of the change. This API allows the application to notify the instance that a change was made to
   * a field.
   *
   * <p>The field name should be the fully qualified name, including package name and class name of
   * the class declaring the field. This allows unambiguous identification of the field to be marked
   * dirty. If multiple classes declare the same field, and if the package and class name are not
   * provided by the parameter in this API, then the field marked dirty is the field declared by the
   * most derived class.
   *
   * <p>Transient instances ignore this method.
   *
   * <p>
   *
   * @param fieldName the name of the field to be marked dirty.
   */
  void jdoMakeDirty(String fieldName);

  /**
   * Return a copy of the JDO identity associated with this instance.
   *
   * <p>Persistent instances of PersistenceCapable classes have a JDO identity managed by the
   * PersistenceManager. This method returns a copy of the ObjectId that represents the JDO
   * identity.
   *
   * <p>Transient instances return null.
   *
   * <p>The ObjectId may be serialized and later restored, and used with a PersistenceManager from
   * the same JDO implementation to locate a persistent instance with the same data store identity.
   *
   * <p>If the JDO identity is managed by the application, then the ObjectId may be used with a
   * PersistenceManager from any JDO implementation that supports the PersistenceCapable class.
   *
   * <p>If the JDO identity is not managed by the application or the data store, then the ObjectId
   * returned is only valid within the current transaction.
   *
   * <p>If the JDO identity is being changed in the transaction, this method returns the object id
   * as of the beginning of the current transaction.
   *
   * @see PersistenceManager#getObjectId(Object pc)
   * @see PersistenceManager#getObjectById(Object oid, boolean validate)
   * @return a copy of the ObjectId of this instance as of the beginning of the transaction.
   */
  Object jdoGetObjectId();

  /**
   * Return a copy of the JDO identity associated with this instance. This method is the same as
   * jdoGetObjectId if the identity of the instance has not changed in the current transaction.
   *
   * <p>If the JDO identity is being changed in the transaction, this method returns the current
   * object id as modified in the current transaction.
   *
   * @see #jdoGetObjectId()
   * @see PersistenceManager#getObjectId(Object pc)
   * @see PersistenceManager#getObjectById(Object oid, boolean validate)
   * @return a copy of the ObjectId of this instance as modified in the transaction.
   */
  Object jdoGetTransactionalObjectId();

  /**
   * Return the version of this instance.
   *
   * @return the version
   * @since 2.0
   */
  Object jdoGetVersion();

  /**
   * Tests whether this object is dirty.
   *
   * <p>Instances that have been modified, deleted, or newly made persistent in the current
   * transaction return true.
   *
   * <p>Transient instances return false.
   *
   * <p>
   *
   * @see javax.jdo.JDOHelper#isDirty(Object pc)
   * @see javax.jdo.JDOHelper#makeDirty(Object pc, String fieldName)
   * @see #jdoMakeDirty(String fieldName)
   * @return true if this instance has been modified in the current transaction.
   */
  boolean jdoIsDirty();

  /**
   * Tests whether this object is transactional.
   *
   * <p>Instances whose state is associated with the current transaction return true.
   *
   * <p>Transient instances return false.
   *
   * <p>
   *
   * @see javax.jdo.JDOHelper#isTransactional(Object pc)
   * @see PersistenceManager#makeTransactional(Object pc)
   * @return true if this instance is transactional.
   */
  boolean jdoIsTransactional();

  /**
   * Tests whether this object is persistent. Instances that represent persistent objects in the
   * data store return true.
   *
   * @see javax.jdo.JDOHelper#isPersistent(Object pc)
   * @see PersistenceManager#makePersistent(Object pc)
   * @return true if this instance is persistent.
   */
  boolean jdoIsPersistent();

  /**
   * Tests whether this object has been newly made persistent.
   *
   * <p>Instances that have been made persistent in the current transaction return true.
   *
   * <p>Transient instances return false.
   *
   * <p>
   *
   * @see javax.jdo.JDOHelper#isNew(Object pc)
   * @see PersistenceManager#makePersistent(Object pc)
   * @return true if this instance was made persistent in the current transaction.
   */
  boolean jdoIsNew();

  /**
   * Tests whether this object has been deleted.
   *
   * <p>Instances that have been deleted in the current transaction return true.
   *
   * <p>Transient instances return false.
   *
   * <p>
   *
   * @see javax.jdo.JDOHelper#isDeleted(Object pc)
   * @see PersistenceManager#deletePersistent(Object pc)
   * @return true if this instance was deleted in the current transaction.
   */
  boolean jdoIsDeleted();

  /**
   * Tests whether this object has been detached.
   *
   * <p>Instances that have been detached return true.
   *
   * <p>Transient instances return false.
   *
   * <p>
   *
   * @see javax.jdo.JDOHelper#isDetached(Object pc)
   * @return true if this instance is detached.
   * @since 2.0
   */
  boolean jdoIsDetached();

  /**
   * Return a new instance of this class, with the jdoStateManager set to the parameter, and
   * jdoFlags set to LOAD_REQUIRED.
   *
   * <p>This method is used as a performance optimization as an alternative to using reflection to
   * construct a new instance. It is used by the JDOImplHelper class method newInstance.
   *
   * @return a new instance of this class.
   * @see JDOImplHelper#newInstance(Class pcClass, StateManager sm)
   * @param sm the StateManager that will own the new instance.
   */
  PersistenceCapable jdoNewInstance(StateManager sm);

  /**
   * Return a new instance of this class, with the jdoStateManager set to the parameter, key fields
   * initialized to the values in the oid, and jdoFlags set to LOAD_REQUIRED.
   *
   * <p>This method is used as a performance optimization as an alternative to using reflection to
   * construct a new instance of a class that uses application identity. It is used by the
   * JDOImplHelper class method newInstance.
   *
   * @return a new instance of this class.
   * @see JDOImplHelper#newInstance(Class pcClass, StateManager sm)
   * @param sm the StateManager that will own the new instance.
   * @param oid an instance of the object id class (application identity).
   */
  PersistenceCapable jdoNewInstance(StateManager sm, Object oid);

  /**
   * Create a new instance of the ObjectId class for this PersistenceCapable class and initialize
   * the key fields from the instance on which this method is called. This method creates a new
   * instance of the class used for JDO identity. It is intended only for application identity. If
   * the class has been enhanced for datastore identity, or if the class is abstract, null is
   * returned.
   *
   * <p>For classes using single field identity, this method must be called on an instance of a
   * persistence-capable class with its primary key field initialized (not null), or a <code>
   * JDONullIdentityException</code> is thrown.
   *
   * <p>The instance returned is initialized with the value(s) of the primary key field(s) of the
   * instance on which the method is called.
   *
   * @return the new instance created.
   */
  Object jdoNewObjectIdInstance();

  /**
   * Create a new instance of the class used for JDO identity, using the key constructor of the
   * object id class. It is intended for single field identity. The identity instance returned has
   * no relationship with the values of the primary key fields of the persistence-capable instance
   * on which the method is called. If the key is the wrong class for the object id class, null is
   * returned.
   *
   * <p>For classes that use single field identity, if the parameter is of one of the following
   * types, the behavior must be as specified:
   *
   * <ul>
   *   <li><code>Number</code> or <code>Character</code>: the parameter must be the single field
   *       type or the wrapper class of the primitive field type; the parameter is passed to the
   *       single field identity constructor
   *   <li><code>ObjectIdFieldSupplier</code>: the field value is fetched from the <code>
   *       ObjectIdFieldSupplier</code> and passed to the single field identity constructor
   *   <li><code>String</code>: the String is passed to the single field identity constructor
   * </ul>
   *
   * @return the new instance created.
   * @param o the object identity constructor parameter
   * @since 2.0
   */
  Object jdoNewObjectIdInstance(Object o);

  /**
   * Copy fields from this PersistenceCapable instance to the Object Id instance. For classes using
   * single field identity, this method always throws <code>JDOUserException</code>.
   *
   * @param oid the ObjectId target of the key fields
   */
  void jdoCopyKeyFieldsToObjectId(Object oid);

  /**
   * Copy fields from an outside source to the key fields in the ObjectId. This method is generated
   * in the <code>PersistenceCapable</code> class to generate a call to the field manager for each
   * key field in the ObjectId. For example, an ObjectId class that has three key fields <code>
   * (int id,
   * String name, and Float salary)</code> would have the method generated: <code>
   * void jdoCopyKeyFieldsToObjectId
   * (ObjectIdFieldSupplier fm, Object objectId) {
   * EmployeeKey oid = (EmployeeKey)objectId;
   * oid.id = fm.fetchIntField (0);
   * oid.name = fm.fetchStringField (1);
   * oid.salary = fm.fetchObjectField (2);
   * }</code>
   *
   * <p>The implementation is responsible for implementing the <code>ObjectIdFieldSupplier</code> to
   * produce the values for the key fields.
   *
   * <p>For classes using single field identity, this method always throws <code>JDOUserException
   * </code>.
   *
   * @param oid the ObjectId target of the copy.
   * @param fm the field supplier that supplies the field values.
   */
  void jdoCopyKeyFieldsToObjectId(ObjectIdFieldSupplier fm, Object oid);

  /**
   * Copy fields to an outside consumer from the key fields in the ObjectId. This method is
   * generated in the <code>PersistenceCapable</code> class to generate a call to the field manager
   * for each key field in the ObjectId. For example, an ObjectId class that has three key fields
   * <code>(int id,
   * String name, and Float salary)</code> would have the method generated: <code>
   * void copyKeyFieldsFromObjectId(ObjectIdFieldConsumer fm, Object objectId) {
   *     EmployeeKey oid = (EmployeeKey)objectId;
   *     fm.storeIntField (0, oid.id);
   *     fm.storeStringField (1, oid.name);
   *     fm.storeObjectField (2, oid.salary);
   * }</code>
   *
   * <p>The implementation is responsible for implementing the <code>ObjectIdFieldConsumer</code> to
   * store the values for the key fields.
   *
   * @param oid the ObjectId source of the copy.
   * @param fm the field manager that receives the field values.
   */
  void jdoCopyKeyFieldsFromObjectId(ObjectIdFieldConsumer fm, Object oid);

  /**
   * This interface is a convenience interface that allows an instance to implement both <code>
   * ObjectIdFieldSupplier</code> and <code>ObjectIdFieldConsumer</code>.
   */
  static interface ObjectIdFieldManager extends ObjectIdFieldConsumer, ObjectIdFieldSupplier {}

  /**
   * This interface is used to provide fields to the Object id instance. It is used by the method
   * copyKeyFieldsToObjectId. When the method is called, the generated code calls the instance of
   * ObjectIdFieldManager for each field in the object id.
   */
  static interface ObjectIdFieldSupplier {

    /**
     * Fetch one field from the field manager. This field will be stored in the proper field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @return the value of the field to be stored into the ObjectId.
     */
    boolean fetchBooleanField(int fieldNumber);

    /**
     * Fetch one field from the field manager. This field will be stored in the proper field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @return the value of the field to be stored into the ObjectId.
     */
    char fetchCharField(int fieldNumber);

    /**
     * Fetch one field from the field manager. This field will be stored in the proper field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @return the value of the field to be stored into the ObjectId.
     */
    byte fetchByteField(int fieldNumber);

    /**
     * Fetch one field from the field manager. This field will be stored in the proper field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @return the value of the field to be stored into the ObjectId.
     */
    short fetchShortField(int fieldNumber);

    /**
     * Fetch one field from the field manager. This field will be stored in the proper field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @return the value of the field to be stored into the ObjectId.
     */
    int fetchIntField(int fieldNumber);

    /**
     * Fetch one field from the field manager. This field will be stored in the proper field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @return the value of the field to be stored into the ObjectId.
     */
    long fetchLongField(int fieldNumber);

    /**
     * Fetch one field from the field manager. This field will be stored in the proper field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @return the value of the field to be stored into the ObjectId.
     */
    float fetchFloatField(int fieldNumber);

    /**
     * Fetch one field from the field manager. This field will be stored in the proper field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @return the value of the field to be stored into the ObjectId.
     */
    double fetchDoubleField(int fieldNumber);

    /**
     * Fetch one field from the field manager. This field will be stored in the proper field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @return the value of the field to be stored into the ObjectId.
     */
    String fetchStringField(int fieldNumber);

    /**
     * Fetch one field from the field manager. This field will be stored in the proper field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @return the value of the field to be stored into the ObjectId.
     */
    Object fetchObjectField(int fieldNumber);
  }

  /**
   * This interface is used to store fields from the Object id instance. It is used by the method
   * copyKeyFieldsFromObjectId. When the method is called, the generated code calls the instance of
   * ObjectIdFieldManager for each field in the object id.
   */
  static interface ObjectIdFieldConsumer {

    /**
     * Store one field into the field manager. This field was retrieved from the field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @param value the value of the field from the ObjectId.
     */
    void storeBooleanField(int fieldNumber, boolean value);

    /**
     * Store one field into the field manager. This field was retrieved from the field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @param value the value of the field from the ObjectId.
     */
    void storeCharField(int fieldNumber, char value);

    /**
     * Store one field into the field manager. This field was retrieved from the field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @param value the value of the field from the ObjectId.
     */
    void storeByteField(int fieldNumber, byte value);

    /**
     * Store one field into the field manager. This field was retrieved from the field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @param value the value of the field from the ObjectId.
     */
    void storeShortField(int fieldNumber, short value);

    /**
     * Store one field into the field manager. This field was retrieved from the field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @param value the value of the field from the ObjectId.
     */
    void storeIntField(int fieldNumber, int value);

    /**
     * Store one field into the field manager. This field was retrieved from the field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @param value the value of the field from the ObjectId.
     */
    void storeLongField(int fieldNumber, long value);

    /**
     * Store one field into the field manager. This field was retrieved from the field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @param value the value of the field from the ObjectId.
     */
    void storeFloatField(int fieldNumber, float value);

    /**
     * Store one field into the field manager. This field was retrieved from the field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @param value the value of the field from the ObjectId.
     */
    void storeDoubleField(int fieldNumber, double value);

    /**
     * Store one field into the field manager. This field was retrieved from the field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @param value the value of the field from the ObjectId.
     */
    void storeStringField(int fieldNumber, String value);

    /**
     * Store one field into the field manager. This field was retrieved from the field of the
     * ObjectId.
     *
     * @param fieldNumber the field number of the key field.
     * @param value the value of the field from the ObjectId.
     */
    void storeObjectField(int fieldNumber, Object value);
  }
}
