Esempio n. 1
0
  private void appendPredicateAndValue(
      CQLAttribute attribute,
      StringBuilder hql,
      List<java.lang.Object> parameters,
      CQLObject queryObject)
      throws QueryTranslationException {
    LOG.debug("Appending predicate to HQL determining object value");

    // determine if the predicate is unary
    boolean unaryPredicate = attribute.getUnaryPredicate() != null;
    LOG.debug("Predicate is " + (unaryPredicate ? "not " : "") + "unary");
    // append the predicate
    hql.append(' ');
    String predicateAsString = null;
    if (unaryPredicate) {
      predicateAsString = predicateValues.get(attribute.getUnaryPredicate());
    } else {
      predicateAsString = predicateValues.get(attribute.getBinaryPredicate());
    }
    if (!unaryPredicate) {
      hql.append(predicateAsString).append(' ');

      // add a placeholder parameter to the HQL query
      hql.append('?');

      // convert the attribute value to the specific data type of the attribute
      Class<?> attributeType = null;
      try {
        attributeType =
            typesInformationResolver.getJavaDataType(
                stripGeneric(queryObject.getClassName()), attribute.getName());
      } catch (TypesInformationException ex) {
        LOG.error("Error determining type: " + ex.getMessage(), ex);
        throw new QueryTranslationException(ex.getMessage(), ex);
      }
      if (attributeType == null) {
        throw new QueryTranslationException(
            "No type could be determined for attribute "
                + queryObject.getClassName()
                + "."
                + attribute.getName());
      }
      LOG.debug("Determined java type to be " + attribute.getName());
      java.lang.Object value =
          getAttributeValueObject(attributeType, attribute.getAttributeValue());

      // add a positional parameter value to the list
      parameters.add(value);
    } else {
      // binary predicates just get appended w/o values associated with them
      hql.append(predicateAsString);
    }
  }
Esempio n. 2
0
  /**
   * Processes a CQL query attribute into HQL
   *
   * @param attribute The CQL attribute
   * @param hql The HQL statement fragment
   * @param parameters The positional parameters list
   * @param associationTrace The trace of associations
   * @param objectClassName The class name of the object to which this association belongs
   * @throws QueryTranslationException
   */
  private void processAttribute(
      CQLAttribute attribute,
      StringBuilder hql,
      List<java.lang.Object> parameters,
      CQLObject queryObject,
      String queryObjectAlias,
      Stack<CQLAssociatedObject> associationStack,
      List<CqlDataBucket> typesProcessingList)
      throws QueryTranslationException {
    LOG.debug("Processing attribute " + queryObject.getClassName() + "." + attribute.getName());

    // determine what the flavor of this attribute is
    DatatypeFlavor flavor = typesProcessingList.get(typesProcessingList.size() - 1).datatypeFlavor;
    LOG.debug("Datatype flavor is " + flavor.name());
    // DSET<Ii>, (and TEL and CD) ends up as "COMPLEX_WITH_SIMPLE_CONTENT" because it's modeled as
    // an
    // association to DSET, then to Ii, which is that type.  Appears to work OK.
    // FIXME: DSET<Ad> doesn't work because I can't get the information about the part names inside
    // the AD
    // out of the Hibernate configuration object API.  Interestingly, AD by itself is fine.
    switch (flavor) {
      case STANDARD:
      case ENUMERATION:
        processStandardAttribute(attribute, hql, parameters, queryObject, queryObjectAlias);
        break;
      case COMPLEX_WITH_SIMPLE_CONTENT:
        processComplexAttributeWithSimpleOrMixedContent(
            attribute, hql, parameters, associationStack, typesProcessingList);
        break;
      case COMPLEX_WITH_MIXED_CONTENT:
        processComplexAttributeWithSimpleOrMixedContent(
            attribute, hql, parameters, associationStack, typesProcessingList);
        break;
      case COMPLEX_WITH_COLLECTION_OF_COMPLEX:
        if (currentlyWrappedByDset(typesProcessingList)) {
          processDsetOfComplexDatatypeWithCollectionOfComplexAttributesWithSimpleContent(
              attribute, hql, parameters, associationStack, typesProcessingList);
        } else {
          processComplexAttributeWithCollectionOfComplexAttributesWithSimpleContent(
              attribute, hql, parameters, associationStack, typesProcessingList);
        }
        break;
      case COLLECTION_OF_COMPLEX_WITH_SIMPLE_CONTENT:
        processComplexAttributeWithSimpleOrMixedContent(
            attribute, hql, parameters, associationStack, typesProcessingList);
        break;
      case COLLECTION_OF_COMPLEX_WITH_COLLECTION_OF_COMPLEX_WITH_SIMPLE_CONTENT:
        // gah
        break;
    }
  }
