Open Source Repository

Home /hibernate/hibernate-3.2.6.ga | Repository Home



org/hibernate/hql/ast/tree/AbstractNullnessCheckNode.java
/*
 * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
 *
 * 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, v. 2.1. This program is distributed in the
 * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
 * distribution; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * Red Hat Author(s): Steve Ebersole
 */
package org.hibernate.hql.ast.tree;

import antlr.collections.AST;

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

/**
 * AbstractNullnessCheckNode implementation
 *
 @author Steve Ebersole
 */
public abstract class AbstractNullnessCheckNode extends UnaryLogicOperatorNode {
  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 = extractDataTypegetOperand() );
    if operandType == null ) {
      return;
    }
    SessionFactoryImplementor sessionFactory = getSessionFactoryHelper().getFactory();
    int operandColumnSpan = operandType.getColumnSpansessionFactory );
    if operandColumnSpan > ) {
      mutateRowValueConstructorSyntaxoperandColumnSpan );
    }
  }

  protected abstract int getExpansionConnectorType();
  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();

    setTypeexpansionConnectorType );
    setTextexpansionConnectorText );

    String[] mutationTexts = extractMutationTextsgetOperand(), operandColumnSpan );

    AST container = this;
    for int i = operandColumnSpan - 1; i > 0; i-- ) {
      if i == ) {
        AST op1 = getASTFactory().createcomparisonType, comparisonText );
        AST operand1 = getASTFactory().createHqlSqlTokenTypes.SQL_TOKEN, mutationTexts[0] );
        op1.setFirstChildoperand1 );
        container.setFirstChildop1 );
        AST op2 = getASTFactory().createcomparisonType, comparisonText );
        AST operand2 = getASTFactory().createHqlSqlTokenTypes.SQL_TOKEN, mutationTexts[1] );
        op2.setFirstChildoperand2 );
        op1.setNextSiblingop2 );
      }
      else {
        AST op = getASTFactory().createcomparisonType, comparisonText );
        AST operand = getASTFactory().createHqlSqlTokenTypes.SQL_TOKEN, mutationTexts[i] );
        op.setFirstChildoperand );
        AST newContainer = getASTFactory().createexpansionConnectorType, expansionConnectorText );
        container.setFirstChildnewContainer );
        newContainer.setNextSiblingop );
        container = newContainer;
      }
    }
  }

  protected Type extractDataType(Node operand) {
    Type type = null;
    if operand instanceof SqlNode ) {
      type = ( ( SqlNode operand ).getDataType();
    }
    if type == null && operand instanceof ExpectedTypeAwareNode ) {
      type = ( ( ExpectedTypeAwareNode operand ).getExpectedType();
    }
    return type;
  }

  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 ) {
      String[] rtn = new Stringoperand.getNumberOfChildren() ];
      int x = 0;
      AST node = operand.getFirstChild();
      while node != null ) {
        rtnx++ = node.getText();
        node = node.getNextSibling();
      }
      return rtn;
    }
    else if operand instanceof SqlNode ) {
      String nodeText = operand.getText();
      if nodeText.startsWith"(" ) ) {
        nodeText = nodeText.substring);
      }
      if nodeText.endsWith")" ) ) {
        nodeText = nodeText.substring0, nodeText.length() );
      }
      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 );
    }
  }
}