Coverage Report - org.kuali.student.r2.common.helper.EntityMergeHelper
 
Classes in this File Line Coverage Branch Coverage Complexity
EntityMergeHelper
0%
0/38
0%
0/16
1.667
EntityMergeHelper$EntityMergeOptions
N/A
N/A
1.667
EntityMergeHelper$EntityMergeResult
0%
0/6
N/A
1.667
EntityMergeHelper$StringMergeOptions
N/A
N/A
1.667
 
 1  
 /**
 2  
  * Copyright 2012 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the the Educational Community License, Version 1.0
 5  
  * (the "License"); you may not use this file except in compliance
 6  
  * with the License.  You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl1.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.student.r2.common.helper;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.LinkedHashMap;
 20  
 import java.util.List;
 21  
 import java.util.Map;
 22  
 
 23  
 /**
 24  
  * 
 25  
  * Helps perform merge operations that take place when an entity is loaded from
 26  
  * the database and then updated from the dto content being provided through the
 27  
  * service.
 28  
  * 
 29  
  * @author ocleirig
 30  
  * 
 31  
  * @param <E> The entity being merged into.
 32  
  * @param <INFO> the dto providing the data to be merged.
 33  
  */
 34  
 public final class EntityMergeHelper<E, INFO> {
 35  
 
 36  
         /**
 37  
          * Options when merging the entity from the dto.
 38  
          *
 39  
          * @param <E>
 40  
          * @param <INFO>
 41  
          */
 42  
         public static interface EntityMergeOptions<E, INFO> {
 43  
                 
 44  
                 /**
 45  
                  * Extracts the id from the entity object.
 46  
                  * 
 47  
                  * @param entity the entity.
 48  
                  * @return the database id for the entity.
 49  
                  */
 50  
                 public String getEntityId(E entity);
 51  
 
 52  
                 /**
 53  
                  * Extracts the id from the dto info object.
 54  
                  * 
 55  
                  * @param info the dto,
 56  
                  * @return the database id encoded in the dto.
 57  
                  */
 58  
                 public String getInfoId(INFO info);
 59  
 
 60  
                 /**
 61  
                  * Merges the dto info into the entity.
 62  
                  * 
 63  
                  * @param entity the target entity.
 64  
                  * @param info the source dto
 65  
                  * @return the list of objects that should be detatched due to the merge.
 66  
                  */
 67  
                 public List<Object> merge(E entity, INFO info);
 68  
 
 69  
                 /**
 70  
                  * Creates a new instance of the target entity.
 71  
                  * 
 72  
                  * @param info the source dto.
 73  
                  * @return the new entity.
 74  
                  */
 75  
                 public E create(INFO info);
 76  
 
 77  
         }
 78  
 
 79  
         /**
 80  
      * Options for merging a list of strings into a list of entities.
 81  
          * 
 82  
          * @param <E> The Entity object
 83  
          */
 84  
         public static interface StringMergeOptions<E> {
 85  
 
 86  
                 /**
 87  
                  * Extract a comparison key from the entity that will match the value of the string list items (for comparison purposes)
 88  
                  * 
 89  
                  * @param entity
 90  
                  * @return the comnparison key.
 91  
                  */
 92  
                 public String getKey(E entity);
 93  
 
 94  
                 /**
 95  
                  * Create a new entry based on the string value provided.
 96  
                  * 
 97  
                  * @param string
 98  
                  * @return the new entity.
 99  
                  */
 100  
                 public E create(String value);
 101  
 
 102  
         }
 103  
 
 104  
         /**
 105  
          * The results of a merge are the merged list and the list of orphaned data.
 106  
          * 
 107  
          * @param <E> the target entity.
 108  
          */
 109  
         public static final class EntityMergeResult<E> {
 110  
 
 111  
                 private final List<E> mergedList;
 112  
 
 113  
                 private final List<Object> orphanList;
 114  
 
 115  
                 public EntityMergeResult(List<E> mergedList, List<Object> orphanList) {
 116  0
                         super();
 117  0
                         this.mergedList = mergedList;
 118  0
                         this.orphanList = orphanList;
 119  0
                 }
 120  
 
 121  
                 public List<E> getMergedList() {
 122  0
                         return mergedList;
 123  
                 }
 124  
 
 125  
                 public List<Object> getOrphanList() {
 126  0
                         return orphanList;
 127  
                 }
 128  
 
 129  
         }
 130  
 
 131  
         
 132  0
         public EntityMergeHelper() {
 133  0
         }
 134  
 
 135  
         /**
 136  
          * Merges a simple string list against a persisted list. We assume that if
 137  
          * the string value does not exist then we can delete the item.
 138  
          * 
 139  
          * @param entityList the list of entities
 140  
          * @param stringList the list of values
 141  
          * @return the merge results.
 142  
          */
 143  
         public EntityMergeResult<E> mergeStringList(List<E> entityList,
 144  
                         List<String> stringList, StringMergeOptions<E> options) {
 145  
 
 146  
                 /*
 147  
                  * Steps:
 148  
                  * 1. create existing map
 149  
                  * 2. create new entries or remove existing from the map
 150  
                  * 3. return new entity list and orphan list.
 151  
                  */
 152  0
                 List<E> mergedList = new ArrayList<E>();
 153  
 
 154  0
                 List<Object> orphanDataList = new ArrayList<Object>();
 155  
 
 156  0
                 Map<String, E> existingEntityMap = new LinkedHashMap<String, E>();
 157  
 
 158  0
                 if (entityList != null) {
 159  0
                         for (E e : entityList) {
 160  
 
 161  0
                                 String key = options.getKey(e);
 162  
 
 163  0
                                 existingEntityMap.put(key, e);
 164  
 
 165  0
                         }
 166  
                 }
 167  0
                 for (String string : stringList) {
 168  
 
 169  0
                         E entity = existingEntityMap.get(string);
 170  
 
 171  0
                         if (entity == null) {
 172  
                                 // create
 173  
 
 174  0
                                 entity = options.create(string);
 175  
 
 176  
                         } else {
 177  
                                 // remove from existing map
 178  0
                                 existingEntityMap.remove(string);
 179  
                         }
 180  
 
 181  0
                         mergedList.add(entity);
 182  
 
 183  0
                 }
 184  
 
 185  0
                 orphanDataList.addAll(existingEntityMap.values());
 186  
 
 187  0
                 return new EntityMergeResult<E>(mergedList, orphanDataList);
 188  
         }
 189  
 
 190  
         /**
 191  
          * Performs a Merge of the current entity list from the info list and
 192  
          * options provided.
 193  
          * 
 194  
          * The results are the list of merged entities and a list of orphaned objects that can be deleted from the database.
 195  
          * 
 196  
          * @param entityList the target list of entities
 197  
          * @param infoList the source list of dto info objects.
 198  
          * @param options the logic for extracting the keys and creating/merging the entities.
 199  
          * @return the results of the merge.
 200  
          */
 201  
         public EntityMergeResult<E> merge(List<E> entityList, List<INFO> infoList,
 202  
                         EntityMergeOptions<E, INFO> options) {
 203  
 
 204  0
                 List<Object> orphanDataList = new ArrayList<Object>();
 205  
 
 206  0
                 Map<String, E> existingEntityMap = new LinkedHashMap<String, E>();
 207  
 
 208  0
                 if (entityList != null) {
 209  0
                         for (E e : entityList) {
 210  
 
 211  0
                                 String id = options.getEntityId(e);
 212  
 
 213  0
                                 existingEntityMap.put(id, e);
 214  
 
 215  0
                         }
 216  
                 }
 217  
 
 218  0
                 List<E> mergedList = new ArrayList<E>();
 219  
 
 220  0
                 for (INFO info : infoList) {
 221  
 
 222  0
                         String id = options.getInfoId(info);
 223  
 
 224  0
                         E entity = null;
 225  0
                         if (existingEntityMap.containsKey(id)) {
 226  
                                 // merge
 227  0
                                 entity = existingEntityMap.remove(id);
 228  
 
 229  0
                                 orphanDataList.addAll(options.merge(entity, info));
 230  
 
 231  
                         } else {
 232  
                                 // new entry
 233  
 
 234  0
                                 entity = options.create(info);
 235  
                         }
 236  
 
 237  0
                         mergedList.add(entity);
 238  0
                 }
 239  
 
 240  0
                 orphanDataList.addAll(existingEntityMap.values());
 241  
 
 242  0
                 return new EntityMergeResult<E>(mergedList, orphanDataList);
 243  
 
 244  
         }
 245  
 
 246  
 }