Android Open Source - spring-sync Diff Sync Controller






From Project

Back to project page spring-sync.

License

The source code is released under:

Apache License

If you think the Android project spring-sync listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2014 the original author or authors.
 */* w  ww.  j a  va2 s .c  o  m*/
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.sync.diffsync.web;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.sync.Patch;
import org.springframework.sync.PatchException;
import org.springframework.sync.diffsync.DiffSync;
import org.springframework.sync.diffsync.Equivalency;
import org.springframework.sync.diffsync.IdPropertyEquivalency;
import org.springframework.sync.diffsync.PersistenceCallback;
import org.springframework.sync.diffsync.PersistenceCallbackRegistry;
import org.springframework.sync.diffsync.ShadowStore;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

/**
 * Controller to handle PATCH requests an apply them to resources using {@link DiffSync}.
 * @author Craig Walls
 */
@RestController
public class DiffSyncController {
  
  private ShadowStore shadowStore;

  private PersistenceCallbackRegistry callbackRegistry;
  
  private Equivalency equivalency = new IdPropertyEquivalency();

  @Autowired
  public DiffSyncController(PersistenceCallbackRegistry callbackRegistry, ShadowStore shadowStore) {
    this.callbackRegistry = callbackRegistry;
    this.shadowStore = shadowStore;
  }

  @SuppressWarnings({ "unchecked", "rawtypes" })
  @RequestMapping(
      value="${spring.diffsync.path:}/{resource}",
      method=RequestMethod.PATCH)
  public Patch patch(@PathVariable("resource") String resource, @RequestBody Patch patch) throws PatchException {
    PersistenceCallback<?> persistenceCallback = callbackRegistry.findPersistenceCallback(resource);    
    return applyAndDiffAgainstList(patch, (List) persistenceCallback.findAll(), persistenceCallback);
  }

  @RequestMapping(
      value="${spring.diffsync.path:}/{resource}/{id}",
      method=RequestMethod.PATCH)
  public Patch patch(@PathVariable("resource") String resource, @PathVariable("id") String id, @RequestBody Patch patch) throws PatchException {
    PersistenceCallback<?> persistenceCallback = callbackRegistry.findPersistenceCallback(resource);    
    Object findOne = persistenceCallback.findOne(id);
    return applyAndDiff(patch, findOne, persistenceCallback);
  }

  
  @ExceptionHandler(PatchException.class)
  @ResponseStatus(value=HttpStatus.CONFLICT, reason="Unable to apply patch")
  public void handlePatchException(PatchException e) {}
  
  
  @SuppressWarnings("unchecked")
  private <T> Patch applyAndDiff(Patch patch, Object target, PersistenceCallback<T> persistenceCallback) {
    DiffSync<T> sync = new DiffSync<T>(shadowStore, persistenceCallback.getEntityType());
    T patched = sync.apply((T) target, patch);
    persistenceCallback.persistChange(patched);
    return sync.diff(patched);
  }
  
  private <T> Patch applyAndDiffAgainstList(Patch patch, List<T> target, PersistenceCallback<T> persistenceCallback) {
    DiffSync<T> sync = new DiffSync<T>(shadowStore, persistenceCallback.getEntityType());
    
    List<T> patched = sync.apply(target, patch);

    List<T> itemsToSave = new ArrayList<T>(patched);
    itemsToSave.removeAll(target);

    // Determine which items should be deleted.
    // Make a shallow copy of the target, remove items that are equivalent to items in the working copy.
    // Equivalent is not the same as equals. It means "this is the same resource, even if it has changed".
    // It usually means "are the id properties equals".
    List<T> itemsToDelete = new ArrayList<T>(target);
    for (T candidate : target) {
      for (T item : patched) {
        if (equivalency.isEquivalent(candidate, item)) {
          itemsToDelete.remove(candidate);
          break;
        }
      }
    }
    persistenceCallback.persistChanges(itemsToSave, itemsToDelete);
    
    return sync.diff(patched);
  }

}




Java Source Code List

org.springframework.sync.AddOperationTest.java
org.springframework.sync.AddOperation.java
org.springframework.sync.CopyOperationTest.java
org.springframework.sync.CopyOperation.java
org.springframework.sync.DiffTest.java
org.springframework.sync.Diff.java
org.springframework.sync.FromOperation.java
org.springframework.sync.InverseTest.java
org.springframework.sync.JsonPatchTest.java
org.springframework.sync.LateObjectEvaluator.java
org.springframework.sync.MoveOperationTest.java
org.springframework.sync.MoveOperation.java
org.springframework.sync.PatchException.java
org.springframework.sync.PatchOperation.java
org.springframework.sync.Patch.java
org.springframework.sync.PathToSpEL.java
org.springframework.sync.PathToSpelTest.java
org.springframework.sync.RemoveOperationTest.java
org.springframework.sync.RemoveOperation.java
org.springframework.sync.ReplaceOperationTest.java
org.springframework.sync.ReplaceOperation.java
org.springframework.sync.TestOperationTest.java
org.springframework.sync.TestOperation.java
org.springframework.sync.Todo.java
org.springframework.sync.diffsync.AbstractShadowStore.java
org.springframework.sync.diffsync.DiffSync.java
org.springframework.sync.diffsync.Equivalency.java
org.springframework.sync.diffsync.IdPropertyEquivalency.java
org.springframework.sync.diffsync.PersistenceCallbackRegistry.java
org.springframework.sync.diffsync.PersistenceCallback.java
org.springframework.sync.diffsync.PersistenceStrategy.java
org.springframework.sync.diffsync.ShadowStore.java
org.springframework.sync.diffsync.Shadow.java
org.springframework.sync.diffsync.VersionedPatch.java
org.springframework.sync.diffsync.config.DiffSyncConfigurerAdapter.java
org.springframework.sync.diffsync.config.DiffSyncConfigurer.java
org.springframework.sync.diffsync.config.DifferentialSynchronizationRegistrar.java
org.springframework.sync.diffsync.config.EnableDifferentialSynchronization.java
org.springframework.sync.diffsync.config.package-info.java
org.springframework.sync.diffsync.shadowstore.GemfireShadowStore.java
org.springframework.sync.diffsync.shadowstore.MapBasedShadowStore.java
org.springframework.sync.diffsync.shadowstore.RedisShadowStore.java
org.springframework.sync.diffsync.shadowstore.package-info.java
org.springframework.sync.diffsync.web.DiffSyncController.java
org.springframework.sync.diffsync.web.JsonPatchHttpMessageConverter.java
org.springframework.sync.diffsync.web.package-info.java
org.springframework.sync.diffsync.package-info.java
org.springframework.sync.json.JsonLateObjectEvaluator.java
org.springframework.sync.json.JsonPatchPatchConverter.java
org.springframework.sync.json.PatchConverter.java
org.springframework.sync.json.package-info.java
org.springframework.sync.util.DeepCloneUtils.java
org.springframework.sync.package-info.java