Package org.hibernate.envers.internal.tools.query

Source Code of org.hibernate.envers.internal.tools.query.Parameters

/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors.  All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA  02110-1301  USA
*/
package org.hibernate.envers.internal.tools.query;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.envers.internal.tools.MutableBoolean;
import org.hibernate.envers.internal.tools.MutableInteger;

/**
* Parameters of a query, built using {@link QueryBuilder}.
*
* @author Adam Warski (adam at warski dot org)
*/
public class Parameters {
  public final static String AND = "and";
  public final static String OR = "or";

  /**
   * Main alias of the entity.
   */
  private final String alias;
  /**
   * Connective between these parameters - "and" or "or".
   */
  private final String connective;
  /**
   * For use by the parameter generator. Must be the same in all "child" (and parent) parameters.
   */
  private final MutableInteger queryParamCounter;

  /**
   * A list of sub-parameters (parameters with a different connective).
   */
  private final List<Parameters> subParameters;
  /**
   * A list of negated parameters.
   */
  private final List<Parameters> negatedParameters;
  /**
   * A list of complete where-expressions.
   */
  private final List<String> expressions;
  /**
   * Values of parameters used in expressions.
   */
  private final Map<String, Object> localQueryParamValues;

  Parameters(String alias, String connective, MutableInteger queryParamCounter) {
    this.alias = alias;
    this.connective = connective;
    this.queryParamCounter = queryParamCounter;

    subParameters = new ArrayList<Parameters>();
    negatedParameters = new ArrayList<Parameters>();
    expressions = new ArrayList<String>();
    localQueryParamValues = new HashMap<String, Object>();
  }

  // Only for deep copy purpose.
  private Parameters(Parameters other) {
    this.alias = other.alias;
    this.connective = other.connective;
    this.queryParamCounter = other.queryParamCounter.deepCopy();

    subParameters = new ArrayList<Parameters>( other.subParameters.size() );
    for ( Parameters p : other.subParameters ) {
      subParameters.add( p.deepCopy() );
    }
    negatedParameters = new ArrayList<Parameters>( other.negatedParameters.size() );
    for ( Parameters p : other.negatedParameters ) {
      negatedParameters.add( p.deepCopy() );
    }
    expressions = new ArrayList<String>( other.expressions );
    localQueryParamValues = new HashMap<String, Object>( other.localQueryParamValues );
  }

  public Parameters deepCopy() {
    return new Parameters( this );
  }

  private String generateQueryParam() {
    return "_p" + queryParamCounter.getAndIncrease();
  }

  /**
   * Adds sub-parameters with a new connective. That is, the parameters will be grouped in parentheses in the
   * generated query, e.g.: ... and (exp1 or exp2) and ..., assuming the old connective is "and", and the
   * new connective is "or".
   *
   * @param newConnective New connective of the parameters.
   *
   * @return Sub-parameters with the given connective.
   */
  public Parameters addSubParameters(String newConnective) {
    if ( connective.equals( newConnective ) ) {
      return this;
    }
    else {
      final Parameters newParams = new Parameters( alias, newConnective, queryParamCounter );
      subParameters.add( newParams );
      return newParams;
    }
  }

  /**
   * Adds negated parameters, by default with the "and" connective. These paremeters will be grouped in parentheses
   * in the generated query and negated, e.g. ... not (exp1 and exp2) ...
   *
   * @return Negated sub paremters.
   */
  public Parameters addNegatedParameters() {
    final Parameters newParams = new Parameters( alias, AND, queryParamCounter );
    negatedParameters.add( newParams );
    return newParams;
  }

  public void addWhere(String left, String op, String right) {
    addWhere( left, true, op, right, true );
  }

  /**
   * Adds <code>IS NULL</code> restriction.
   *
   * @param propertyName Property name.
   * @param addAlias Positive if an alias to property name shall be added.
   */
  public void addNullRestriction(String propertyName, boolean addAlias) {
    addWhere( propertyName, addAlias, "is", "null", false );
  }

