/*
 * 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.
 */

/*
 * FetchGroup.java
 *
 */

package javax.jdo;

import java.util.Set;

/**
 * FetchGroup represents a named fetch group for a specific class or interface. A fetch group
 * instance identifies the name of the class or interface, the list of members (fields or
 * properties) to be fetched when the fetch group is active, and the recursion depth for each
 * member.
 *
 * <p>Fetch groups are updated using methods on this interface. An instance of a class implementing
 * this interface can be obtained from {@link PersistenceManager#getFetchGroup} or {@link
 * PersistenceManagerFactory#getFetchGroup}.
 *
 * <p>A FetchGroup can be unscoped or can be in one of two scopes (the {@link PersistenceManager} or
 * the {@link PersistenceManagerFactory} scope). Unscoped FetchGroups do not affect any behavior. A
 * FetchGroup in PersistenceManager scope hides the corresponding FetchGroup in the
 * PersistenceManagerFactory scope.
 *
 * <ul>
 *   <li>When a FetchGroup is obtained via {@link PersistenceManager#getFetchGroup}, it is
 *       immediately in scope of its <code>PersistenceManager</code>. Subsequent modifications of
 *       the FetchGroup immediately affect <code>FetchPlan</code>s that contain the <code>FetchGroup
 *       </code>.
 *   <li>When a FetchGroup is obtained via {@link PersistenceManagerFactory#getFetchGroup}, it is
 *       unscoped.
 *   <li>When a FetchGroup is added to the set of active FetchGroups via {@link
 *       PersistenceManagerFactory#addFetchGroups}, it is put in scope of the <code>
 *       PersistenceManagerFactory</code>.
 *   <li>When a FetchGroup is removed from the set of active FetchGroups via {@link
 *       PersistenceManagerFactory#removeFetchGroups}, {@link
 *       PersistenceManagerFactory#removeAllFetchGroups}, or replaced via {@link
 *       PersistenceManagerFactory#addFetchGroups}, it is unscoped.
 * </ul>
 *
 * @version 2.2
 * @since 2.2
 */
public interface FetchGroup {

  /**
   * For use with {@link #addCategory} and {@link #removeCategory} calls. This category includes
   * members defined in the default fetch group in xml or annotations. Redefining the default fetch
   * group via the API does not affect the members defined by this category.
   *
   * <p>Using this category also sets the fetch-depth for the members in the default fetch group.
   *
   * @since 2.2
   */
  public static final String DEFAULT = "default";

  /**
   * For use with {@link #addCategory} and {@link #removeCategory} calls. This category includes
   * members of all relationship types.
   *
   * @since 2.2
   */
  public static final String RELATIONSHIP = "relationship";

  /**
   * For use with {@link #addCategory} and {@link #removeCategory} calls. This category includes
   * members of all multi-valued types, including Collection, array, and Map types of basic and
   * relationship types.
   *
   * @since 2.2
   */
  public static final String MULTIVALUED = "multivalued";

  /**
   * For use with {@link #addCategory} and {@link #removeCategory} calls. This category includes
   * members of all primitive and immutable object class types as defined in section 6.4 of the
   * specification, including String, Locale, Currency, BigDecimal, and BigInteger; as well as Date
   * and its jdbc subtypes and Enum types.
   *
   * @since 2.2
   */
  public static final String BASIC = "basic";

  /**
   * For use with {@link #addCategory} and {@link #removeCategory} calls. This category includes all
   * members in the persistent type.
   *
   * <p>Using this category also sets the fetch-depth for the members in the default fetch group.
   *
   * @since 2.2
   */
  public static final String ALL = "all";

  /**
   * Return the hashCode for this instance. The hash code should combine both the class and fetch
   * group name. The hash codes for two equal instances must be identical.
   *
   * @return the hash code
   * @since 2.2
   */
  int hashCode();

  /**
   * Return whether this instance is equal to the other. The equals method must compare the class
   * for identity and the fetch group name for equality.
   *
   * @return whether this instance is equal to the other
   * @since 2.2
   */
  boolean equals(Object other);

  /**
   * Get the name of this FetchGroup. The name is set only in the factory method.
   *
   * @return the name
   * @since 2.2
   */
  String getName();

  /**
   * Get the persistent type (class or interface) of this FetchGroup. The persistent type is set
   * only in the factory method(s).
   *
   * @return the persistent type
   * @since 2.2
   */
  Class<?> getType();

  /**
   * Get the post-load property of this FetchGroup.
   *
   * @return the post-load property
   * @since 2.2
   */
  boolean getPostLoad();

