Package org.hibernate.hql.internal.ast.tree

Source Code of org.hibernate.hql.internal.ast.tree.AbstractNullnessCheckNode

/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
*
* 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.hql.internal.ast.tree;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.type.Type;

import antlr.collections.AST;

/**
* Base class for nodes dealing 'is null' and 'is not null' operators.
* <p/>
* todo : a good deal of this is copied from BinaryLogicOperatorNode; look at consolidating these code fragments
*
* @author Steve Ebersole
*/
public abstract class AbstractNullnessCheckNode extends UnaryLogicOperatorNode {
  @Override
  public void initialize() {
    // TODO : this really needs to be delayed unitl after we definitively know the operand node type;
    // where this is currently a problem is parameters for which where we cannot unequivocally
    // resolve an expected type
    Type operandType = extractDataType( getOperand() );
    if ( operandType == null ) {
      return;
    }
    SessionFactoryImplementor sessionFactory = getSessionFactoryHelper().getFactory();
    int operandColumnSpan = operandType.getColumnSpan( sessionFactory );
    if ( operandColumnSpan > 1 ) {
      mutateRowValueConstructorSyntax( operandColumnSpan );
    }
  }

  /**
   * When (if) we need to expand a row value constructor, what is the type of connector to use between the
   * expansion fragments.
   *
   * @return The expansion connector type.
   */
  protected abstract int getExpansionConnectorType();

  /**
   * When (if) we need to expand a row value constructor, what is the text of the connector to use between the
   * expansion fragments.
   *
   * @return The expansion connector text.
   */
  protected abstract String getExpansionConnectorText();

  private void mutateRowValueConstructorSyntax(int operandColumnSpan) {
    final int comparisonType = getType();
    final String comparisonText = getText();

    final int expansionConnectorType = getExpansionConnectorType();
    final String expansionConnectorText = getExpansionConnectorText();

    setType( expansionConnectorType );
    setText( expansionConnectorText );

    String[] mutationTexts = extractMutationTexts( getOperand(), operandColumnSpan );

    AST container = this;
    for ( int i = operandColumnSpan - 1; i > 0; i-- ) {
      if ( i == 1 ) {
        AST op1 = getASTFactory().create( comparisonType, comparisonText );
        AST operand1 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, mutationTexts[0] );
        op1.setFirstChild( operand1 );
        container.setFirstChild( op1 );
        AST op2 = getASTFactory().create( comparisonType, comparisonText );
        AST operand2 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, mutationTexts[1] );
        op2.setFirstChild( operand2 );
        op1.setNextSibling( op2 );
      }
      else {
        AST op = getASTFactory().create( comparisonType, comparisonText );
        AST operand = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, mutationTexts[i] );
        op.setFirstChild( operand );
        AST newContainer = getASTFactory().create( expansionConnectorType, expansionConnectorText );
        container.setFirstChild( newContainer );
        newContainer.setNextSibling( op );
        container = newContainer;
      }
    }
  }

  private static Type extractDataType(Node operand) {
    if ( operand instanceof SqlNode ) {
      return ( (SqlNode) operand ).getDataType();
    }

    if ( operand instanceof ExpectedTypeAwareNode ) {
      return ( (ExpectedTypeAwareNode) operand ).getExpectedType();
    }

    return null;
  }

  private static String[] extractMutationTexts(Node operand, int count) {
    if ( operand instanceof ParameterNode ) {
      String[] rtn = new String[count];
      for ( int i = 0; i < count; i++ ) {
        rtn[i] = "?";
      }
      return rtn;
    }
    else if ( operand.getType() == HqlSqlTokenTypes.VECTOR_EXPR ) {
      final String[] rtn = new String[ operand.getNumberOfChildren() ];
      AST node = operand.getFirstChild();
      int x = 0;
      while ( node != null ) {
        rtn[ x++ ] = node.getText();
        node = node.getNextSibling();
      }
      return rtn;
    }
    else if ( operand instanceof SqlNode ) {
      String nodeText = operand.getText();
      if ( nodeText.startsWith( "(" ) ) {
        nodeText = nodeText.substring( 1 );
      }
      if ( nodeText.endsWith( ")" ) ) {
        nodeText = nodeText.substring( 0, nodeText.length() - 1 );
      }
      String[] splits = StringHelper.split( ", ", nodeText );
      if ( count != splits.length ) {
        throw new HibernateException( "SqlNode's text did not reference expected number of columns" );
      }
      return splits;
    }
    else {
      throw new HibernateException( "dont know how to extract row value elements from node : " + operand );
    }
  }
}
TOP

Related Classes of org.hibernate.hql.internal.ast.tree.AbstractNullnessCheckNode

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.