Esempio n. 3
0
  /**
   * Processes a CQL group into HQL
   *
   * @param group The CQL Group
   * @param hql The HQL fragment which will be edited
   * @param parameters The positional HQL query parameters
   * @param associationTrace The trace of associations
   * @param sourceClassName The class to which this group belongs
   * @throws QueryTranslationException
   */
  private void processGroup(
      CQLGroup group,
      StringBuilder hql,
      List<java.lang.Object> parameters,
      Stack<CQLAssociatedObject> associationStack,
      List<CqlDataBucket> typesProcessingList,
      CQLObject sourceQueryObject,
      String sourceAlias)
      throws QueryTranslationException {
    LOG.debug("Processing group on " + sourceQueryObject.getClassName());

    String logic = convertLogicalOperator(group.getLogicalOperation());
    boolean mustAddLogic = false;

    // open the group
    hql.append('(');

    if (group.getCQLAttribute() != null) {
      for (int i = 0; i < group.getCQLAttribute().length; i++) {
        mustAddLogic = true;
        processAttribute(
            group.getCQLAttribute(i),
            hql,
            parameters,
            sourceQueryObject,
            sourceAlias,
            associationStack,
            typesProcessingList);
        if (i + 1 < group.getCQLAttribute().length) {
          hql.append(' ').append(logic).append(' ');
        }
      }
    }
    if (group.getCQLAssociatedObject() != null) {
      if (mustAddLogic) {
        hql.append(' ').append(logic).append(' ');
      }
      for (int i = 0; i < group.getCQLAssociatedObject().length; i++) {
        mustAddLogic = true;
        processAssociation(
            group.getCQLAssociatedObject(i),
            hql,
            parameters,
            associationStack,
            typesProcessingList,
            sourceQueryObject,
            sourceAlias);
        if (i + 1 < group.getCQLAssociatedObject().length) {
          hql.append(' ').append(logic).append(' ');
        }
      }
    }
    if (group.getCQLGroup() != null) {
      if (mustAddLogic) {
        hql.append(' ').append(logic).append(' ');
      }
      for (int i = 0; i < group.getCQLGroup().length; i++) {
        processGroup(
            group.getCQLGroup(i),
            hql,
            parameters,
            associationStack,
            typesProcessingList,
            sourceQueryObject,
            sourceAlias);
        if (i + 1 < group.getCQLGroup().length) {
          hql.append(' ').append(logic).append(' ');
        }
      }
    }

    // close the group
    hql.append(')');
  }
