/** Compare the attributes. Return true if they are alike. Ignore the order of the elements. */
  private boolean compareAttributeValuesWithoutOrder(
      Object collection1, Object collection2, AbstractSession session) {
    ContainerPolicy cp = this.getContainerPolicy();

    Vector vector2 = cp.vectorFor(collection2, session); // "clone" it so we can clear out the slots

    for (Object iter1 = cp.iteratorFor(collection1); cp.hasNext(iter1); ) {
      Object element1 = cp.next(iter1, session);

      boolean found = false;
      for (int i = 0; i < vector2.size(); i++) {
        if (this.compareElements(element1, vector2.elementAt(i), session)) {
          found = true;
          vector2.setElementAt(XXX, i); // clear out the matching element
          break; // matching element found - skip the rest of them
        }
      }
      if (!found) {
        return false;
      }
    }

    // look for elements that were not in collection1
    for (Enumeration stream = vector2.elements(); stream.hasMoreElements(); ) {
      if (stream.nextElement() != XXX) {
        return false;
      }
    }
    return true;
  }
  /** INTERNAL: Delete the reference objects. */
  public void preDelete(DeleteObjectQuery query) throws DatabaseException, OptimisticLockException {
    if (isForeignKeyRelationship()) {
      return;
    }

    if (!this.shouldObjectModifyCascadeToParts(query)) {
      return;
    }

    Object objects =
        this.getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession());
    ContainerPolicy cp = this.getContainerPolicy();

    // if privately-owned parts have their privately-owned sub-parts, delete them one by one;
    // else delete everything in one shot
    if (this.mustDeleteReferenceObjectsOneByOne()) {
      for (Object iter = cp.iteratorFor(objects); cp.hasNext(iter); ) {
        DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
        deleteQuery.setIsExecutionClone(true);
        deleteQuery.setObject(cp.next(iter, query.getSession()));
        deleteQuery.setCascadePolicy(query.getCascadePolicy());
        query.getSession().executeQuery(deleteQuery);
      }
      if (!query.getSession().isUnitOfWork()) {
        // This deletes any objects on the database, as the collection in memory may have been
        // changed.
        // This is not required for unit of work, as the update would have already deleted these
        // objects,
        // and the backup copy will include the same objects causing double deletes.
        this.deleteReferenceObjectsLeftOnDatabase(query);
      }
    } else {
      this.deleteAll(query);
    }
  }
  /**
   * 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);
    }
  }
  protected Object instantiate(AbstractSession session) throws DatabaseException {
    Vector rows = mapping.getForeignKeyRows(this.getRow());

    int size = rows.size();
    ContainerPolicy cp = ((ReadAllQuery) this.getQuery()).getContainerPolicy();
    Object returnValue = cp.containerInstance(size);

    for (int i = 0; i < size; i++) {
      AbstractRecord nextRow = (AbstractRecord) rows.get(i);
      Object results = session.executeQuery(getQuery(), nextRow);

      if (results instanceof Collection) {
        Iterator iter = ((Collection) results).iterator();
        while (iter.hasNext()) {
          cp.addInto(iter.next(), returnValue, session);
        }
      } else if (results instanceof java.util.Map) {
        Iterator iter = ((java.util.Map) results).values().iterator();
        while (iter.hasNext()) {
          cp.addInto(iter.next(), returnValue, session);
        }
      } else {
        cp.addInto(results, returnValue, session);
      }
    }
    return returnValue;
  }
 /**
  * PUBLIC: Configure the query to use an instance of the specified container class to hold the
  * result objects. The key used to index the value in the Map is the value returned by a call to
  * the specified zero-argument method. The method must be implemented by the class (or a
  * superclass) of the value to be inserted into the Map.
  *
  * <p>jdk1.2.x: The container class must implement (directly or indirectly) the Map interface.
  *
  * <p>jdk1.1.x: The container class must be a subclass of Hashtable.
  *
  * <p>The referenceClass must set before calling this method.
  */
 public void useMapClass(Class concreteClass, String methodName) {
   // the reference class has to be specified before coming here
   if (getReferenceClass() == null) {
     throw QueryException.referenceClassMissing(this);
   }
   ContainerPolicy policy = ContainerPolicy.buildPolicyFor(concreteClass);
   policy.setKeyName(methodName, getReferenceClass().getName());
   setContainerPolicy(policy);
 }
  /**
   * This method will make sure that all the records privately owned by this mapping are actually
   * removed. If such records are found then those are all read and removed one by one along with
   * their privately owned parts.
   */
  protected void deleteReferenceObjectsLeftOnDatabase(DeleteObjectQuery query)
      throws DatabaseException, OptimisticLockException {
    Object objects = this.readPrivateOwnedForObject(query);

    // delete all these objects one by one
    ContainerPolicy cp = this.getContainerPolicy();
    for (Object iter = cp.iteratorFor(objects); cp.hasNext(iter); ) {
      query.getSession().deleteObject(cp.next(iter, query.getSession()));
    }
  }
  /** INTERNAL: Insert privately owned parts */
  public void preInsert(WriteObjectQuery query) throws DatabaseException, OptimisticLockException {
    if (!this.isForeignKeyRelationship()) {
      return;
    }

    if (!this.shouldObjectModifyCascadeToParts(query)) {
      return;
    }

    // only cascade dependents in UOW
    if (query.shouldCascadeOnlyDependentParts()) {
      return;
    }

    Object objects =
        this.getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession());

    // insert each object one by one
    ContainerPolicy cp = this.getContainerPolicy();
    for (Object iter = cp.iteratorFor(objects); cp.hasNext(iter); ) {
      Object object = cp.next(iter, query.getSession());
      if (this.isPrivateOwned()) {
        // no need to set changeset here as insert is just a copy of the object anyway
        InsertObjectQuery insertQuery = new InsertObjectQuery();
        insertQuery.setIsExecutionClone(true);
        insertQuery.setObject(object);
        insertQuery.setCascadePolicy(query.getCascadePolicy());
        query.getSession().executeQuery(insertQuery);
      } else {
        // This will happen in a unit of work or cascaded query.
        // This is done only for persistence by reachability and is not required if the targets are
        // in the queue anyway
        // Avoid cycles by checking commit manager, this is allowed because there is no dependency.
        if (!query.getSession().getCommitManager().isCommitInPreModify(object)) {
          WriteObjectQuery writeQuery = new WriteObjectQuery();
          writeQuery.setIsExecutionClone(true);
          if (query.getSession().isUnitOfWork()) {
            UnitOfWorkChangeSet uowChangeSet =
                (UnitOfWorkChangeSet)
                    ((UnitOfWorkImpl) query.getSession()).getUnitOfWorkChangeSet();
            if (uowChangeSet != null) {
              writeQuery.setObjectChangeSet(
                  (ObjectChangeSet) uowChangeSet.getObjectChangeSetForClone(object));
            }
          }
          writeQuery.setObject(object);
          writeQuery.setCascadePolicy(query.getCascadePolicy());
          query.getSession().executeQuery(writeQuery);
        }
      }
    }
  }
  /** INTERNAL: Used to verify whether the specified object is deleted or not. */
  public boolean verifyDelete(Object object, AbstractSession session) throws DatabaseException {
    if (this.isPrivateOwned()) {
      Object objects = this.getRealCollectionAttributeValueFromObject(object, session);

      ContainerPolicy containerPolicy = getContainerPolicy();
      for (Object iter = containerPolicy.iteratorFor(objects); containerPolicy.hasNext(iter); ) {
        if (!session.verifyDelete(containerPolicy.next(iter, session))) {
          return false;
        }
      }
    }
    return true;
  }
  /**
   * Build and return the change record that results from comparing the two collection attributes.
   * The order of the elements is significant.
   */
  private ChangeRecord compareAttributeValuesForChangeWithOrder(
      Object cloneCollection,
      Object backupCollection,
      ObjectChangeSet owner,
      AbstractSession session) {
    ContainerPolicy cp = this.getContainerPolicy();

    Vector cloneVector =
        cp.vectorFor(
            cloneCollection,
            session); // convert it to a Vector so we can preserve the order and use indexes
    Vector backupVector =
        cp.vectorFor(backupCollection, session); // "clone" it so we can clear out the slots

    EISOrderedCollectionChangeRecord changeRecord =
        new EISOrderedCollectionChangeRecord(
            owner, this.getAttributeName(), this.getDatabaseMapping());

    for (int i = 0; i < cloneVector.size(); i++) {
      Object cloneElement = cloneVector.elementAt(i);
      boolean found = false;
      for (int j = 0; j < backupVector.size(); j++) {
        if (this.compareElementsForChange(cloneElement, backupVector.elementAt(j), session)) {
          // the clone element was found in the backup collection
          found = true;
          backupVector.setElementAt(XXX, j); // clear out the matching backup element

          changeRecord.addMovedChangeSet(this.buildChangeSet(cloneElement, owner, session), j, i);
          break; // matching backup element found - skip the rest of them
        }
      }
      if (!found) {
        // the clone element was not found, so it must have been added
        changeRecord.addAddedChangeSet(this.buildChangeSet(cloneElement, owner, session), i);
      }
    }

    for (int i = 0; i < backupVector.size(); i++) {
      Object backupElement = backupVector.elementAt(i);
      if (backupElement != XXX) {
        // the backup element was not in the clone collection, so it must have been removed
        changeRecord.addRemovedChangeSet(this.buildChangeSet(backupElement, owner, session), i);
      }
    }

    if (changeRecord.hasChanges()) {
      return changeRecord;
    } else {
      return null;
    }
  }
  /** INTERNAL: */
  @Override
  public void writeFromObjectIntoRow(
      Object object, AbstractRecord row, AbstractSession session, WriteType writeType)
      throws DescriptorException {
    if (this.isReadOnly()) {
      return;
    }

    Object attributeValue = this.getAttributeValueFromObject(object);
    if (attributeValue == null) {
      row.put(this.getField(), null);
      return;
    }

    ContainerPolicy cp = this.getContainerPolicy();

    Vector nestedRows = new Vector(cp.sizeFor(attributeValue));
    Object iter = cp.iteratorFor(attributeValue);
    if (null != iter) {
      while (cp.hasNext(iter)) {
        Object element = cp.next(iter, session);
        // convert the value - if necessary
        element =
            convertObjectValueToDataValue(element, session, ((XMLRecord) row).getMarshaller());
        if (element == null) {
          XMLNullRepresentationType nullRepresentation =
              getNullPolicy().getMarshalNullRepresentation();
          if (nullRepresentation == XMLNullRepresentationType.XSI_NIL) {
            nestedRows.add(XMLRecord.NIL);
          } else if (nullRepresentation == XMLNullRepresentationType.EMPTY_NODE) {
            Node emptyNode =
                XPathEngine.getInstance()
                    .createUnownedElement(((XMLRecord) row).getDOM(), (XMLField) field);
            DOMRecord nestedRow = new DOMRecord(emptyNode);
            nestedRows.add(nestedRow);
          }
        } else {
          nestedRows.addElement(buildCompositeRow(element, session, row, writeType));
        }
      }
    }

    Object fieldValue = null;
    if (!nestedRows.isEmpty()) {
      fieldValue =
          this.getDescriptor()
              .buildFieldValueFromNestedRows(nestedRows, getStructureName(), session);
    }
    row.put(this.getField(), fieldValue);
  }
  /**
   * Compare the attributes. Return true if they are alike. The order of the elements is
   * significant.
   */
  private boolean compareAttributeValuesWithOrder(
      Object collection1, Object collection2, AbstractSession session) {
    ContainerPolicy cp = this.getContainerPolicy();

    Object iter1 = cp.iteratorFor(collection1);
    Object iter2 = cp.iteratorFor(collection2);

    while (cp.hasNext(iter1)) {
      if (!this.compareElements(cp.next(iter1, session), cp.next(iter2, session), session)) {
        return false;
      }
    }
    return true;
  }
 /**
  * INTERNAL: The mapping is initialized with the given session. This mapping is fully initialized
  * after this.
  */
 public void initialize(AbstractSession session) throws DescriptorException {
   super.initialize(session);
   ContainerPolicy cp = getContainerPolicy();
   if (cp != null) {
     if (cp.getContainerClass() == null) {
       Class cls =
           session
               .getDatasourcePlatform()
               .getConversionManager()
               .convertClassNameToClass(cp.getContainerClassName());
       cp.setContainerClass(cls);
     }
   }
 }
 /**
  * INTERNAL: Extract the primary key values from the row, then create an
  * org.eclipse.persistence.internal.oxm.Reference instance and stored it on the session's
  * org.eclipse.persistence.internal.oxm.ReferenceResolver.
  */
 public Object readFromRowIntoObject(
     AbstractRecord databaseRow,
     JoinedAttributeManager joinManager,
     Object targetObject,
     ObjectBuildingQuery sourceQuery,
     AbstractSession executionSession)
     throws DatabaseException {
   ClassDescriptor descriptor = sourceQuery.getSession().getClassDescriptor(getReferenceClass());
   ContainerPolicy cp = this.getContainerPolicy();
   Vector pkFieldNames = referenceDescriptor.getPrimaryKeyFieldNames();
   Vector primaryKeyValues = new Vector();
   primaryKeyValues.setSize(pkFieldNames.size());
   HashMap primaryKeyMap = new HashMap();
   // for each source xmlField, get the value from the row and store
   for (Iterator fieldIt = getFields().iterator(); fieldIt.hasNext(); ) {
     XMLField fld = (XMLField) fieldIt.next();
     XMLField tgtFld = (XMLField) getSourceToTargetKeyFieldAssociations().get(fld);
     Object fieldValue = databaseRow.getValues(fld);
     if ((fieldValue == null)
         || (fieldValue instanceof String)
         || !(fieldValue instanceof Vector)) {
       return cp.containerInstance();
     }
     // fix for bug# 5687430
     // need to get the actual type of the target (i.e. int, String, etc.)
     // and use the converted value when checking the cache.
     XMLConversionManager xmlConversionManager =
         (XMLConversionManager) executionSession.getDatasourcePlatform().getConversionManager();
     Vector newValues = new Vector();
     for (Iterator valIt = ((Vector) fieldValue).iterator(); valIt.hasNext(); ) {
       for (StringTokenizer stok = new StringTokenizer((String) valIt.next());
           stok.hasMoreTokens(); ) {
         Object value =
             xmlConversionManager.convertObject(
                 stok.nextToken(), descriptor.getTypedField(tgtFld).getType());
         if (value != null) {
           newValues.add(value);
         }
       }
     }
     primaryKeyMap.put(tgtFld.getXPath(), newValues);
   }
   // store the Reference instance on the resolver for use during mapping resolution phase
   ReferenceResolver resolver = ReferenceResolver.getInstance(sourceQuery.getSession());
   if (resolver != null) {
     resolver.addReference(new Reference(this, targetObject, referenceClass, primaryKeyMap));
   }
   return null;
 }
  /**
   * Merge changes from the source to the target object. Make the necessary removals and adds and
   * map key modifications.
   */
  private void mergeChangesIntoObjectWithoutOrder(
      Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager) {
    EISCollectionChangeRecord sdkChangeRecord = (EISCollectionChangeRecord) changeRecord;
    ContainerPolicy cp = this.getContainerPolicy();
    AbstractSession session = mergeManager.getSession();

    Object targetCollection = null;
    if (sdkChangeRecord.getOwner().isNew()) {
      targetCollection = cp.containerInstance(sdkChangeRecord.getAdds().size());
    } else {
      targetCollection = this.getRealCollectionAttributeValueFromObject(target, session);
    }

    Vector removes = sdkChangeRecord.getRemoves();
    Vector adds = sdkChangeRecord.getAdds();
    Vector changedMapKeys = sdkChangeRecord.getChangedMapKeys();

    synchronized (targetCollection) {
      for (Enumeration stream = removes.elements(); stream.hasMoreElements(); ) {
        Object removeElement =
            this.buildRemovedElementFromChangeSet(stream.nextElement(), mergeManager);

        Object targetElement = null;
        for (Object iter = cp.iteratorFor(targetCollection); cp.hasNext(iter); ) {
          targetElement = cp.next(iter, session);
          if (this.compareElements(targetElement, removeElement, session)) {
            break; // matching element found - skip the rest of them
          }
        }
        if (targetElement != null) {
          // a matching element was found, remove it
          cp.removeFrom(targetElement, targetCollection, session);
        }
      }

      for (Enumeration stream = adds.elements(); stream.hasMoreElements(); ) {
        Object addElement = this.buildAddedElementFromChangeSet(stream.nextElement(), mergeManager);
        cp.addInto(addElement, targetCollection, session);
      }

      for (Enumeration stream = changedMapKeys.elements(); stream.hasMoreElements(); ) {
        Object changedMapKeyElement =
            this.buildAddedElementFromChangeSet(stream.nextElement(), mergeManager);
        Object originalElement =
            ((UnitOfWorkImpl) session).getOriginalVersionOfObject(changedMapKeyElement);
        cp.removeFrom(originalElement, targetCollection, session);
        cp.addInto(changedMapKeyElement, targetCollection, session);
      }
    }

    // reset the attribute to allow for set method to re-morph changes if the collection is not
    // being stored directly
    this.setRealAttributeValueInObject(target, targetCollection);
  }
  /**
   * Build and return the change record that results from comparing the two collection attributes.
   * Ignore the order of the elements.
   */
  private ChangeRecord compareAttributeValuesForChangeWithoutOrder(
      Object cloneCollection,
      Object backupCollection,
      ObjectChangeSet owner,
      AbstractSession session) {
    ContainerPolicy cp = this.getContainerPolicy();

    Vector backupVector =
        cp.vectorFor(backupCollection, session); // "clone" it so we can clear out the slots

    EISCollectionChangeRecord changeRecord =
        new EISCollectionChangeRecord(owner, this.getAttributeName(), this.getDatabaseMapping());
    for (Object cloneIter = cp.iteratorFor(cloneCollection); cp.hasNext(cloneIter); ) {
      Object cloneElement = cp.next(cloneIter, session);

      boolean found = false;
      for (int i = 0; i < backupVector.size(); i++) {
        if (this.compareElementsForChange(cloneElement, backupVector.elementAt(i), session)) {
          // the clone element was found in the backup collection
          found = true;
          backupVector.setElementAt(XXX, i); // clear out the matching backup element
          if (this.mapKeyHasChanged(cloneElement, session)) {
            changeRecord.addChangedMapKeyChangeSet(
                this.buildChangeSet(cloneElement, owner, session));
          }
          break; // matching backup element found - skip the rest of them
        }
      }
      if (!found) {
        // the clone element was not found, so it must have been added
        changeRecord.addAddedChangeSet(this.buildChangeSet(cloneElement, owner, session));
      }
    }

    for (int i = 0; i < backupVector.size(); i++) {
      Object backupElement = backupVector.elementAt(i);
      if (backupElement != XXX) {
        // the backup element was not in the clone collection, so it must have been removed
        changeRecord.addRemovedChangeSet(this.buildChangeSet(backupElement, owner, session));
      }
    }

    if (changeRecord.hasChanges()) {
      return changeRecord;
    } else {
      return null;
    }
  }
  public void addEmployeeDescriptor(boolean methodAccess) {
    XMLDescriptor descriptor = new XMLDescriptor();
    descriptor.setJavaClass(Employee.class);
    descriptor.setDefaultRootElement("employee");

    XMLDirectMapping idMapping = new XMLDirectMapping();
    idMapping.setAttributeName("id");
    idMapping.setXPath("@id");
    descriptor.addMapping(idMapping);

    XMLDirectMapping firstNameMapping = new XMLDirectMapping();
    firstNameMapping.setAttributeName("firstName");
    firstNameMapping.setXPath("first-name/text()");
    descriptor.addMapping(firstNameMapping);

    XMLDirectMapping lastNameMapping = new XMLDirectMapping();
    lastNameMapping.setAttributeName("lastName");
    lastNameMapping.setXPath("last-name/text()");
    descriptor.addMapping(lastNameMapping);

    XMLCompositeObjectMapping addressMapping = new XMLCompositeObjectMapping();
    addressMapping.setAttributeName("address");
    addressMapping.setReferenceClass(Address.class);
    addressMapping.setXPath("address");
    descriptor.addMapping(addressMapping);

    XMLCompositeCollectionMapping phoneMapping = new XMLCompositeCollectionMapping();
    phoneMapping.setAttributeName("phoneNumbers");
    phoneMapping.setReferenceClass(PhoneNumber.class);
    phoneMapping.setXPath("phone-numbers/number");
    phoneMapping.setContainerPolicy(ContainerPolicy.buildPolicyFor(ArrayList.class));
    descriptor.addMapping(phoneMapping);
    this.addDescriptor(descriptor);
  }
  /**
   * INTERNAL: Select all objects for an interface descriptor. This is accomplished by selecting for
   * all of the concrete classes and then merging the objects.
   *
   * @return Vector containing all objects.
   * @exception DatabaseException - an error has occurred on the database.
   */
  public Object selectAllObjectsUsingMultipleTableSubclassRead(ReadAllQuery query)
      throws DatabaseException {
    org.eclipse.persistence.internal.queries.ContainerPolicy containerPolicy =
        query.getContainerPolicy();
    Object objects = containerPolicy.containerInstance(1);

    for (Enumeration childDescriptors = getChildDescriptors().elements();
        childDescriptors.hasMoreElements(); ) {
      ClassDescriptor descriptor = (ClassDescriptor) childDescriptors.nextElement();
      objects =
          containerPolicy.concatenateContainers(
              objects, descriptor.getInterfacePolicy().selectAllObjects(query));
    }

    return objects;
  }
  /**
   * For isMany=false properties set the value to null. For isMany=true set the value to an empty
   * container of the appropriate type.
   */
  public void unsetDeclaredProperty(int propertyIndex) {
    SDOProperty declaredProperty =
        (SDOProperty) dataObject.getType().getDeclaredProperties().get(propertyIndex);
    Mapping mapping = this.getJAXBMappingForProperty(declaredProperty);
    if (declaredProperty.isMany()) {
      ContainerMapping containerMapping = (ContainerMapping) mapping;
      ContainerPolicy containerPolicy = containerMapping.getContainerPolicy();

      // OLD VALUE
      if (mapping.isAbstractCompositeCollectionMapping()) {
        XMLCompositeCollectionMapping compositeMapping = (XMLCompositeCollectionMapping) mapping;
        if (compositeMapping.getContainerAccessor() != null) {

          Object oldContainer = mapping.getAttributeValueFromObject(entity);
          if (oldContainer != null) {
            AbstractSession session =
                ((JAXBContext) jaxbHelperContext.getJAXBContext())
                    .getXMLContext()
                    .getSession(entity);
            Object iterator = containerPolicy.iteratorFor(oldContainer);
            while (containerPolicy.hasNext(iterator)) {
              Object oldValue = containerPolicy.next(iterator, session);
              compositeMapping.getContainerAccessor().setAttributeValueInObject(oldValue, null);
            }
          }
        }
      }

      // NEW VALUE
      Object container = containerPolicy.containerInstance();
      mapping.getAttributeAccessor().setAttributeValueInObject(entity, container);
    } else {
      // OLD VALUE
      Object oldValue = mapping.getAttributeAccessor().getAttributeValueFromObject(entity);
      if (mapping.isAbstractCompositeObjectMapping()) {
        XMLCompositeObjectMapping compositeMapping = (XMLCompositeObjectMapping) mapping;
        if (compositeMapping.getContainerAccessor() != null) {
          if (oldValue != null) {
            compositeMapping.getContainerAccessor().setAttributeValueInObject(oldValue, null);
          }
        }
      }

      // NEW VALUE
      mapping.getAttributeAccessor().setAttributeValueInObject(entity, null);
    }
  }
  public boolean marshal(
      XPathFragment xPathFragment,
      MarshalRecord marshalRecord,
      Object object,
      AbstractSession session,
      NamespaceResolver namespaceResolver) {
    if (xmlBinaryDataCollectionMapping.isReadOnly()) {
      return false;
    }
    Object collection =
        xmlBinaryDataCollectionMapping.getAttributeAccessor().getAttributeValueFromObject(object);
    if (null == collection) {
      return false;
    }
    String xopPrefix = null;
    // If the field's resolver is non-null and has an entry for XOP,
    // use it - otherwise, create a new resolver, set the XOP entry,
    // on it, and use it instead.
    // We do this to avoid setting the XOP namespace declaration on
    // a given field or descriptor's resolver, as it is only required
    // on the current element
    if (namespaceResolver != null) {
      xopPrefix = namespaceResolver.resolveNamespaceURI(XMLConstants.XOP_URL);
    }
    if (xopPrefix == null || namespaceResolver == null) {
      xopPrefix = XMLConstants.XOP_PREFIX;
      marshalRecord.getNamespaceResolver().put(xopPrefix, XMLConstants.XOP_URL);
    }

    ContainerPolicy cp = getContainerPolicy();
    Object iterator = cp.iteratorFor(collection);
    while (cp.hasNext(iterator)) {
      Object objectValue = cp.next(iterator, session);
      marshalSingleValue(
          xPathFragment,
          marshalRecord,
          object,
          objectValue,
          session,
          namespaceResolver,
          ObjectMarshalContext.getInstance());
    }

    marshalRecord.getNamespaceResolver().removeNamespace(XMLConstants.XOP_PREFIX);
    return true;
  }
  /**
   * Merge changes from the source to the target object. Simply replace the entire target
   * collection.
   */
  private void mergeChangesIntoObjectWithOrder(
      Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager) {
    ContainerPolicy cp = this.getContainerPolicy();
    AbstractSession session = mergeManager.getSession();

    Vector changes = ((EISOrderedCollectionChangeRecord) changeRecord).getNewCollection();
    Object targetCollection = cp.containerInstance(changes.size());

    for (Enumeration stream = changes.elements(); stream.hasMoreElements(); ) {
      Object targetElement =
          this.buildAddedElementFromChangeSet(stream.nextElement(), mergeManager);
      cp.addInto(targetElement, targetCollection, session);
    }

    // reset the attribute to allow for set method to re-morph changes if the collection is not
    // being stored directly
    this.setRealAttributeValueInObject(target, targetCollection);
  }
  /**
   * INTERNAL: Get the appropriate attribute value from the object and put it in the appropriate
   * field of the database row. Loop through the reference objects and extract the primary keys and
   * put them in the vector of "nested" rows.
   */
  public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session) {
    if (!isForeignKeyRelationship) {
      return;
    }

    if (((getSourceForeignKeysToTargetKeys()) == null)
        || (getSourceForeignKeysToTargetKeys().size() == 0)) {
      return;
    }

    if (this.isReadOnly()) {
      return;
    }

    AbstractRecord referenceRow =
        this.getIndirectionPolicy().extractReferenceRow(this.getAttributeValueFromObject(object));
    if (referenceRow != null) {
      // the reference objects have not been instantiated - use the value from the original row
      if (getForeignKeyGroupingElement() != null) {
        row.put(
            this.getForeignKeyGroupingElement(),
            referenceRow.getValues(this.getForeignKeyGroupingElement()));
      } else if (getSourceForeignKeyFields().size() > 0) {
        DatabaseField foreignKeyField = (DatabaseField) getSourceForeignKeyFields().get(0);
        row.put(foreignKeyField, referenceRow.getValues(foreignKeyField));
      }
      return;
    }

    ContainerPolicy cp = this.getContainerPolicy();

    // extract the keys from the objects
    Object attributeValue = this.getRealCollectionAttributeValueFromObject(object, session);
    Vector nestedRows = new Vector(cp.sizeFor(attributeValue));

    if (getForeignKeyGroupingElement() != null) {
      for (Object iter = cp.iteratorFor(attributeValue); cp.hasNext(iter); ) {
        XMLRecord nestedRow =
            this.extractKeyRowFromReferenceObject(cp.next(iter, session), session, (XMLRecord) row);
        nestedRows.addElement(nestedRow);
      }
      row.add(this.getForeignKeyGroupingElement(), nestedRows);
    } else {
      DatabaseField singleField = (DatabaseField) getSourceForeignKeyFields().get(0);
      DatabaseField pkField = (DatabaseField) getSourceForeignKeysToTargetKeys().get(singleField);
      for (Object iter = cp.iteratorFor(attributeValue); cp.hasNext(iter); ) {
        Object singleValue =
            getReferenceDescriptor()
                .getObjectBuilder()
                .extractValueFromObjectForField(cp.next(iter, session), pkField, session);
        row.add(singleField, singleValue);
      }
    }
  }
  /**
   * Compare the attributes. Return true if they are alike. Assume the passed-in attributes are
   * non-null.
   */
  private boolean compareAttributeValues(
      Object collection1, Object collection2, AbstractSession session) {
    ContainerPolicy cp = this.getContainerPolicy();

    if (cp.sizeFor(collection1) != cp.sizeFor(collection2)) {
      return false;
    }

    // if they are both empty, go no further...
    if (cp.sizeFor(collection1) == 0) {
      return true;
    }

    if (cp.hasOrder()) {
      return this.compareAttributeValuesWithOrder(collection1, collection2, session);
    } else {
      return this.compareAttributeValuesWithoutOrder(collection1, collection2, session);
    }
  }
  /**
   * INTERNAL: Build and return the change record that results from comparing the two collection
   * attributes.
   */
  public ChangeRecord compareForChange(
      Object clone, Object backup, ObjectChangeSet owner, AbstractSession session) {
    ContainerPolicy cp = this.getContainerPolicy();
    Object cloneCollection = this.getRealCollectionAttributeValueFromObject(clone, session);

    Object backupCollection = null;
    if (owner.isNew()) {
      backupCollection = cp.containerInstance(1);
    } else {
      backupCollection = this.getRealCollectionAttributeValueFromObject(backup, session);
    }

    if (cp.hasOrder()) {
      return this.compareAttributeValuesForChangeWithOrder(
          cloneCollection, backupCollection, owner, session);
    } else {
      return this.compareAttributeValuesForChangeWithoutOrder(
          cloneCollection, backupCollection, owner, session);
    }
  }
 /**
  * INTERNAL: The results are *not* in a cursor, build the collection. Cache the results in
  * temporaryCachedQueryResults.
  */
 protected Object executeNonCursor() throws DatabaseException {
   Vector rows = getQueryMechanism().executeSelect();
   Object results = null;
   if (this.resultType == MAP) {
     results = getContainerPolicy().buildContainerFromVector(rows, this.session);
   } else if (this.resultType == VALUE) {
     if (!rows.isEmpty()) {
       AbstractRecord record = (AbstractRecord) rows.get(0);
       // Use get with field for XML records.
       results = record.get(record.getFields().get(0));
       if (getValueConverter() != null) {
         results = getValueConverter().convertDataValueToObjectValue(results, this.session);
       }
     }
   } else {
     int size = rows.size();
     ContainerPolicy containerPolicy = getContainerPolicy();
     results = containerPolicy.containerInstance(size);
     if (containerPolicy.shouldAddAll()) {
       if (size > 0) {
         List values = new ArrayList(size);
         for (int index = 0; index < size; index++) {
           AbstractRecord row = (AbstractRecord) rows.get(index);
           Object value = buildObject(row);
           values.add(value);
         }
         containerPolicy.addAll(values, results, this.session, rows, this);
       }
     } else {
       for (int index = 0; index < size; index++) {
         AbstractRecord row = (AbstractRecord) rows.get(index);
         Object value = buildObject(row);
         containerPolicy.addInto(value, results, this.session, row, this);
       }
     }
   }
   // Bug 6135563 - cache DataReadQuery results verbatim, as ObjectBuilder is not invoked
   cacheResult(results);
   return results;
 }
