protected void addUnmappedFieldToMain(DatabaseField field, Info info) {
   for (int operation = INSERT; operation <= UPDATE; operation++) {
     if (info.is(operation)) {
       addFieldToMain(operation, UNMAPPED, field);
       addFieldToMain(operation, ALL, field);
     }
   }
 }
 protected void addMappedFieldToMain(DatabaseField field, Info info) {
   for (int operation = INSERT; operation <= UPDATE; operation++) {
     for (int state = RETURN_ONLY; state <= WRITE_RETURN; state++) {
       if (info.is(operation, state)) {
         addFieldToMain(operation, state, field);
         addFieldToMain(operation, MAPPED, field);
         addFieldToMain(operation, ALL, field);
       }
     }
   }
 }
 boolean equals(Info infoToCompare) {
   if (this == infoToCompare) {
     return true;
   }
   if (!getField().equals(infoToCompare.getField())) {
     return false;
   }
   if ((getField().getType() == null) && (infoToCompare.getField().getType() != null)) {
     return false;
   }
   if ((getField().getType() != null)
       && !getField().getType().equals(infoToCompare.getField().getType())) {
     return false;
   }
   if (isInsert() != infoToCompare.isInsert()) {
     return false;
   }
   if (isInsertModeReturnOnly() != infoToCompare.isInsertModeReturnOnly()) {
     return false;
   }
   if (isUpdate() != infoToCompare.isUpdate()) {
     return false;
   }
   return true;
 }
  /** INTERNAL: */
  public void initialize(AbstractSession session) {
    clearInitialization();
    main = new Collection[NUM_OPERATIONS][MAIN_SIZE];

    // The order of descriptor initialization guarantees initialization of Parent before children.
    // main array is copied from Parent's ReturningPolicy
    if (getDescriptor().isChildDescriptor()) {
      ClassDescriptor parentDescriptor =
          getDescriptor().getInheritancePolicy().getParentDescriptor();
      if (parentDescriptor.hasReturningPolicy()) {
        copyMainFrom(parentDescriptor.getReturningPolicy());
      }
    }

    if (!infos.isEmpty()) {
      Hashtable infoHashtable = removeDuplicateAndValidateInfos(session);
      Hashtable infoHashtableUnmapped = (Hashtable) infoHashtable.clone();
      for (Enumeration fields = getDescriptor().getFields().elements();
          fields.hasMoreElements(); ) {
        DatabaseField field = (DatabaseField) fields.nextElement();
        Info info = (Info) infoHashtableUnmapped.get(field);
        if (info != null) {
          infoHashtableUnmapped.remove(field);
          if (verifyFieldAndMapping(session, field)) {
            if (info.getField().getType() == null) {
              addMappedFieldToMain(field, info);
            } else {
              addMappedFieldToMain(info.getField(), info);
              fieldIsNotFromDescriptor(info.getField());
            }
          }
        }
      }

      if (!infoHashtableUnmapped.isEmpty()) {
        Enumeration fields = infoHashtableUnmapped.keys();
        while (fields.hasMoreElements()) {
          DatabaseField field = (DatabaseField) fields.nextElement();
          Info info = (Info) infoHashtableUnmapped.get(field);
          if (verifyField(session, field, getDescriptor())) {
            if (field.getType() != null) {
              addUnmappedFieldToMain(field, info);
              fieldIsNotFromDescriptor(field);
              session.log(
                  SessionLog.FINEST,
                  SessionLog.QUERY,
                  "added_unmapped_field_to_returning_policy",
                  info.toString(),
                  getDescriptor().getJavaClassName());
            } else {
              if (getDescriptor().isReturnTypeRequiredForReturningPolicy()) {
                session
                    .getIntegrityChecker()
                    .handleError(
                        DescriptorException.returningPolicyUnmappedFieldTypeNotSet(
                            field.getName(), getDescriptor()));
              }
            }
          }
        }
      }
    }

    initializeIsUsedToSetPrimaryKey();
  }
 protected Hashtable removeDuplicateAndValidateInfos(AbstractSession session) {
   Hashtable infoHashtable = new Hashtable();
   for (int i = 0; i < infos.size(); i++) {
     Info info1 = infos.get(i);
     info1 = (Info) info1.clone();
     DatabaseField descField = getDescriptor().buildField(info1.getField());
     if (info1.getField().getType() == null) {
       info1.setField(descField);
     } else {
       // keep the original type if specified
       info1.getField().setName(descField.getName());
       info1
           .getField()
           .setTableName(
               getDescriptor().getDefaultTable().getQualifiedNameDelimited(session.getPlatform()));
     }
     Info info2 = (Info) infoHashtable.get(info1.getField());
     if (info2 == null) {
       infoHashtable.put(info1.getField(), info1);
     } else {
       Info infoMerged = mergeInfos(info1, info2, session, getDescriptor());
       if (infoMerged != null) {
         // substitute info2 with infoMerged
         infoHashtable.put(infoMerged.getField(), infoMerged);
       } else {
         // couldn't merge info1 and info2 due to a conflict.
         // substitute info2 with info1
         infoHashtable.put(info1.getField(), info1);
       }
     }
   }
   return infoHashtable;
 }
  // precondition: info1.field.equals(info2.field);
  static Info mergeInfos(
      Info info1, Info info2, AbstractSession session, ClassDescriptor descriptor) {
    boolean ok = true;

    DatabaseField fieldMerged = info1.getField();

    if (info2.getField().getType() != null) {
      if (info1.getField().getType() == null) {
        fieldMerged = info2.field;
      } else if (!info1.getField().getType().equals(info2.getField().getType())) {
        session
            .getIntegrityChecker()
            .handleError(
                DescriptorException.returningPolicyFieldTypeConflict(
                    info1.getField().getName(),
                    info1.getField().getType().getName(),
                    info2.getField().getType().getName(),
                    descriptor));
        ok = false;
      }
    }

    boolean isInsertMerged = false;
    boolean isInsertModeReturnOnlyMerged = false;
    if (info1.isInsert() && !info2.isInsert()) {
      isInsertMerged = true;
      isInsertModeReturnOnlyMerged = info1.isInsertModeReturnOnly();
    } else if (!info1.isInsert() && info2.isInsert()) {
      isInsertMerged = true;
      isInsertModeReturnOnlyMerged = info2.isInsertModeReturnOnly();
    } else if (info1.isInsert() && info2.isInsert()) {
      isInsertMerged = true;
      isInsertModeReturnOnlyMerged = info1.isInsertModeReturnOnly();
      if (info1.isInsertModeReturnOnly() != info2.isInsertModeReturnOnly()) {
        session
            .getIntegrityChecker()
            .handleError(
                DescriptorException.returningPolicyFieldInsertConflict(
                    info1.getField().getName(), descriptor));
        ok = false;
      }
    }

    if (ok) {
      // merging
      boolean isUpdateMerged = info1.isUpdate() || info2.isUpdate();
      return new Info(fieldMerged, isInsertMerged, isInsertModeReturnOnlyMerged, isUpdateMerged);
    } else {
      // there is a problem - can't merge
      return null;
    }
  }