/**
   * Create a shallow copy of the DataObject dataObject: Creates a new DataObject copiedDataObject
   * with the same values as the source dataObject for each property where
   * property.getType().isDataType() is true. The value of such a Property property in
   * copiedDataObject is: dataObject.get(property) for single-valued Properties
   * (copiedDataObject.get(property) equals() dataObject.get(property)), or a List where each member
   * is equal to the member at the same index in dataObject for multi-valued Properties
   * copiedDataObject.getList(property).get(i) equals() dataObject.getList(property).get(i) The
   * copied Object is unset for each Property where property.getType().isDataType() is false since
   * they are not copied. Read-only properties are copied. A copied object shares metadata with the
   * source object sourceDO.getType() == copiedDO.getType() If a ChangeSummary is part of the source
   * DataObject the copy has a new, empty ChangeSummary. Logging state is the same as the source
   * ChangeSummary.
   *
   * @param dataObject to be copied
   * @return copy of dataObject
   */
  public DataObject copyShallow(DataObject dataObject) {
    if (null == dataObject) {
      return null;
    }
    SDODataObject copy =
        (SDODataObject)
            getHelperContext()
                .getDataFactory()
                .create(dataObject.getType().getURI(), dataObject.getType().getName());

    List ocListOriginal = ((SDODataObject) dataObject)._getOpenContentProperties();
    for (Iterator anOCIterator = ocListOriginal.iterator(); anOCIterator.hasNext(); ) {
      copy.addOpenContentProperty((Property) anOCIterator.next());
    }

    List ocAttrsListOriginal = ((SDODataObject) dataObject)._getOpenContentPropertiesAttributes();
    for (Iterator anOCAttrIterator = ocAttrsListOriginal.iterator(); anOCAttrIterator.hasNext(); ) {
      copy.addOpenContentProperty((Property) anOCAttrIterator.next());
    }

    List allProperties = copy.getInstanceProperties(); // start iterating all copy's properties
    Iterator iterProperties = allProperties.iterator();
    while (iterProperties.hasNext()) {
      SDOProperty eachProperty = (SDOProperty) iterProperties.next();
      if (dataObject.isSet(eachProperty)) {
        Object o = getValue((SDODataObject) dataObject, eachProperty, null);
        if (eachProperty.getType().isDataType()) {
          if (!eachProperty.getType().isChangeSummaryType()) {
            // we defer sequence updates at this point
            copy.setInternal(eachProperty, o, false); // make copy if current property is datatype
          }
        }
      }
    }

    if (dataObject.getType().isSequenced()) {
      List settings = ((SDOSequence) dataObject.getSequence()).getSettings();
      for (int index = 0, size = dataObject.getSequence().size(); index < size; index++) {
        Setting nextSetting = (Setting) settings.get(index);

        Property prop = dataObject.getSequence().getProperty(index);
        if (prop == null || ((SDOType) prop.getType()).isDataType()) {
          Setting copySetting = nextSetting.copy(copy);
          copy.getSequence().getSettings().add(copySetting);
          copy.getSequence().addValueToSettings(copySetting);
        }
      }
    }

    if ((copy != null)
        && (copy.getChangeSummary() != null)
        && (copy.getType().getChangeSummaryProperty() != null)) {
      if (((SDODataObject) dataObject).getChangeSummary().isLogging()) {
        copy.getChangeSummary().setLogging(true);
      }
    }

    return copy;
  }
  /**
   * INTERNAL: Make a copy of all settings on the original sequence onto the copy sequence while
   * using a cross-reference doMap that relates the original DataObject key to the copy DataObject
   * key. This function is used during deep copy and changeSummary copy.
   *
   * @param origSequence
   * @param copySequence
   * @param doMap
   */
  private void replicateAndRereferenceSequenceCopyPrivate(
      SDOSequence origSequence,
      SDOSequence copySequence,
      DataObject dataObject,
      DataObject copy,
      Map doMap,
      SDOChangeSummary cs) {
    if (cs != null && cs.isDeleted(dataObject)) {
      origSequence = cs.getOldSequence(dataObject);
    }

    SDOProperty seqProperty = null;
    try {
      List settings = origSequence.getSettings();
      for (int index = 0, size = origSequence.size(); index < size; index++) {
        Setting nextSetting = (Setting) settings.get(index);
        seqProperty = origSequence.getProperty(nextSetting);

        if ((null == seqProperty) || seqProperty.getType().isDataType()) {
          Setting copySetting = nextSetting.copy(copy);
          copySequence.getSettings().add(copySetting);
          copySequence.addValueToSettings(copySetting);
        } else {
          Object copySeqValue = null;
          Object origSeqValue = origSequence.getValue(index);

          if (cs != null) {
            Object orig = cs.getReverseDeletedMap().get(origSeqValue);
            if (orig != null) {
              origSeqValue = orig;
            }
          }

          if (origSeqValue instanceof XMLRoot) {
            origSeqValue = ((XMLRoot) origSeqValue).getObject();
          }

          // lookup copy if not null, if null then the copySeqValue will be null in the reduced
          // scope assignment above
          if (null != origSeqValue) {
            copySeqValue = doMap.get(origSeqValue);
          } else {
            // as a secondary verification to the assignment above - make sure the copy is null as
            // well
            copySeqValue =
                null; // this assignment is however redundant in our reduced scope assignment above
          }

          // now we have the new value
          Setting copySetting = nextSetting.copy(copy, copySeqValue);
          copySequence.getSettings().add(copySetting);
          copySequence.addValueToSettings(copySetting);
        }

        /**
         * Move assignment inside the loop to minimize scope and to initialize the variable to null
         * to handle the case where the original is null and no lookup is performed. Do not move the
         * scope of this variable outside the for loop or we will end up with the previous
         * iterations' value set for a complex object that is unset(null). see #6026714
         */
      }
    } catch (ClassCastException cce) { // catch any failure of a DataObject cast above
      throw SDOException.foundSimpleValueForNonDataTypeProperty(seqProperty.getName());
    }
  }