Esempio n. 25
0
  /**
   * INTERNAL: Execute the query. Get the rows and build the object from the rows.
   *
   * @exception DatabaseException - an error has occurred on the database
   * @return java.lang.Object collection of objects resulting from execution of query.
   */
  protected Object executeObjectLevelReadQuery() throws DatabaseException {
    Object result = null;

    if (getContainerPolicy().overridesRead()) {
      return getContainerPolicy().execute();
    }

    if (this.descriptor.isDescriptorForInterface()) {
      Object returnValue =
          this.descriptor.getInterfacePolicy().selectAllObjectsUsingMultipleTableSubclassRead(this);
      setExecutionTime(System.currentTimeMillis());
      return returnValue;
    }

    List rows = getQueryMechanism().selectAllRows();
    setExecutionTime(System.currentTimeMillis());

    // If using 1-m joins, must set all rows.
    if (hasJoining() && this.joinedAttributeManager.isToManyJoin()) {
      this.joinedAttributeManager.setDataResults(rows, this.session);
    }

    if (this.session.isUnitOfWork()) {
      result =
          registerResultInUnitOfWork(
              rows, (UnitOfWorkImpl) this.session, this.translationRow, true); //
    } else {
      result = getContainerPolicy().containerInstance(rows.size());
      this.descriptor.getObjectBuilder().buildObjectsInto(this, rows, result);
    }

    if (this.shouldIncludeData) {
      ComplexQueryResult complexResult = new ComplexQueryResult();
      complexResult.setResult(result);
      complexResult.setData(rows);
      return complexResult;
    }

    // Add the other (already registered) results and return them.
    if (getDescriptor().hasTablePerClassPolicy()) {
      result =
          containerPolicy.concatenateContainers(
              result,
              getDescriptor()
                  .getTablePerClassPolicy()
                  .selectAllObjectsUsingMultipleTableSubclassRead(this));
    }

    return result;
  }
  /** INTERNAL: Delete the reference objects. */
  @Override
  public void postDelete(DeleteObjectQuery query)
      throws DatabaseException, OptimisticLockException {
    if (!isForeignKeyRelationship()) {
      return;
    }

    if (!this.shouldObjectModifyCascadeToParts(query)) {
      return;
    }
    Object referenceObjects =
        this.getRealCollectionAttributeValueFromObject(query.getObject(), query.getSession());

    // if we have a custom delete all query, use it;
    // otherwise, delete the reference objects one by one
    if (this.hasCustomDeleteAllQuery()) {
      this.deleteAll(query, referenceObjects);
    } else {
      ContainerPolicy cp = this.getContainerPolicy();
      for (Object iter = cp.iteratorFor(referenceObjects); cp.hasNext(iter); ) {
        DeleteObjectQuery deleteQuery = new DeleteObjectQuery();
        deleteQuery.setIsExecutionClone(true);
        deleteQuery.setObject(cp.next(iter, query.getSession()));
        deleteQuery.setCascadePolicy(query.getCascadePolicy());
        query.getSession().executeQuery(deleteQuery);
      }
      if (!query.getSession().isUnitOfWork()) {
        // This deletes any objects on the database, as the collection in memory may have been
        // changed.
        // This is not required for unit of work, as the update would have already deleted these
        // objects,
        // and the backup copy will include the same objects, causing double deletes.
        this.deleteReferenceObjectsLeftOnDatabase(query);
      }
    }
  }
  /** INTERNAL: Write the attribute value from the object to the row. */
  public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session) {
    // for each xmlField on this mapping
    for (Iterator fieldIt = getFields().iterator(); fieldIt.hasNext(); ) {
      XMLField xmlField = (XMLField) fieldIt.next();
      ContainerPolicy cp = getContainerPolicy();
      Object collection = getAttributeAccessor().getAttributeValueFromObject(object);
      if (collection == null) {
        return;
      }

      Object fieldValue;
      Object objectValue;
      String stringValue = "";
      QName schemaType;
      Object iterator = cp.iteratorFor(collection);
      if (usesSingleNode()) {
        while (cp.hasNext(iterator)) {
          objectValue = cp.next(iterator, session);
          fieldValue = buildFieldValue(objectValue, xmlField, session);
          if (fieldValue != null) {
            schemaType = getSchemaType(xmlField, fieldValue, session);
            String newValue = getValueToWrite(schemaType, fieldValue, session);
            if (newValue != null) {
              stringValue += newValue;
              if (cp.hasNext(iterator)) {
                stringValue += SPACE;
              }
            }
          }
        }
        if (!(stringValue.equals(""))) {
          row.put(xmlField, stringValue);
        }
      } else {
        ArrayList keyValues = new ArrayList();
        while (cp.hasNext(iterator)) {
          objectValue = cp.next(iterator, session);
          fieldValue = buildFieldValue(objectValue, xmlField, session);
          if (fieldValue != null) {
            schemaType = getSchemaType(xmlField, fieldValue, session);
            stringValue = getValueToWrite(schemaType, fieldValue, session);
            // row.add(xmlField, stringValue);
            keyValues.add(stringValue);
          }
        }
        row.put(xmlField, keyValues);
      }
    }
  }
  /**
   * INTERNAL: Merge changes from the source to the target object. Simply replace the entire target
   * collection.
   */
  public void mergeIntoObject(
      Object target, boolean isTargetUnInitialized, Object source, MergeManager mergeManager) {
    ContainerPolicy cp = this.getContainerPolicy();
    AbstractSession session = mergeManager.getSession();

    Object sourceCollection = this.getRealCollectionAttributeValueFromObject(source, session);
    Object targetCollection = cp.containerInstance(cp.sizeFor(sourceCollection));

    for (Object iter = cp.iteratorFor(sourceCollection); cp.hasNext(iter); ) {
      Object targetElement = this.buildElementFromElement(cp.next(iter, session), mergeManager);
      cp.addInto(targetElement, targetCollection, session);
    }

    // reset the attribute to allow for set method to re-morph changes if the collection is not
    // being stored directly
    this.setRealAttributeValueInObject(target, targetCollection);
  }