Esempio n. 4
0
  /**
   * Processes CQL associations into HQL
   *
   * @param association The CQL association
   * @param hql The HQL fragment which will be edited
   * @param parameters The positional HQL query parameters
   * @param associationTrace The trace of associations
   * @param sourceClassName The class name of the type to which this association belongs
   * @throws QueryTranslationException
   */
  private void processAssociation(
      CQLAssociatedObject association,
      StringBuilder hql,
      List<java.lang.Object> parameters,
      Stack<CQLAssociatedObject> associationStack,
      List<CqlDataBucket> typesProcessingList,
      CQLObject sourceQueryObject,
      String sourceAlias)
      throws QueryTranslationException {
    LOG.debug(
        "Processing association "
            + sourceQueryObject.getClassName()
            + " to "
            + association.getClassName());

    // get the association's role name
    String roleName = association.getEndName();
    if (roleName == null) {
      try {
        roleName =
            typesInformationResolver.getRoleName(
                sourceQueryObject.getClassName(), association.getClassName());
      } catch (TypesInformationException ex) {
        throw new QueryTranslationException(ex.getMessage(), ex);
      }
    }
    if (roleName == null) {
      // still null?? no association to the object!
      throw new QueryTranslationException(
          "No role name for an association between "
              + sourceQueryObject.getClassName()
              + " and "
              + association.getClassName()
              + " cound be determined.  Maybe the association doesn't exist?");
    }
    LOG.debug("Role name determined to be " + roleName);

    // determine the alias for this association
    String alias =
        getAssociationAlias(sourceQueryObject.getClassName(), association.getClassName(), roleName);
    LOG.debug("Association alias determined to be " + alias);

    // add this association to the stack
    associationStack.push(association);
    DatatypeFlavor flavor = null;
    try {
      flavor =
          DatatypeFlavor.getFlavorOfClass(Class.forName(stripGeneric(association.getClassName())));
    } catch (ClassNotFoundException ex) {
      throw new QueryTranslationException(
          "Error determining datatype flavor of "
              + association.getClassName()
              + ": "
              + ex.getMessage(),
          ex);
    }
    addTypeProcessingInformation(
        typesProcessingList,
        association.getClassName(),
        flavor == DatatypeFlavor.STANDARD ? alias : roleName);

    if (DatatypeFlavor.STANDARD.equals(flavor)) {
      // flag indicates the query is only verifying the association is populated
      boolean simpleNullCheck = true;
      if (association.getCQLAttribute() != null) {
        simpleNullCheck = false;
        hql.append(sourceAlias).append('.').append(roleName);
        hql.append(".id in (select ").append(alias).append(".id from ");
        hql.append(association.getClassName()).append(" as ").append(alias).append(" where ");
        processAttribute(
            association.getCQLAttribute(),
            hql,
            parameters,
            association,
            alias,
            associationStack,
            typesProcessingList);
        hql.append(") ");
      }
      if (association.getCQLAssociatedObject() != null) {
        simpleNullCheck = false;
        // add clause to select things from this association
        hql.append(sourceAlias).append('.').append(roleName);
        hql.append(".id in (select ").append(alias).append(".id from ");
        hql.append(association.getClassName()).append(" as ").append(alias).append(" where ");
        processAssociation(
            association.getCQLAssociatedObject(),
            hql,
            parameters,
            associationStack,
            typesProcessingList,
            association,
            alias);
        hql.append(") ");
      }
      if (association.getCQLGroup() != null) {
        simpleNullCheck = false;
        hql.append(sourceAlias).append('.').append(roleName);
        hql.append(".id in (select ").append(alias).append(".id from ");
        hql.append(association.getClassName()).append(" as ").append(alias).append(" where ");
        processGroup(
            association.getCQLGroup(),
            hql,
            parameters,
            associationStack,
            typesProcessingList,
            association,
            alias);
        hql.append(") ");
      }
      if (simpleNullCheck) {
        // query is checking for the association to exist and be non-null
        hql.append(sourceAlias).append('.').append(roleName).append(".id is not null ");
      }
    } else {
      // complex datatype association (modeled as an attribute, so saying "Person.AD is not null"
      // doesn't make sense...
      // "Person.AD.NullFlavor = NullFlavor.NI, however, is fine
      // FIXME: have to handle complex types here
      boolean simpleNullCheck = true;
      if (association.getCQLAssociatedObject() != null) {
        simpleNullCheck = false;
        // continue processing
        // TODO: does alias need to be role name?
        processAssociation(
            association.getCQLAssociatedObject(),
            hql,
            parameters,
            associationStack,
            typesProcessingList,
            association,
            alias);
      }
      if (association.getCQLGroup() != null) {
        simpleNullCheck = false;
        // continue processing
        // TODO: does alias need to be role name?
        processGroup(
            association.getCQLGroup(),
            hql,
            parameters,
            associationStack,
            typesProcessingList,
            association,
            alias);
      }
      if (association.getCQLAttribute() != null) {
        simpleNullCheck = false;
        // TODO: does sourceAlias need to be roleName??
        processAttribute(
            association.getCQLAttribute(),
            hql,
            parameters,
            sourceQueryObject,
            sourceAlias,
            associationStack,
            typesProcessingList);
      }
      if (simpleNullCheck) {
        // checking for the type not to be null, but .id doesn't work....
        // depending on the sequence of datatype flavors leading to this point
        // we have to construct the HQL in different ways

        String path = getAssociationNavigationPath(typesProcessingList, 4);
        if (path.startsWith("join ")) {
          // throw away the "where" part of the existing query
          if (hql.toString().endsWith("where ")) {
            removeLastWhereStatement(hql);
          }
        }
        hql.append(path).append(" is not null");
      }
    }

    // pop this association off the stack
    associationStack.pop();
    clipTypeProcessingInformation(typesProcessingList);
    LOG.debug(associationStack.size() + " associations remain on the stack");
  }