  /**
   * Set the post-load property of this FetchGroup.
   *
   * @param postLoad Whether to post load this fetch group
   * @return the FetchGroup
   * @throws JDOUserException if the FetchGroup is unmodifiable
   * @since 2.2
   */
  FetchGroup setPostLoad(boolean postLoad);

  /**
   * Add the member (field or property) to the set of members in this FetchGroup.
   *
   * @param memberName the name of a member to add to the FetchGroup
   * @return the FetchGroup
   * @throws JDOUserException if the parameter is not a member of the persistent type
   * @throws JDOUserException if the FetchGroup is unmodifiable
   * @since 2.2
   */
  FetchGroup addMember(String memberName);

  /**
   * Add the member (field or property) to the set of members in this FetchGroup. Duplicates are
   * ignored.
   *
   * @param memberNames the names of members to add to the FetchGroup
   * @return the FetchGroup
   * @throws JDOUserException if any parameter is not a member of the persistent type
   * @throws JDOUserException if the FetchGroup is unmodifiable
   * @since 2.2
   */
  FetchGroup addMembers(String... memberNames);

  /**
   * Remove the member (field or property) from the set of members in this FetchGroup.
   *
   * @param memberName Name of the member of the class to remove from the FetchGroup.
   * @return the FetchGroup
   * @throws JDOUserException if the parameter is not a member of the persistent type
   * @throws JDOUserException if the FetchGroup is unmodifiable
   * @since 2.2
   */
  FetchGroup removeMember(String memberName);

  /**
   * Remove the member (field or property) from the set of members in this FetchGroup. Duplicates in
   * the parameter list are eliminated before removing them from the membership.
   *
   * @param memberNames Member names of the class to remove from this FetchGroup.
   * @return the FetchGroup
   * @throws JDOUserException if any parameter is not a member of the persistent type
   * @throws JDOUserException if the FetchGroup is unmodifiable
   * @since 2.2
   */
  FetchGroup removeMembers(String... memberNames);

  /**
   * Add the members (fields or properties) of the named category to the set of members in this
   * FetchGroup. This method first resolves the category name to a set of members and then adds the
   * members as if {@link #addMembers} was called. After this method executes, the category is not
   * remembered.
   *
   * @param categoryName Category to add to this FetchGroup.
   * @return the FetchGroup
   * @throws JDOUserException if the FetchGroup is unmodifiable
   * @since 2.2
   */
  FetchGroup addCategory(String categoryName);

  /**
   * Remove the members (fields or properties) of the named category from the set of members in this
   * FetchGroup. This method first resolves the category name to a set of members and then removes
   * the members as if {@link #removeMembers} was called. After this method executes, the category
   * is not remembered.
   *
   * @param categoryName Category to remove from this FetchGroup.
   * @return the FetchGroup
   * @throws JDOUserException if the FetchGroup is unmodifiable
   * @since 2.2
   */
  FetchGroup removeCategory(String categoryName);

  /**
   * Set the recursion-depth for this member. The default is 1. A value of 0 means don't fetch the
   * member (as if the member were omitted entirely). A value of -1 means fetch all instances
   * reachable via this member.
   *
   * @return the FetchGroup
   * @param memberName the name of the field or property
   * @param recursionDepth the value for the recursion-depth property
   * @throws JDOUserException if the member does not exist
   * @throws JDOUserException if the FetchGroup is unmodifiable
   * @since 2.2
   */
  FetchGroup setRecursionDepth(String memberName, int recursionDepth);

  /**
   * Get the recursion-depth for this member.
   *
   * @param memberName the name of the field or property
   * @return the recursion-depth for this member
   * @throws JDOUserException if the member is not in the FetchGroup
   * @since 2.2
   */
  int getRecursionDepth(String memberName);

  /**
   * Return an immutable Set of String containing the names of all members. The Set is a copy of the
   * currently defined members and will not change based on subsequent changes to the membership in
   * the FetchGroup.
   *
   * @return an immutable Set containing the names of all members in the FetchGroup
   * @since 2.2
   */
  Set<String> getMembers();

  /**
   * Make this FetchGroup unmodifiable. If already unmodifiable, this method has no effect.
   *
   * @return the FetchGroup
   * @since 2.2
   */
  FetchGroup setUnmodifiable();

  /**
   * Return whether this FetchGroup is unmodifiable. If so, methods {@link #setPostLoad}, {@link
   * #addMember}, {@link #removeMember}, {@link #addMembers}, {@link #removeMembers}, {@link
   * #addCategory}, and {@link #removeCategory} will throw {@link JDOUserException}.
   *
   * @return whether the FetchGroup is unmodifiable
   * @since 2.2
   */
  boolean isUnmodifiable();
}
