[Fix] fixed check for duplicate objects in the cache

This commit is contained in:
Reto Breitenmoser 2017-10-05 10:38:03 +02:00
parent 4087608e1a
commit 8525bbdf6a
1 changed files with 67 additions and 61 deletions

View File

@ -16,12 +16,18 @@
package li.strolch.utils.objectfilter;
import java.text.MessageFormat;
import java.util.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import li.strolch.utils.collections.MapOfMaps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import li.strolch.utils.collections.MapOfMaps;
/**
* This class implements a filter where modifications to an object are collected, and only the most recent action and
* version of the object is returned.
@ -121,17 +127,16 @@ public class ObjectFilter {
* </table>
*
* @param key
* the key to register the object with
* the key to register the object with
* @param objectKey
* the key for the object
* the key for the object
* @param objectToAdd
* The object for which addition shall be registered.
* The object for which addition shall be registered.
*/
public void add(String key, Object objectKey, Object objectToAdd) {
if (ObjectFilter.logger.isDebugEnabled())
ObjectFilter.logger
.debug(MessageFormat.format("add object {0} with key {1}", objectToAdd, key)); //$NON-NLS-1$
ObjectFilter.logger.debug(MessageFormat.format("add object {0} with key {1}", objectToAdd, key)); //$NON-NLS-1$
// BEWARE: you fix a bug here, be sure to update BOTH tables on the logic.
ObjectCache cached = this.cache.getElement(key, objectKey);
@ -147,9 +152,8 @@ public class ObjectFilter {
String existingKey = cached.getKey();
if (!existingKey.equals(key)) {
String msg = "Invalid key provided for object with transaction ID {0} and operation {1}: existing key is {2}, new key is {3}. Object may be present in the same filter instance only once, registered using one key only. Object:{4}"; //$NON-NLS-1$
throw new IllegalArgumentException(MessageFormat
.format(msg, Long.toString(id), Operation.ADD.toString(), existingKey, key,
objectKey.toString()));
throw new IllegalArgumentException(MessageFormat.format(msg, Long.toString(id),
Operation.ADD.toString(), existingKey, key, objectKey.toString()));
}
// The object is in cache: update the version as required, keeping in mind that most
@ -198,22 +202,34 @@ public class ObjectFilter {
* </table>
*
* @param key
* the key to register the object with
* the key to register the object with
* @param objectKey
* the key for the object
* the key for the object
* @param objectToUpdate
* The object for which update shall be registered.
* The object for which update shall be registered.
*/
public void update(String key, Object objectKey, Object objectToUpdate) {
if (ObjectFilter.logger.isDebugEnabled())
ObjectFilter.logger
.debug(MessageFormat.format("update object {0} with key {1}", objectKey, key)); //$NON-NLS-1$
ObjectFilter.logger.debug(MessageFormat.format("update object {0} with key {1}", objectKey, key)); //$NON-NLS-1$
// BEWARE: you fix a bug here, be sure to update BOTH tables on the logic.
ObjectCache cached = this.cache.getElement(key, objectKey);
if (cached == null) {
List<ObjectCache> allElements = this.cache.getAllElements();
// check if the object is already in the cache with an other key
if (allElements.stream().anyMatch(oCache -> oCache.getObject().equals(objectToUpdate))) {
String msg = "Invalid key provided for object with transaction ID {0} and operation {1}: existing key is {2}, new key is {3}. Object may be present in the same filter instance only once, registered using one key only. Object:{4}"; //$NON-NLS-1$
Optional<ObjectCache> duplicateObj = allElements.stream()
.filter(oCache -> oCache.getObject().equals(objectToUpdate)).findFirst();
throw new IllegalArgumentException(MessageFormat.format(msg, Long.toString(id),
Operation.MODIFY.toString(), duplicateObj.get().getKey(), key, objectToUpdate.toString()));
}
// The object got an ID during this run, but was not added to this cache.
// Hence, we add it now, with the current operation.
ObjectCache cacheObj = new ObjectCache(dispenseID(), key, objectKey, objectToUpdate, Operation.MODIFY);
@ -221,14 +237,6 @@ public class ObjectFilter {
} else {
String existingKey = cached.getKey();
if (!existingKey.equals(key)) {
String msg = "Invalid key provided for object with transaction ID {0} and operation {1}: existing key is {2}, new key is {3}. Object may be present in the same filter instance only once, registered using one key only. Object:{4}"; //$NON-NLS-1$
throw new IllegalArgumentException(MessageFormat
.format(msg, Long.toString(id), Operation.MODIFY.toString(), existingKey, key,
objectToUpdate.toString()));
}
// The object is in cache: update the version as required.
Operation op = cached.getOperation();
switch (op) {
@ -272,17 +280,16 @@ public class ObjectFilter {
* </table>
*
* @param key
* the key to register the object with
* the key to register the object with
* @param objectKey
* the key for the object
* the key for the object
* @param objectToRemove
* The object for which removal shall be registered.
* The object for which removal shall be registered.
*/
public void remove(String key, Object objectKey, Object objectToRemove) {
if (ObjectFilter.logger.isDebugEnabled())
ObjectFilter.logger
.debug(MessageFormat.format("remove object {0} with key {1}", objectKey, key)); //$NON-NLS-1$
ObjectFilter.logger.debug(MessageFormat.format("remove object {0} with key {1}", objectKey, key)); //$NON-NLS-1$
// BEWARE: you fix a bug here, be sure to update BOTH tables on the logic.
ObjectCache cached = this.cache.getElement(key, objectKey);
@ -296,9 +303,8 @@ public class ObjectFilter {
String existingKey = cached.getKey();
if (!existingKey.equals(key)) {
String msg = "Invalid key provided for object with transaction ID {0} and operation {1}: existing key is {2}, new key is {3}. Object may be present in the same filter instance only once, registered using one key only. Object:{4}"; //$NON-NLS-1$
throw new IllegalArgumentException(MessageFormat
.format(msg, Long.toString(id), Operation.REMOVE.toString(), existingKey, key,
objectKey.toString()));
throw new IllegalArgumentException(MessageFormat.format(msg, Long.toString(id),
Operation.REMOVE.toString(), existingKey, key, objectKey.toString()));
}
// The object is in cache: update the version as required.
@ -332,7 +338,7 @@ public class ObjectFilter {
* Register the addition of the given object. Since no key is provided, the class name is used as a key.
*
* @param object
* The object that shall be registered for addition
* The object that shall be registered for addition
*/
public void add(Object object) {
add(object.getClass().getName(), object, object);
@ -342,9 +348,9 @@ public class ObjectFilter {
* Register the addition of the given object. Since no key is provided, the class name is used as a key.
*
* @param objectKey
* the key for the object
* the key for the object
* @param object
* The object that shall be registered for addition
* The object that shall be registered for addition
*/
public void add(Object objectKey, Object object) {
add(object.getClass().getName(), objectKey, object);
@ -354,7 +360,7 @@ public class ObjectFilter {
* Register the update of the given object. Since no key is provided, the class name is used as a key.
*
* @param object
* The object that shall be registered for updating
* The object that shall be registered for updating
*/
public void update(Object object) {
update(object.getClass().getName(), object, object);
@ -364,9 +370,9 @@ public class ObjectFilter {
* Register the update of the given object. Since no key is provided, the class name is used as a key.
*
* @param objectKey
* the key for the object
* the key for the object
* @param object
* The object that shall be registered for updating
* The object that shall be registered for updating
*/
public void update(Object objectKey, Object object) {
update(object.getClass().getName(), objectKey, object);
@ -376,7 +382,7 @@ public class ObjectFilter {
* Register the removal of the given object. Since no key is provided, the class name is used as a key.
*
* @param object
* The object that shall be registered for removal
* The object that shall be registered for removal
*/
public void remove(Object object) {
remove(object.getClass().getName(), object, object);
@ -386,9 +392,9 @@ public class ObjectFilter {
* Register the removal of the given object. Since no key is provided, the class name is used as a key.
*
* @param objectKey
* the key for the object
* the key for the object
* @param object
* The object that shall be registered for removal
* The object that shall be registered for removal
*/
public void remove(Object objectKey, Object object) {
remove(object.getClass().getName(), objectKey, object);
@ -398,9 +404,9 @@ public class ObjectFilter {
* Returns the ObjectCache for the given key and objectKey
*
* @param key
* the key under which it was registered
* the key under which it was registered
* @param objectKey
* the objectKey
* the objectKey
*
* @return the ObjectCache, or null
*/
@ -412,11 +418,11 @@ public class ObjectFilter {
* Returns the element with the given key and objectKey
*
* @param key
* the key under which it was registered
* the key under which it was registered
* @param objectKey
* the objectKey
* the objectKey
* @param <V>
* the class to which to cast the element to
* the class to which to cast the element to
*
* @return the element, or null
*/
@ -433,9 +439,9 @@ public class ObjectFilter {
* Return true if the element with the given key and objectKey exist
*
* @param key
* the key under which it was registered
* the key under which it was registered
* @param objectKey
* the objectKey
* the objectKey
*
* @return true if the element with the given key and objectKey exist
*/
@ -447,7 +453,7 @@ public class ObjectFilter {
* Get all objects that were registered under the given key and that have as a resulting final action an addition.
*
* @param key
* The registration key of the objects to match
* The registration key of the objects to match
*
* @return The list of all objects registered under the given key and that need to be added.
*/
@ -466,9 +472,9 @@ public class ObjectFilter {
* Get all objects that were registered under the given key and that have as a resulting final action an addition.
*
* @param clazz
* The class type of the object to be retrieved, that acts as an additional filter criterion.
* The class type of the object to be retrieved, that acts as an additional filter criterion.
* @param key
* The registration key of the objects to match
* The registration key of the objects to match
*
* @return The list of all objects registered under the given key and that need to be added.
*/
@ -491,7 +497,7 @@ public class ObjectFilter {
* Get all objects that were registered under the given key and that have as a resulting final action an update.
*
* @param key
* registration key of the objects to match
* registration key of the objects to match
*
* @return The list of all objects registered under the given key and that need to be updated.
*/
@ -510,9 +516,9 @@ public class ObjectFilter {
* Get all objects that were registered under the given key and that have as a resulting final action an update.
*
* @param clazz
* The class type of the object to be retrieved, that acts as an additional filter criterion.
* The class type of the object to be retrieved, that acts as an additional filter criterion.
* @param key
* registration key of the objects to match
* registration key of the objects to match
*
* @return The list of all objects registered under the given key and that need to be updated.
*/
@ -535,7 +541,7 @@ public class ObjectFilter {
* Get all objects that were registered under the given key that have as a resulting final action their removal.
*
* @param key
* The registration key of the objects to match
* The registration key of the objects to match
*
* @return The list of object registered under the given key that have, as a final action, removal.
*/
@ -554,9 +560,9 @@ public class ObjectFilter {
* Get all objects that were registered under the given key that have as a resulting final action their removal.
*
* @param clazz
* The class type of the object to be retrieved, that acts as an additional filter criterion.
* The class type of the object to be retrieved, that acts as an additional filter criterion.
* @param key
* The registration key of the objects to match
* The registration key of the objects to match
*
* @return The list of object registered under the given key that have, as a final action, removal.
*/
@ -579,9 +585,9 @@ public class ObjectFilter {
* Get all objects that were registered under the given key
*
* @param clazz
* The class type of the object to be retrieved, that acts as an additional filter criterion.
* The class type of the object to be retrieved, that acts as an additional filter criterion.
* @param key
* The registration key of the objects to match
* The registration key of the objects to match
*
* @return The list of object registered under the given key that have, as a final action, removal.
*/
@ -602,7 +608,7 @@ public class ObjectFilter {
* Get all objects that of the given class
*
* @param clazz
* The class type of the object to be retrieved, that acts as an additional filter criterion.
* The class type of the object to be retrieved, that acts as an additional filter criterion.
*
* @return The list of all objects that of the given class
*/
@ -624,7 +630,7 @@ public class ObjectFilter {
* is associated to the object.
*
* @param key
* The registration key for which the objects shall be retrieved
* The registration key for which the objects shall be retrieved
*
* @return The list of objects matching the given key.
*/
@ -642,7 +648,7 @@ public class ObjectFilter {
* is associated to the object.
*
* @param key
* The registration key for which the objects shall be retrieved
* The registration key for which the objects shall be retrieved
*
* @return The list of objects matching the given key.
*/