コード例 #1
0
 private int determineLevelsRemovedFromStandardDatatype(List<CqlDataBucket> typesProcessingList) {
   int count = 0;
   for (int i = typesProcessingList.size() - 1; i >= 0; i--) {
     count++;
     if (DatatypeFlavor.STANDARD.equals(typesProcessingList.get(i).datatypeFlavor)) {
       break;
     }
   }
   return count;
 }
コード例 #2
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");
  }