# ParameterIndices.java

    /*
    ** Module   : ParameterIndices.java
    ** Abstract : Mapping of query substitution parameters in an array, after where clause preprocessing.
    **
    ** Copyright (c) 2008-2022, Golden Code Development Corporation.
    **
    ** -#- -I- --Date-- -JPRM- ------------------------------------Description------------------------------------
    ** 001 ECF 20081009 @40080 Created initial version. A mapping of query substitution parameters in an array,
    **                         after where clause preprocessing.
    ** 002 OM  20221103        New class names for FQLPreprocessor, FQLExpression, FQLBundle, and FQLCache.
    */

    /*
    ** This program is free software: you can redistribute it and/or modify
    ** it under the terms of the GNU Affero General Public License as
    ** published by the Free Software Foundation, either version 3 of the
    ** License, or (at your option) any later version.
    **
    ** This program is distributed in the hope that it will be useful,
    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ** GNU Affero General Public License for more details.
    **
    ** You may find a copy of the GNU Affero GPL version 3 at the following
    ** location: https://www.gnu.org/licenses/agpl-3.0.en.html
    **
    ** Additional terms under GNU Affero GPL version 3 section 7:
    **
    **   Under Section 7 of the GNU Affero GPL version 3, the following additional
    **   terms apply to the works covered under the License.  These additional terms
    **   are non-permissive additional terms allowed under Section 7 of the GNU
    **   Affero GPL version 3 and may not be removed by you.
    **
    **   0. Attribution Requirement.
    **
    **     You must preserve all legal notices or author attributions in the covered
    **     work or Appropriate Legal Notices displayed by works containing the covered
    **     work.  You may not remove from the covered work any author or developer
    **     credit already included within the covered work.
    **
    **   1. No License To Use Trademarks.
    **
    **     This license does not grant any license or rights to use the trademarks
    **     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
    **     of Golden Code Development Corporation. You are not authorized to use the
    **     name Golden Code, FWD, or the names of any author or contributor, for
    **     publicity purposes without written authorization.
    **
    **   2. No Misrepresentation of Affiliation.
    **
    **     You may not represent yourself as Golden Code Development Corporation or FWD.
    **
    **     You may not represent yourself for publicity purposes as associated with
    **     Golden Code Development Corporation, FWD, or any author or contributor to
    **     the covered work, without written authorization.
    **
    **   3. No Misrepresentation of Source or Origin.
    **
    **     You may not represent the covered work as solely your work.  All modified
    **     versions of the covered work must be marked in a reasonable way to make it
    **     clear that the modified work is not originating from Golden Code Development
    **     Corporation or FWD.  All modified versions must contain the notices of
    **     attribution required in this license.
    */

    package com.goldencode.p2j.persist;

    /**
     * A mapping of the active indices in an array of query substitution
     * parameters, after an HQL where clause has been preprocessed.  The HQL
     * preprocessor may inline or re-order query substitution parameters.  Thus,
     * given an array of query substitution parameters, it is necessary to provide
     * a means for a query object to organize the remaining parameters when
     * submitting a query for execution.
     * <p>
     * A query object will have the original array of parameters provided by
     * business logic, as well as an instance of {@link FQLPreprocessor}.  That
     * instance will provide an instance of this class via its {@link
     * FQLPreprocessor#getParameterIndices()} method.  To obtain the correct list
     * of parameters which corresponds with the preprocessed where clause, the
     * query iterates its original array of parameters.  For each index in that
     * array, it calls {@link #getIndex(int)} to obtain the remapped position of
     * the parameter originally at the current index.  If <code>null</code> is
     * returned, it means the parameter originally at the current index has been
     * inlined into the where clause.  A non-<code>null</code> value represents
     * the zero-based index at which the parameter can be found in the original
     * array.
     */
    final class ParameterIndices
    {
       /** Count of substitution parameters in use */
       private final int count;

       /** Mapping of indices of parameters in original array */
       private final Integer[] indices;

       /**
        * Constructor which sets the array of new index positions of query
        * substitution parameters for the associated where clause.
        *
        * @param   indices
        *          Array of zero-based index positions of query substitution
        *          parameters in the original array of parameters.  If
        *          <code>null</code>, the associated query string has no query
        *          substitution parameters.
        */
       ParameterIndices(Integer[] indices)
       {
          int i = 0;

          if (indices != null)
          {
             for (Integer next : indices)
             {
                if (next != null)
                {
                   i++;
                }
             }
          }

          this.indices = indices;
          this.count = i;
       }

       /**
        * Get the count of query substitution parameters which survived the where
        * clause preprocessing step.  This is the count of non-<code>null</code>
        * index positions in the array of indices passed to this object's
        * constructor.
        *
        * @return  Count of query substitution parameters.
        */
       int getCount()
       {
          return count;
       }

       /**
        * Given a position of a query substitution parameter in the original array
        * of parameters (before the where clause preprocessing step), get the new,
        * zero-based index of that parameter in the original array.  Note that the
        * original array is not changed, only the mapping of indices may have
        * changed.  If the index returned matches the <code>position</code>
        * supplied, this indicates the parameter's placeholder (<code>?</code>) is
        * located at the same relative position in the where clause as before
        * preprocessing.
        *
        * @param   position
        *          Zero-based index of the target substitution parameter in the
        *          original array.
        *
        * @return  New, zero-based index of the target substitution parameter in
        *          the original array, or <code>null</code> if the parameter was
        *          inlined during preprocessing of the where clause.
        */
       Integer getIndex(int position)
       {
          return (indices == null ? null : indices[position]);
       }
    }