/*
 * 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
<<<<<<< Updated upstream
 *
 *     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
=======
 * 
 *     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 
>>>>>>> Stashed changes
 * 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);
  }
}
