private static final StateDiff stateDiff(Serializable... values) {
   assertTrue(values.length % 2 == 0);
   StateDiff diff = new StateDiff();
   for (int i = 0; i < values.length; i += 2) {
     diff.put((String) values[i], values[i + 1]);
   }
   return diff;
 }
示例#2
0
 /**
  * Makes a diff copy of two {@link State} maps.
  *
  * <p>The returned diff state contains only the key/values that changed. {@code null} values are
  * equivalent to absent values.
  *
  * <p>For values set to null or removed, the value is null.
  *
  * <p>When setting a delta, the old value is checked to know if the delta should be kept or if a
  * full value should be set instead.
  *
  * <p>For sub-documents, a recursive diff is returned.
  *
  * @return a {@link StateDiff} which, when applied to a, gives b.
  */
 public static StateDiff diff(State a, State b) {
   StateDiff diff = new StateDiff();
   for (Entry<String, Serializable> en : a.entrySet()) {
     Serializable va = en.getValue();
     if (va == null) {
       // checked by loop on b
       continue;
     }
     String key = en.getKey();
     Serializable vb = b.get(key);
     if (vb == null) {
       // value must be cleared
       diff.put(key, null);
     } else {
       // compare values
       Serializable elemDiff = diff(va, vb);
       if (elemDiff != NOP) {
         if (elemDiff instanceof Delta) {
           Delta delta = (Delta) elemDiff;
           Serializable deltaBase = delta.getBase();
           if (!Objects.equals(va, deltaBase)) {
             // delta's base is not the old value
             // -> set a new value, don't use a delta update
             elemDiff = delta.getFullValue();
           }
           // else delta's base is the in-database value
           // because base is consistent with old value, assume the delta is already properly
           // computed
         }
         diff.put(key, elemDiff);
       }
     }
   }
   for (Entry<String, Serializable> en : b.entrySet()) {
     String key = en.getKey();
     Serializable va = a.get(key);
     if (va != null) {
       // already checked by loop on a
       continue;
     }
     Serializable vb = en.getValue();
     if (!equalsLoose(null, vb)) {
       // value must be added
       diff.put(key, vb);
     }
   }
   return diff;
 }
示例#3
0
 /**
  * Does a diff of two values.
  *
  * @return a {@link StateDiff}, a {@link ListDiff}, {@link #NOP}, or an actual value (including
  *     {@code null})
  */
 public static Serializable diff(Object a, Object b) {
   if (equalsLoose(a, b)) {
     return NOP;
   }
   if (a instanceof Object[] && b instanceof Object[]) {
     return diff((Object[]) a, (Object[]) b);
   }
   if (a instanceof List && b instanceof List) {
     @SuppressWarnings("unchecked")
     List<Object> la = (List<Object>) a;
     @SuppressWarnings("unchecked")
     List<Object> lb = (List<Object>) b;
     return (Serializable) diff(la, lb);
   }
   if (a instanceof State && b instanceof State) {
     StateDiff diff = diff((State) a, (State) b);
     return diff.isEmpty() ? NOP : diff;
   }
   return (Serializable) b;
 }