Esempio n. 29
0
 /**
  * INTERNAL: Execute the query. If there are cached results return those. This must override the
  * super to support result caching.
  *
  * @param session - the session in which the receiver will be executed.
  * @return An object or vector, the result of executing the query.
  * @exception DatabaseException - an error has occurred on the database
  */
 public Object execute(AbstractSession session, AbstractRecord row) throws DatabaseException {
   if (shouldCacheQueryResults()) {
     if (getContainerPolicy().overridesRead()) {
       throw QueryException.cannotCacheCursorResultsOnQuery(this);
     }
     if (shouldConformResultsInUnitOfWork()) {
       throw QueryException.cannotConformAndCacheQueryResults(this);
     }
     if (isPrepared()) { // only prepared queries can have cached results.
       Object queryResults = getQueryResults(session, row, true);
       if (queryResults != null) {
         if (QueryMonitor.shouldMonitor()) {
           QueryMonitor.incrementReadAllHits(this);
         }
         // bug6138532 - check for "cached no results" (InvalidObject singleton) in query
         // results, and return an empty container instance as configured
         if (queryResults == InvalidObject.instance) {
           return getContainerPolicy().containerInstance(0);
         }
         Collection results = (Collection) queryResults;
         if (session.isUnitOfWork()) {
           ContainerPolicy policy = getContainerPolicy();
           Object resultCollection = policy.containerInstance(results.size());
           Object iterator = policy.iteratorFor(results);
           while (policy.hasNext(iterator)) {
             Object result =
                 ((UnitOfWorkImpl) session)
                     .registerExistingObject(policy.next(iterator, session), this.descriptor);
             policy.addInto(result, resultCollection, session);
           }
           return resultCollection;
         }
         return results;
       }
     }
   }
   if (QueryMonitor.shouldMonitor()) {
     QueryMonitor.incrementReadAllMisses(this);
   }
   return super.execute(session, row);
 }
  /**
   * INTERNAL: Return the value of the reference attribute or a value holder. Check whether the
   * mapping's attribute should be optimized through batch and joining.
   */
  public Object valueFromRow(
      AbstractRecord row,
      JoinedAttributeManager joinManager,
      ObjectBuildingQuery sourceQuery,
      AbstractSession executionSession)
      throws DatabaseException {
    if (((EISDescriptor) this.getDescriptor()).getDataFormat() == EISDescriptor.XML) {
      ((XMLRecord) row).setSession(executionSession);
    }

    ReadQuery targetQuery = getSelectionQuery();
    if (!isForeignKeyRelationship) {
      // if the source query is cascading then the target query must use the same settings
      if (targetQuery.isObjectLevelReadQuery()
          && (sourceQuery.shouldCascadeAllParts()
              || (sourceQuery.shouldCascadePrivateParts() && isPrivateOwned())
              || (sourceQuery.shouldCascadeByMapping() && this.cascadeRefresh))) {
        targetQuery = (ObjectLevelReadQuery) targetQuery.clone();
        ((ObjectLevelReadQuery) targetQuery)
            .setShouldRefreshIdentityMapResult(sourceQuery.shouldRefreshIdentityMapResult());
        targetQuery.setCascadePolicy(sourceQuery.getCascadePolicy());
        // CR #4365
        targetQuery.setQueryId(sourceQuery.getQueryId());
        // For queries that have turned caching off, such as aggregate collection, leave it off.
        if (targetQuery.shouldMaintainCache()) {
          targetQuery.setShouldMaintainCache(sourceQuery.shouldMaintainCache());
        }
      }

      return getIndirectionPolicy().valueFromQuery(targetQuery, row, sourceQuery.getSession());
    } else {
      if (getIndirectionPolicy().usesIndirection()) {
        EISOneToManyQueryBasedValueHolder valueholder =
            new EISOneToManyQueryBasedValueHolder(this, targetQuery, row, sourceQuery.getSession());
        return valueholder;
      } else {
        Vector subRows = getForeignKeyRows(row);

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

        ContainerPolicy cp = this.getContainerPolicy();
        Object results = cp.containerInstance(subRows.size());

        for (int i = 0; i < subRows.size(); i++) {
          XMLRecord subRow = (XMLRecord) subRows.elementAt(i);
          subRow.setSession(executionSession);
          Object object =
              getIndirectionPolicy().valueFromQuery(targetQuery, subRow, sourceQuery.getSession());
          if (object instanceof Collection) {
            java.util.Iterator iter = ((Collection) object).iterator();
            while (iter.hasNext()) {
              cp.addInto(iter.next(), results, executionSession);
            }
          } else if (object instanceof java.util.Map) {
            java.util.Iterator iter = ((java.util.Map) object).values().iterator();
            while (iter.hasNext()) {
              cp.addInto(iter.next(), results, executionSession);
            }
          } else {
            cp.addInto(object, results, executionSession);
          }
        }
        if (cp.sizeFor(results) == 0) {
          return null;
        }
        return results;
      }
    }
  }