Exemplo n.º 1
0
  /**
   * This DBObjectDeltaRec constructor is used to generate a delta record that records the
   * difference between two objects for the Ganymede journal
   */
  public DBObjectDeltaRec(DBObject oldObj, DBObject newObj) {
    if (oldObj == null || newObj == null) {
      throw new IllegalArgumentException(
          "Got a null object parameter"
              + ((oldObj == null) ? " old " : "")
              + ((newObj == null) ? " new " : ""));
    }

    if (!oldObj.getInvid().equals(newObj.getInvid())) {
      throw new IllegalArgumentException("Old and New object id's don't match");
    }

    /* - */

    this.invid = oldObj.getInvid();

    DBObjectBase objectBase = oldObj.getBase();
    DBField origField, currentField;

    /* -- */

    // algorithm: iterate over base.getFieldsInFieldOrder() to find
    // all fields possibly contained in the object.. for each field,
    // check to see if the value has changed.  if so, create a
    // fieldDeltaRec for it.

    // note that we're counting on objectBase.sortedFields not being
    // changed while we're iterating here.. this is an ok assumption,
    // since only the loader and the schema editor will trigger changes
    // in sortedFields.

    if (debug) {
      System.err.println(
          "Entering deltarec creation for objects "
              + oldObj.getLabel()
              + " and "
              + newObj.getLabel());
    }

    for (DBObjectBaseField fieldDef : objectBase.getFieldsInFieldOrder()) {
      if (debug) {
        System.err.println("Comparing field " + fieldDef.getName());
      }

      origField = (DBField) oldObj.getField(fieldDef.getID());
      currentField = (DBField) newObj.getField(fieldDef.getID());

      if ((origField == null || !origField.isDefined())
          && (currentField == null || !currentField.isDefined())) {
        // no change.. was null/undefined, still is.

        continue;
      }

      if (currentField == null || !currentField.isDefined()) {
        // lost this field

        fieldRecs.addElement(new fieldDeltaRec(fieldDef.getID(), null));

        continue;
      }

      if (origField == null || !origField.isDefined()) {
        // we gained this field

        fieldRecs.addElement(new fieldDeltaRec(fieldDef.getID(), currentField));

        continue;
      }

      if (currentField.equals(origField)) {
        // no changes, we don't need to write this one out.

        continue;
      }

      // at this point, we know we need to write out a change
      // record..  the only question now is whether it is for a
      // scalar or a vector.

      if (!fieldDef.isArray()) {
        // got a scalar.. save this field entire to write out
        // when we emit to the journal

        fieldRecs.addElement(new fieldDeltaRec(fieldDef.getID(), currentField));

        continue;
      }

      // it's a vector.. use the DBField.getVectorDiff() method
      // to generate a vector diff.

      fieldRecs.addElement(currentField.getVectorDiff(origField));
    }
  }
Exemplo n.º 2
0
  /**
   * This method takes an object in its original state, and returns a new copy of the object with
   * the changes embodied in this DBObjectDeltaRec applied to it.
   */
  public DBObject applyDelta(DBObject original) {
    if (!original.getInvid().equals(invid)) {
      throw new IllegalArgumentException("Error, object identity mismatch");
    }

    /* - */

    DBObject copy;
    fieldDeltaRec fieldRec;
    Object value;

    /* -- */

    copy = new DBObject(original, null);

    // now process the fieldDeltaRec's.

    for (int i = 0; i < fieldRecs.size(); i++) {
      fieldRec = (fieldDeltaRec) fieldRecs.elementAt(i);

      // are we clearing this field?

      if (!fieldRec.vector && fieldRec.scalarValue == null) {
        copy.clearField(fieldRec.fieldcode);

        continue;
      }

      // are we doing a replace or add?

      if (!fieldRec.vector) {
        fieldRec.scalarValue.setOwner(copy);

        if (copy.getField(fieldRec.fieldcode) != null) {
          copy.replaceField(fieldRec.scalarValue);
        } else {
          copy.addField(fieldRec.scalarValue);
        }

        continue;
      }

      // ok, we must be doing a vector mod

      // remember that we are intentionally bypassing the DBField's
      // add/remove logic, as we assume that this DBObjectDeltaRec
      // was generated as a result of a properly checked operation.

      // Also, since we know that only string, invid, and IP fields
      // can be vectors, we don't have to worry about the password
      // and permission matrix special-case logic.

      DBField field = copy.retrieveField(fieldRec.fieldcode);

      if (fieldRec.addValues != null) {
        for (int j = 0; j < fieldRec.addValues.size(); j++) {
          value = fieldRec.addValues.elementAt(j);

          if (value instanceof IPwrap) {
            value = ((IPwrap) value).address;
          }

          field.getVectVal().addElement(value);
        }
      }

      if (fieldRec.delValues != null) {
        for (int j = 0; j < fieldRec.delValues.size(); j++) {
          value = fieldRec.delValues.elementAt(j);

          if (value instanceof IPwrap) {
            value = ((IPwrap) value).address;
          }

          field.getVectVal().removeElement(value);
        }
      }
    }

    return copy;
  }