  /**
   * Adds <code>IS NOT NULL</code> restriction.
   *
   * @param propertyName Property name.
   * @param addAlias Positive if an alias to property name shall be added.
   */
  public void addNotNullRestriction(String propertyName, boolean addAlias) {
    addWhere( propertyName, addAlias, "is not", "null", false );
  }

  public void addWhere(String left, boolean addAliasLeft, String op, String right, boolean addAliasRight) {
    final StringBuilder expression = new StringBuilder();

    if ( addAliasLeft ) {
      expression.append( alias ).append( "." );
    }
    expression.append( left );

    expression.append( " " ).append( op ).append( " " );

    if ( addAliasRight ) {
      expression.append( alias ).append( "." );
    }
    expression.append( right );

    expressions.add( expression.toString() );
  }

  public void addWhereWithParam(String left, String op, Object paramValue) {
    addWhereWithParam( left, true, op, paramValue );
  }

  public void addWhereWithParam(String left, boolean addAlias, String op, Object paramValue) {
    final String paramName = generateQueryParam();
    localQueryParamValues.put( paramName, paramValue );

    addWhereWithNamedParam( left, addAlias, op, paramName );
  }

  public void addWhereWithNamedParam(String left, String op, String paramName) {
    addWhereWithNamedParam( left, true, op, paramName );
  }

  public void addWhereWithNamedParam(String left, boolean addAlias, String op, String paramName) {
    final StringBuilder expression = new StringBuilder();

    if ( addAlias ) {
      expression.append( alias ).append( "." );
    }
    expression.append( left );
    expression.append( " " ).append( op ).append( " " );
    expression.append( ":" ).append( paramName );

    expressions.add( expression.toString() );
  }

  public void addWhereWithParams(String left, String opStart, Object[] paramValues, String opEnd) {
    final StringBuilder expression = new StringBuilder();

    expression.append( alias ).append( "." ).append( left ).append( " " ).append( opStart );

    for ( int i = 0; i < paramValues.length; i++ ) {
      final Object paramValue = paramValues[i];
      final String paramName = generateQueryParam();
      localQueryParamValues.put( paramName, paramValue );
      expression.append( ":" ).append( paramName );

      if ( i != paramValues.length - 1 ) {
        expression.append( ", " );
      }
    }

    expression.append( opEnd );

    expressions.add( expression.toString() );
  }

  public void addWhere(String left, String op, QueryBuilder right) {
    addWhere( left, true, op, right );
  }

  public void addWhere(String left, boolean addAlias, String op, QueryBuilder right) {
    final StringBuilder expression = new StringBuilder();

    if ( addAlias ) {
      expression.append( alias ).append( "." );
    }

    expression.append( left );

    expression.append( " " ).append( op ).append( " " );

    expression.append( "(" );
    right.build( expression, localQueryParamValues );
    expression.append( ")" );

    expressions.add( expression.toString() );
  }

  private void append(StringBuilder sb, String toAppend, MutableBoolean isFirst) {
    if ( !isFirst.isSet() ) {
      sb.append( " " ).append( connective ).append( " " );
    }

    sb.append( toAppend );

    isFirst.unset();
  }

  boolean isEmpty() {
    return expressions.size() == 0 && subParameters.size() == 0 && negatedParameters.size() == 0;
  }

  void build(StringBuilder sb, Map<String, Object> queryParamValues) {
    final MutableBoolean isFirst = new MutableBoolean( true );

    for ( String expression : expressions ) {
      append( sb, expression, isFirst );
    }

    for ( Parameters sub : subParameters ) {
      if ( !subParameters.isEmpty() ) {
        append( sb, "(", isFirst );
        sub.build( sb, queryParamValues );
        sb.append( ")" );
      }
    }

    for ( Parameters negated : negatedParameters ) {
      if ( !negatedParameters.isEmpty() ) {
        append( sb, "not (", isFirst );
        negated.build( sb, queryParamValues );
        sb.append( ")" );
      }
    }

    queryParamValues.putAll( localQueryParamValues );
  }
}
TOP

Related Classes of org.hibernate.envers.internal.tools.query.Parameters

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.