/**
   * INTERNAL: Return the results from exeucting the database query. the arguments should be a
   * database row with raw data values. Find the correct child session to broker the query to, and
   * return the result of the session executing the query.
   */
  public Object internalExecuteQuery(DatabaseQuery query, AbstractRecord row)
      throws DatabaseException, QueryException {
    AbstractSession sessionByQuery = getSessionForQuery(query);

    // Note, this disables local profilers.
    return sessionByQuery.internalExecuteQuery(query, row);
  }
 /** INTERNAL: Return the create table statement. */
 public Writer buildCreationWriter(AbstractSession session, Writer writer)
     throws ValidationException {
   try {
     DatabasePlatform platform = session.getPlatform();
     writer.write("CREATE PACKAGE " + getFullName());
     writer.write(" AS");
     writer.write("\n");
     for (Enumeration statementsEnum = getStatements().elements();
         statementsEnum.hasMoreElements(); ) {
       writer.write((String) statementsEnum.nextElement());
       writer.write(platform.getBatchDelimiterString());
       writer.write("\n");
     }
     for (Enumeration proceduresEnum = getProcedures().elements();
         proceduresEnum.hasMoreElements(); ) {
       writer.write("\n");
       String procedureString =
           ((StoredProcedureDefinition) proceduresEnum.nextElement())
               .buildCreationWriter(session, writer)
               .toString();
       writer.write(procedureString.substring(7, procedureString.length()));
       writer.write("\n");
     }
     writer.write(platform.getBatchEndString());
     writer.write("\n" + session.getPlatform().getStoredProcedureTerminationToken());
   } catch (IOException ioException) {
     throw ValidationException.fileError(ioException);
   }
   return writer;
 }
  /**
   * INTERNAL: Return the value of the field from the row or a value holder on the query to obtain
   * the object. Check for batch + aggregation reading.
   */
  public Object valueFromRow(
      AbstractRecord row,
      JoinedAttributeManager joinManager,
      ObjectBuildingQuery query,
      AbstractSession executionSession)
      throws DatabaseException {
    Ref ref = (Ref) row.get(getField());

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

    Struct struct;
    try {
      ((DatabaseAccessor) executionSession.getAccessor()).incrementCallCount(executionSession);
      java.sql.Connection connection =
          ((DatabaseAccessor) executionSession.getAccessor()).getConnection();
      struct =
          (Struct) executionSession.getPlatform().getRefValue(ref, executionSession, connection);
    } catch (java.sql.SQLException exception) {
      throw DatabaseException.sqlException(exception, executionSession, false);
    }
    AbstractRecord targetRow =
        ((ObjectRelationalDataTypeDescriptor) getReferenceDescriptor())
            .buildRowFromStructure(struct);
    ((DatabaseAccessor) executionSession.getAccessor()).decrementCallCount();

    return getReferenceDescriptor().getObjectBuilder().buildObject(query, targetRow, joinManager);
  }
 /**
  * INTERNAL: Return a clone of the attribute.
  *
  * @param buildDirectlyFromRow indicates that we are building the clone directly from a row as
  *     opposed to building the original from the row, putting it in the shared cache, and then
  *     cloning the original.
  */
 public Object cloneAttribute(
     Object attributeValue,
     Object original,
     CacheKey cacheKey,
     Object clone,
     Integer refreshCascade,
     AbstractSession cloningSession,
     boolean buildDirectlyFromRow) {
   // Since valueFromRow was called with the UnitOfWork, attributeValue
   // is already a registered result.
   if (buildDirectlyFromRow) {
     return attributeValue;
   }
   if (!cloningSession.isUnitOfWork()) {
     return mapping.buildContainerClone(attributeValue, cloningSession);
   }
   boolean isExisting =
       !cloningSession.isUnitOfWork()
           || (((UnitOfWorkImpl) cloningSession).isObjectRegistered(clone)
               && (!(((UnitOfWorkImpl) cloningSession).isOriginalNewObject(original))));
   return this.getMapping()
       .buildCloneForPartObject(
           attributeValue,
           original,
           cacheKey,
           clone,
           cloningSession,
           refreshCascade,
           isExisting,
           isExisting); // only assume from shared cache if it is existing
 }
  /** INTERNAL: Get a value from the object and set that in the respective field of the row. */
  @Override
  public Object valueFromObject(Object object, DatabaseField field, AbstractSession session) {
    // First check if the value can be obtained from the value holder's row.
    AbstractRecord referenceRow =
        getIndirectionPolicy().extractReferenceRow(getAttributeValueFromObject(object));
    if (referenceRow != null) {
      Object value = referenceRow.get(field);

      // Must ensure the classification to get a cache hit.
      try {
        value = session.getDatasourcePlatform().convertObject(value, getFieldClassification(field));
      } catch (ConversionException e) {
        throw ConversionException.couldNotBeConverted(this, getDescriptor(), e);
      }

      return value;
    }

    // 2.5.1.6 PWK.  added to support batch reading on variable one to ones
    Object referenceObject = getRealAttributeValueFromObject(object, session);
    String queryKeyName = (String) getSourceToTargetQueryKeyNames().get(field);
    ClassDescriptor objectDescriptor = session.getDescriptor(referenceObject.getClass());
    DatabaseField targetField =
        objectDescriptor.getObjectBuilder().getTargetFieldForQueryKeyName(queryKeyName);

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

    return objectDescriptor
        .getObjectBuilder()
        .extractValueFromObjectForField(referenceObject, targetField, session);
  }
  /**
   * PUBLIC: Return a session broker that behaves as a client session broker. An acquire session
   * broker is done under the covers on each session inside the session broker, and a new broker is
   * returned.
   *
   * <p>NOTE: when finished with the client broker, it should be releases. See
   * releaseClientSessionBroker.
   */
  public SessionBroker acquireClientSessionBroker() {
    log(SessionLog.FINER, SessionLog.CONNECTION, "acquire_client_session_broker");
    SessionBroker clientBroker = copySessionBroker();
    clientBroker.parent = this;
    clientBroker
        .getIdentityMapAccessorInstance()
        .setIdentityMapManager(getIdentityMapAccessorInstance().getIdentityMapManager());
    clientBroker.commitManager = getCommitManager();
    clientBroker.commandManager = getCommandManager();
    clientBroker.externalTransactionController = getExternalTransactionController();
    clientBroker.setServerPlatform(getServerPlatform());
    String sessionName;
    AbstractSession serverSession;
    Iterator names = this.getSessionsByName().keySet().iterator();
    while (names.hasNext()) {
      sessionName = (String) names.next();
      serverSession = getSessionForName(sessionName);
      if (serverSession instanceof org.eclipse.persistence.sessions.server.ServerSession) {
        if (serverSession.getProject().hasIsolatedClasses()) {
          throw ValidationException.isolatedDataNotSupportedInSessionBroker(sessionName);
        }
        clientBroker.internalRegisterSession(
            sessionName,
            ((org.eclipse.persistence.sessions.server.ServerSession) serverSession)
                .acquireClientSession());
      } else {
        throw ValidationException.cannotAcquireClientSessionFromSession();
      }
    }

    clientBroker.initializeSequencing();
    return clientBroker;
  }
  /** INTERNAL: Build a ADT structure from the row data. */
  public Struct buildStructureFromRow(
      AbstractRecord row, AbstractSession session, java.sql.Connection connection)
      throws DatabaseException {
    Struct structure;
    boolean reconnected = false;

    try {
      if (connection == null) {
        ((DatabaseAccessor) session.getAccessor()).incrementCallCount(session);
        reconnected = true;
        connection = ((DatabaseAccessor) session.getAccessor()).getConnection();
      }

      Object[] fields = new Object[getOrderedFields().size()];
      for (int index = 0; index < getOrderedFields().size(); index++) {
        DatabaseField field = (DatabaseField) getOrderedFields().elementAt(index);
        fields[index] = row.get(field);
      }

      structure =
          session.getPlatform().createStruct(getStructureName(), fields, session, connection);
    } catch (java.sql.SQLException exception) {
      throw DatabaseException.sqlException(exception, session, false);
    } finally {
      if (reconnected) {
        ((DatabaseAccessor) session.getAccessor()).decrementCallCount();
      }
    }

    return structure;
  }
  /**
   * INTERNAL: Build and return the appropriate field value for the specified set of nested rows.
   * The database better be expecting an ARRAY. It looks like we can ignore inheritance here....
   */
  public Object buildFieldValueFromNestedRows(
      Vector nestedRows, String structureName, AbstractSession session) throws DatabaseException {
    Object[] fields = new Object[nestedRows.size()];
    java.sql.Connection connection = ((DatabaseAccessor) session.getAccessor()).getConnection();
    boolean reconnected = false;

    try {
      if (connection == null) {
        ((DatabaseAccessor) session.getAccessor()).incrementCallCount(session);
        reconnected = true;
        connection = ((DatabaseAccessor) session.getAccessor()).getConnection();
      }

      int i = 0;
      for (Enumeration stream = nestedRows.elements(); stream.hasMoreElements(); ) {
        AbstractRecord nestedRow = (AbstractRecord) stream.nextElement();
        fields[i++] = this.buildStructureFromRow(nestedRow, session, connection);
      }

      return session.getPlatform().createArray(structureName, fields, session, connection);
    } catch (java.sql.SQLException exception) {
      throw DatabaseException.sqlException(exception, session, false);
    } finally {
      if (reconnected) {
        ((DatabaseAccessor) session.getAccessor()).decrementCallCount();
      }
    }
  }
 protected static boolean verifyField(
     AbstractSession session, DatabaseField field, ClassDescriptor descriptor) {
   boolean ok = true;
   if (field.equals(descriptor.getSequenceNumberField())) {
     ok = false;
     session
         .getIntegrityChecker()
         .handleError(
             DescriptorException.returningPolicyFieldNotSupported(field.getName(), descriptor));
   } else if (descriptor.hasInheritance()
       && field.equals(descriptor.getInheritancePolicy().getClassIndicatorField())) {
     ok = false;
     session
         .getIntegrityChecker()
         .handleError(
             DescriptorException.returningPolicyFieldNotSupported(field.getName(), descriptor));
   } else if (descriptor.usesOptimisticLocking()) {
     OptimisticLockingPolicy optimisticLockingPolicy = descriptor.getOptimisticLockingPolicy();
     if (optimisticLockingPolicy instanceof VersionLockingPolicy) {
       VersionLockingPolicy versionLockingPolicy = (VersionLockingPolicy) optimisticLockingPolicy;
       if (field.equals(versionLockingPolicy.getWriteLockField())) {
         ok = false;
         session
             .getIntegrityChecker()
             .handleError(
                 DescriptorException.returningPolicyFieldNotSupported(
                     field.getName(), descriptor));
       }
     }
   }
   return ok;
 }
  /**
   * INTERNAL: The mapping is initialized with the given session. This mapping is fully initialized
   * after this.
   */
  public void initialize(AbstractSession session) throws DescriptorException {
    // modified so that reference class on composite mappings is no longer mandatory
    String referenceClassName = getReferenceClassName();
    if (this.referenceClass == null && referenceClassName != null) {
      if (!referenceClassName.equals(XMLConstants.UNKNOWN_OR_TRANSIENT_CLASS)) {
        setReferenceClass(
            session
                .getDatasourcePlatform()
                .getConversionManager()
                .convertClassNameToClass(referenceClassName));
      }
    }
    initializeReferenceDescriptorAndField(session);
    ContainerPolicy cp = getContainerPolicy();
    if (cp != null) {
      if (cp.getContainerClass() == null) {
        Class cls =
            session
                .getDatasourcePlatform()
                .getConversionManager()
                .convertClassNameToClass(cp.getContainerClassName());
        cp.setContainerClass(cls);
      }
      if (cp instanceof MapContainerPolicy) {
        initializeMapContainerPolicy(session, (MapContainerPolicy) cp);
      }
    }

    if (null != getContainerAccessor()) {
      getContainerAccessor().initializeAttributes(this.referenceClass);
    }
  }
 /**
  * INTERNAL: This method is used to unwrap the oracle connection wrapped by the application
  * server. TopLink needs this unwrapped connection for certain Oracle Specific support. (ie
  * TIMESTAMPTZ) This is added as a workaround for bug 4565190
  */
 public Connection getConnection(AbstractSession session, Connection connection) {
   if (session.getServerPlatform() != null
       && (session.getLogin()).shouldUseExternalConnectionPooling()) {
     // This is added as a workaround for bug 4460996
     return session.getServerPlatform().unwrapConnection(connection);
   }
   return connection;
 }
  /**
   * PUBLIC: set the integrityChecker. IntegrityChecker holds all the ClassDescriptor Exceptions.
   */
  public void setIntegrityChecker(IntegrityChecker integrityChecker) {
    super.setIntegrityChecker(integrityChecker);

    for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
      AbstractSession session = (AbstractSession) sessionEnum.next();
      session.setIntegrityChecker(integrityChecker);
    }
  }
  /**
   * PUBLIC: Set the profiler for the session. This allows for performance operations to be
   * profiled.
   */
  public void setProfiler(SessionProfiler profiler) {
    super.setProfiler(profiler);

    for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
      AbstractSession session = (AbstractSession) sessionEnum.next();
      session.setProfiler(profiler);
    }
  }
  /**
   * PUBLIC: Set the message log.
   *
   * @see #logMessages()
   */
  public void setLog(Writer log) {
    super.setLog(log);

    for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
      AbstractSession session = (AbstractSession) sessionEnum.next();
      session.setLog(log);
    }
  }
  /**
   * INTERNAL: Return the qualified canonical name of the given qualified class name. This method
   * will check the session for a corresponding class that was processed during deploy. If one is
   * not found, will build the canonical name applying any default package and the default suffix
   * qualifier "_".
   */
  public static String getQualifiedCanonicalName(String qualifiedName, AbstractSession session) {
    String sessionStaticMetamodelClass = session.getStaticMetamodelClass(qualifiedName);

    if (sessionStaticMetamodelClass == null) {
      return getQualifiedCanonicalName(qualifiedName, session.getProperties());
    } else {
      return sessionStaticMetamodelClass;
    }
  }
  /** PUBLIC: Return if this session is a server session broker. */
  public boolean isServerSessionBroker() {
    for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
      AbstractSession session = (AbstractSession) sessionEnum.next();
      if (session.isServerSession()) {
        return true;
      }
    }

    return false;
  }
  /** Set the value on the underlying POJO, unwrapping values as necessary. */
  public void setDeclaredProperty(int propertyIndex, Object value) {
    SDOProperty declaredProperty =
        (SDOProperty) dataObject.getType().getDeclaredProperties().get(propertyIndex);
    if (declaredProperty.getType().isChangeSummaryType()) {
      return;
    }

    Mapping mapping = this.getJAXBMappingForProperty(declaredProperty);

    Object newValue = value;
    Object oldValue = mapping.getAttributeAccessor().getAttributeValueFromObject(entity);

    if (declaredProperty.getType().isDataType()) {
      if (!declaredProperty.isMany()) {
        AbstractSession session =
            ((JAXBContext) jaxbHelperContext.getJAXBContext()).getXMLContext().getSession(entity);
        XMLDirectMapping directMapping = (XMLDirectMapping) mapping;
        if (directMapping.hasConverter()) {
          newValue = directMapping.getConverter().convertDataValueToObjectValue(newValue, session);
        } else {
          CoreField field = mapping.getField();
          newValue =
              session
                  .getDatasourcePlatform()
                  .getConversionManager()
                  .convertObject(
                      newValue,
                      descriptor.getObjectBuilder().getFieldClassification((XMLField) field));
        }
      }
      mapping.setAttributeValueInObject(entity, newValue);
    } else if (declaredProperty.isMany()) {
      // Get a ListWrapper and set it's current elements
      ListWrapper listWrapper = (ListWrapper) getDeclaredProperty(propertyIndex);
      listWrapper.addAll((List) newValue);
    } else {
      // OLD VALUE
      if (mapping.isAbstractCompositeObjectMapping()) {
        XMLCompositeObjectMapping compositeMapping = (XMLCompositeObjectMapping) mapping;
        if (oldValue != null && compositeMapping.getContainerAccessor() != null) {
          compositeMapping.getContainerAccessor().setAttributeValueInObject(oldValue, null);
        }
      }

      // NEW VALUE
      newValue = jaxbHelperContext.unwrap((DataObject) value);
      mapping.getAttributeAccessor().setAttributeValueInObject(entity, newValue);
      if (mapping.isAbstractCompositeObjectMapping()) {
        XMLCompositeObjectMapping compositeMapping = (XMLCompositeObjectMapping) mapping;
        if (value != null && compositeMapping.getContainerAccessor() != null) {
          compositeMapping.getContainerAccessor().setAttributeValueInObject(newValue, entity);
        }
      }
    }
  }
 /**
  * PUBLIC: Release the session. This does nothing by default, but allows for other sessions such
  * as the ClientSession to do something.
  */
 public void release() {
   if (isClientSessionBroker()) {
     log(SessionLog.FINER, SessionLog.CONNECTION, "releasing_client_session_broker");
   }
   AbstractSession session;
   for (Iterator enumtr = getSessionsByName().values().iterator(); enumtr.hasNext(); ) {
     session = (AbstractSession) enumtr.next();
     session.release();
   }
   super.release();
 }
 /** Compare objects. */
 public static void compareObjects(Object obj1, Object obj2, String persistenceUnit) {
   AbstractSession dbs = getDatabaseSession(persistenceUnit);
   if (!dbs.compareObjects(obj1, obj2)) {
     fail(
         "Objects "
             + obj1
             + " and "
             + obj2
             + " are not equal. See log (on finest) for what did not match.");
   }
 }
 /**
  * INTERNAL: This method notifies the accessor that a particular sets of writes has completed.
  * This notification can be used for such thing as flushing the batch mechanism
  */
 public void writesCompleted() {
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     if (!session.isConnected()) {
       throw DatabaseException.databaseAccessorNotConnected();
     }
   }
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     session.writesCompleted();
   }
 }
  // 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;
    }
  }
 /**
  * INTERNAL: Commit the transaction on all child sessions. This assumes that the commit of the
  * transaction will not fail because all of the modification has already taken place and no errors
  * would have occurred.
  */
 protected void basicCommitTransaction() throws DatabaseException {
   // Do one last check it make sure that all sessions are still connected.
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     if (!session.isConnected()) {
       throw DatabaseException.databaseAccessorNotConnected();
     }
   }
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     session.commitTransaction();
   }
 }
  /** Append the string containing the SQL insert string for the given table. */
  protected SQLCall buildCallWithoutReturning(AbstractSession session) {
    SQLCall call = new SQLCall();
    call.returnNothing();

    Writer writer = new CharArrayWriter(200);
    try {
      writer.write("INSERT ");
      if (getHintString() != null) {
        writer.write(getHintString());
        writer.write(" ");
      }
      writer.write("INTO ");
      writer.write(getTable().getQualifiedNameDelimited(session.getPlatform()));
      writer.write(" (");

      Vector fieldsForTable = new Vector();
      for (Enumeration fieldsEnum = getModifyRow().keys(); fieldsEnum.hasMoreElements(); ) {
        DatabaseField field = (DatabaseField) fieldsEnum.nextElement();
        if (field.getTable().equals(getTable()) || (!field.hasTableName())) {
          fieldsForTable.addElement(field);
        }
      }

      if (fieldsForTable.isEmpty()) {
        throw QueryException.objectToInsertIsEmpty(getTable());
      }

      for (int i = 0; i < fieldsForTable.size(); i++) {
        writer.write(
            ((DatabaseField) fieldsForTable.elementAt(i)).getNameDelimited(session.getPlatform()));
        if ((i + 1) < fieldsForTable.size()) {
          writer.write(", ");
        }
      }
      writer.write(") VALUES (");

      for (int i = 0; i < fieldsForTable.size(); i++) {
        DatabaseField field = (DatabaseField) fieldsForTable.elementAt(i);
        call.appendModify(writer, field);
        if ((i + 1) < fieldsForTable.size()) {
          writer.write(", ");
        }
      }
      writer.write(")");

      call.setSQLString(writer.toString());
    } catch (IOException exception) {
      throw ValidationException.fileError(exception);
    }
    return call;
  }
 /**
  * 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();
   }
 }
  /** PUBLIC: Return if all sessions are still connected to the database. */
  public boolean isConnected() {
    if ((getSessionsByName() == null) || (getSessionsByName().isEmpty())) {
      return false;
    }

    for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
      AbstractSession session = (AbstractSession) sessionEnum.next();
      if (!session.isConnected()) {
        return false;
      }
    }

    return true;
  }
 protected void logDebugLocalPreallocation(
     AbstractSession writeSession, String seqName, Vector sequences, Accessor accessor) {
   if (writeSession.shouldLog(SessionLog.FINEST, SessionLog.SEQUENCING)) {
     Object[] args = {
       seqName, new Integer(sequences.size()), sequences.firstElement(), sequences.lastElement()
     };
     writeSession.log(
         SessionLog.FINEST,
         SessionLog.SEQUENCING,
         "sequencing_localPreallocation",
         args,
         accessor);
   }
 }
 /**
  * Return if pessimistic locking/select for update nowait is supported for this test platform.
  * Currently testing supports nowait on Oracle, SQLServer. PostgreSQL also supports NOWAIT, but
  * doesn't support the outer joins used in the tests.
  */
 public static boolean isSelectForUpateNoWaitSupported(String puName) {
   AbstractSession dbSession = getDatabaseSession(puName);
   if (dbSession.isBroker()) {
     for (AbstractSession memberSession :
         ((SessionBroker) dbSession).getSessionsByName().values()) {
       if (!isSelectForUpateSupported(memberSession.getPlatform())) {
         return false;
       }
     }
     return true;
   } else {
     return isSelectForUpateNoWaitSupported(dbSession.getPlatform());
   }
 }
 /** Verifies that the object was deleted from the database correctly. */
 public void verifyDelete(Object writtenObject, String persistenceUnit) {
   AbstractSession dbs = getDatabaseSession(persistenceUnit);
   boolean ok;
   if (dbs.isServerSession()) {
     ok = ((ServerSession) dbs).acquireClientSession().verifyDelete(writtenObject);
   } else if (dbs.isSessionBroker()) {
     ok = ((SessionBroker) dbs).acquireClientSessionBroker().verifyDelete(writtenObject);
   } else {
     ok = dbs.verifyDelete(writtenObject);
   }
   if (!ok) {
     fail("Object not deleted from the database correctly: " + writtenObject);
   }
 }
 /** INTERNAL: Rollback the transaction on all child sessions. */
 protected void basicRollbackTransaction() throws DatabaseException {
   DatabaseException globalException = null;
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     try {
       session.rollbackTransaction();
     } catch (DatabaseException exception) {
       globalException = exception;
     }
   }
   if (globalException != null) {
     throw globalException;
   }
 }
 public void waitUntilUnlocked(long timeToWaitBeforeVerify) throws InterruptedException {
   if (isLocked()) {
     long n = timeToWaitBeforeVerify / 100;
     for (int i = 0; i < n && isLocked(); i++) {
       if (isStateEnabled(UNLOCKED_BY_SOURCE_SESSION)) {
         // source session remote connection has been removed
         if (sourceSession
             .getCommandManager()
             .getTransportManager()
             .getConnectionsToExternalServices()
             .isEmpty()) {
           // the following line unlocks, unless UNLOCKED_BY_SOURCE_SESSION state is disabled
           unlock(UNLOCKED_BY_SOURCE_SESSION);
         }
       }
       if (isLocked()) {
         Thread.sleep(100);
       }
     }
     if (isLocked()) {
       unlock(UNLOCKED_BY_TIMER);
     } else if (state == UNLOCKED_BY_TARGET_LISTENER) {
       Thread.sleep(100);
     }
   }
 }