/**
   * Reset the commit order from the session's descriptors. This uses the constraint dependencies in
   * the descriptor's mappings, to decide which descriptors are dependent on which other
   * descriptors. Multiple computations of the commit order should produce the same ordering. This
   * is done to improve performance on unit of work writes through decreasing the stack size, and
   * acts as a deadlock avoidance mechanism.
   */
  public void initializeCommitOrder() {
    Vector descriptors = Helper.buildVectorFromMapElements(getSession().getDescriptors());

    // Must ensure uniqueness, some descriptor my be register twice for interfaces.
    descriptors = Helper.addAllUniqueToVector(new Vector(descriptors.size()), descriptors);
    Object[] descriptorsArray = new Object[descriptors.size()];
    for (int index = 0; index < descriptors.size(); index++) {
      descriptorsArray[index] = descriptors.elementAt(index);
    }
    Arrays.sort(descriptorsArray, new DescriptorCompare());
    descriptors = new Vector(descriptors.size());
    for (int index = 0; index < descriptorsArray.length; index++) {
      descriptors.addElement(descriptorsArray[index]);
    }

    CommitOrderCalculator calculator = new CommitOrderCalculator(getSession());
    calculator.addNodes(descriptors);
    calculator.calculateMappingDependencies();
    calculator.orderCommits();
    descriptors = calculator.getOrderedDescriptors();

    calculator = new CommitOrderCalculator(getSession());
    calculator.addNodes(descriptors);
    calculator.calculateSpecifiedDependencies();
    calculator.orderCommits();

    setCommitOrder(calculator.getOrderedClasses());
  }
 /** Return any tables that are defined by this expression (and not its base). */
 @Override
 public List<DatabaseTable> getOwnedTables() {
   ClassDescriptor descriptor = getDescriptor();
   List<DatabaseTable> tables = null;
   if (descriptor == null) {
     List additionalTables = getAdditionalTables();
     if (additionalTables == null) {
       return null;
     } else {
       return new ArrayList(additionalTables);
     }
   } else if (descriptor.isAggregateDescriptor()) {
     return null;
   } else if ((descriptor.getHistoryPolicy() != null)
       && (getAsOfClause() != null && getAsOfClause().getValue() != null)) {
     tables = descriptor.getHistoryPolicy().getHistoricalTables();
   } else if (isUsingOuterJoinForMultitableInheritance()) {
     tables = descriptor.getInheritancePolicy().getAllTables();
   } else {
     tables = descriptor.getTables();
   }
   List additionalTables = getAdditionalTables();
   if (additionalTables != null) {
     tables = new Vector(tables);
     Helper.addAllUniqueToList(tables, additionalTables);
     return tables;
   }
   return tables;
 }
  /** INTERNAL: */
  public String toString() {
    StringWriter writer = new StringWriter();
    writer.write(Helper.getShortClassName(getClass()));
    writer.write("(");

    for (int index = 0; index < getFields().size(); index++) {
      writer.write(Helper.cr());
      writer.write("\t");
      writer.write(String.valueOf((getFields().elementAt(index))));
      writer.write(" => ");
      writer.write(String.valueOf((getValues().elementAt(index))));
    }
    writer.write(")");

    return writer.toString();
  }
  /** PUBLIC: Add a type indicator conversion to this mapping. */
  public void addClassIndicator(Class implementer, Object typeIndicator) {
    if (typeIndicator == null) {
      typeIndicator = Helper.getNullWrapper();
    }

    getTypeIndicatorTranslation().put(implementer, typeIndicator);
    getTypeIndicatorTranslation().put(typeIndicator, implementer);
  }
  /** INTERNAL: Return the type for a specified implementor */
  protected Object getTypeForImplementor(Class implementor) {
    Object type = getTypeIndicatorTranslation().get(implementor);
    if (type == Helper.getNullWrapper()) {
      type = null;
    }

    return type;
  }
  /**
   * INTERNAL: Extract the direct values from the specified field value. Return them in a vector.
   * The field value better be an Array.
   */
  public Vector buildDirectValuesFromFieldValue(Object fieldValue) throws DatabaseException {

    if (fieldValue == null) {
      return null;
    }

    return Helper.vectorFromArray((Object[]) fieldValue);
  }
 public String toString() {
   if (isInstantiated()) {
     return "{" + getValue() + "}";
   } else {
     return "{"
         + Helper.getShortClassName(getClass())
         + ": "
         + ToStringLocalization.buildMessage("not_instantiated", (Object[]) null)
         + "}";
   }
 }
  /** INTERNAL: Return the implementor for a specified type */
  protected Object getImplementorForType(Object type, AbstractSession session) {
    if (type == null) {
      return getTypeIndicatorTranslation().get(Helper.getNullWrapper());
    }

    // Must ensure the type is the same, i.e. Integer != BigDecimal.
    try {
      type = session.getDatasourcePlatform().convertObject(type, getTypeField().getType());
    } catch (ConversionException e) {
      throw ConversionException.couldNotBeConverted(this, getDescriptor(), e);
    }

    return getTypeIndicatorTranslation().get(type);
  }
 /**
  * INTERNAL: Build the appropriate field value for the specified set of direct values. The
  * database better be expecting an ARRAY.
  */
 public Object buildFieldValueFromDirectValues(
     Vector directValues, String elementDataTypeName, AbstractSession session)
     throws DatabaseException {
   Object[] fields = Helper.arrayFromVector(directValues);
   try {
     ((DatabaseAccessor) session.getAccessor()).incrementCallCount(session);
     java.sql.Connection connection = ((DatabaseAccessor) session.getAccessor()).getConnection();
     return session.getPlatform().createArray(elementDataTypeName, fields, session, connection);
   } catch (java.sql.SQLException ex) {
     throw DatabaseException.sqlException(ex, session, false);
   } finally {
     ((DatabaseAccessor) session.getAccessor()).decrementCallCount();
   }
 }
  /** INTERNAL: Set the type field classification through searching the indicators hashtable. */
  @Override
  public void preInitialize(AbstractSession session) throws DescriptorException {
    super.preInitialize(session);
    if (getTypeIndicatorTranslation().isEmpty()) {
      return;
    }
    Class type = null;
    for (Iterator typeValuesEnum = getTypeIndicatorTranslation().values().iterator();
        typeValuesEnum.hasNext() && (type == null); ) {
      Object value = typeValuesEnum.next();
      if ((value != Helper.getNullWrapper()) && (!(value instanceof Class))) {
        type = value.getClass();
      }
    }

    getTypeField().setType(type);
  }
 /**
  * INTERNAL: Add indicators by classname. For use by the Mapping Workbench to avoid classpath
  * dependencies
  */
 public void addClassNameIndicator(String className, Object typeIndicator) {
   if (typeIndicator == null) {
     typeIndicator = Helper.getNullWrapper();
   }
   getTypeIndicatorNameTranslation().put(className, typeIndicator);
 }
 /**
  * INTERNAL: Rehash any maps based on fields. This is used to clone descriptors for aggregates,
  * which hammer field names.
  */
 @Override
 public void rehashFieldDependancies(AbstractSession session) {
   setSourceToTargetQueryKeyFields(Helper.rehashMap(getSourceToTargetQueryKeyNames()));
 }
 /** Print the in progress depth. */
 public String toString() {
   Object[] args = {Integer.valueOf(this.commitDepth)};
   return Helper.getShortClassName(getClass())
       + ToStringLocalization.buildMessage("commit_depth", args);
 }