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

/*
 * 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><li>When a FetchGroup is obtained via 
 * {@link PersistenceManagerFactory#getFetchGroup}, it is unscoped.
 * </li><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><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.
 * </li></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.</p>
     * @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.</p>
     * @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 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();
}
