[Major] Multiple changes to StrolchTransaction:
New: - needsCommit() -> return true if objects or commands are registered - hasResource() - hasOrder() - hasActivity() Changes: - When tx.add(), update() or remove() is called, then get*Template(), or get*By() check the internal cache and thus e.g. a new resource is immediately available. - the has*()-methods also check the internal cache, thus the need to get the underlying maps should now no longe be required in normal TX use.
This commit is contained in:
parent
b2604f7ab5
commit
dad2f35b16
|
@ -25,7 +25,7 @@ import li.strolch.model.parameter.Parameter;
|
|||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
class ElementMapHelpers {
|
||||
public class ElementMapHelpers {
|
||||
|
||||
public static void assertIsRefParam(String expectedInterpretation, Parameter<?> refP) {
|
||||
|
||||
|
|
|
@ -15,50 +15,21 @@
|
|||
*/
|
||||
package li.strolch.persistence.api;
|
||||
|
||||
import static li.strolch.model.StrolchModelConstants.*;
|
||||
import static li.strolch.model.Tags.AGENT;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import li.strolch.agent.api.ActivityMap;
|
||||
import li.strolch.agent.api.AuditTrail;
|
||||
import li.strolch.agent.api.ComponentContainer;
|
||||
import li.strolch.agent.api.ObserverEvent;
|
||||
import li.strolch.agent.api.ObserverHandler;
|
||||
import li.strolch.agent.api.OrderMap;
|
||||
import li.strolch.agent.api.ResourceMap;
|
||||
import li.strolch.agent.api.StrolchAgent;
|
||||
import li.strolch.agent.api.StrolchLockException;
|
||||
import li.strolch.agent.api.StrolchRealm;
|
||||
import li.strolch.agent.impl.AuditingActivityMap;
|
||||
import li.strolch.agent.impl.AuditingAuditMapFacade;
|
||||
import li.strolch.agent.impl.AuditingOrderMap;
|
||||
import li.strolch.agent.impl.AuditingResourceMap;
|
||||
import li.strolch.agent.impl.InternalStrolchRealm;
|
||||
import li.strolch.agent.api.*;
|
||||
import li.strolch.agent.impl.*;
|
||||
import li.strolch.exception.StrolchAccessDeniedException;
|
||||
import li.strolch.exception.StrolchException;
|
||||
import li.strolch.exception.StrolchModelException;
|
||||
import li.strolch.handler.operationslog.LogMessage;
|
||||
import li.strolch.handler.operationslog.LogSeverity;
|
||||
import li.strolch.handler.operationslog.OperationsLog;
|
||||
import li.strolch.model.GroupedParameterizedElement;
|
||||
import li.strolch.model.Locator;
|
||||
import li.strolch.model.Order;
|
||||
import li.strolch.model.ParameterBag;
|
||||
import li.strolch.model.Resource;
|
||||
import li.strolch.model.StrolchElement;
|
||||
import li.strolch.model.StrolchRootElement;
|
||||
import li.strolch.model.Tags;
|
||||
import li.strolch.model.*;
|
||||
import li.strolch.model.activity.Activity;
|
||||
import li.strolch.model.activity.IActivityElement;
|
||||
import li.strolch.model.audit.AccessType;
|
||||
|
@ -73,11 +44,11 @@ import li.strolch.model.query.ResourceQuery;
|
|||
import li.strolch.model.query.StrolchQuery;
|
||||
import li.strolch.model.timedstate.StrolchTimedState;
|
||||
import li.strolch.model.timevalue.IValue;
|
||||
import li.strolch.model.visitor.ElementTypeVisitor;
|
||||
import li.strolch.privilege.base.AccessDeniedException;
|
||||
import li.strolch.privilege.base.PrivilegeException;
|
||||
import li.strolch.privilege.model.Certificate;
|
||||
import li.strolch.privilege.model.PrivilegeContext;
|
||||
import li.strolch.runtime.StrolchConstants;
|
||||
import li.strolch.runtime.privilege.PrivilegeHandler;
|
||||
import li.strolch.runtime.privilege.TransactedRestrictable;
|
||||
import li.strolch.service.api.Command;
|
||||
|
@ -85,6 +56,8 @@ import li.strolch.utils.dbc.DBC;
|
|||
import li.strolch.utils.helper.ExceptionHelper;
|
||||
import li.strolch.utils.helper.StringHelper;
|
||||
import li.strolch.utils.objectfilter.ObjectFilter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
|
@ -279,7 +252,12 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T extends StrolchRootElement> void lock(Locator locator) throws StrolchLockException {
|
||||
public boolean needsCommit() {
|
||||
return !this.objectFilter.isEmpty() || !this.commands.isEmpty() || !this.flushedCommands.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lock(Locator locator) throws StrolchLockException {
|
||||
this.realm.lock(locator);
|
||||
this.lockedElements.add(locator);
|
||||
}
|
||||
|
@ -511,33 +489,52 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
throw new StrolchException(MessageFormat.format(msg, locator, stateOrBagOrActivity));
|
||||
}
|
||||
|
||||
private <V> V getElementFromFilter(String key, Locator locator) {
|
||||
if (this.objectFilter == null)
|
||||
return null;
|
||||
return this.objectFilter.getElement(key, locator);
|
||||
}
|
||||
|
||||
private boolean hasElementInFilter(String key, Locator locator) {
|
||||
return this.objectFilter != null && this.objectFilter.hasElement(key, locator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResourceTemplate(String type) {
|
||||
return getResourceMap().getTemplate(this, type);
|
||||
return getResourceTemplate(type, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResourceTemplate(String type, boolean assertExists) throws StrolchException {
|
||||
Resource element = getElementFromFilter(Tags.RESOURCE, Resource.locatorFor(StrolchConstants.TEMPLATE, type));
|
||||
if (element != null)
|
||||
return element;
|
||||
return getResourceMap().getTemplate(this, type, assertExists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Order getOrderTemplate(String type) {
|
||||
return getOrderMap().getTemplate(this, type);
|
||||
return getOrderTemplate(type, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Order getOrderTemplate(String type, boolean assertExists) throws StrolchException {
|
||||
Order element = getElementFromFilter(Tags.ORDER, Order.locatorFor(StrolchConstants.TEMPLATE, type));
|
||||
if (element != null)
|
||||
return element;
|
||||
return getOrderMap().getTemplate(this, type, assertExists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Activity getActivityTemplate(String type) {
|
||||
return getActivityMap().getTemplate(this, type);
|
||||
return getActivityTemplate(type, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Activity getActivityTemplate(String type, boolean assertExists) throws StrolchException {
|
||||
Activity element = getElementFromFilter(Tags.ACTIVITY, Activity.locatorFor(StrolchConstants.TEMPLATE, type));
|
||||
if (element != null)
|
||||
return element;
|
||||
return getActivityMap().getTemplate(this, type, assertExists);
|
||||
}
|
||||
|
||||
|
@ -548,31 +545,43 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
|
||||
@Override
|
||||
public Order getOrderBy(String type, String id, boolean assertExists) throws StrolchException {
|
||||
Order element = getElementFromFilter(Tags.ORDER, Order.locatorFor(type, id));
|
||||
if (element != null)
|
||||
return element;
|
||||
return getOrderMap().getBy(this, type, id, assertExists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Order getOrderBy(StringParameter refP) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
return getOrderBy(refP, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Order getOrderBy(StringParameter refP, boolean assertExists) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
ElementMapHelpers.assertIsRefParam(INTERPRETATION_ORDER_REF, refP);
|
||||
Order element = getElementFromFilter(Tags.ORDER, Order.locatorFor(refP.getUom(), refP.getValue()));
|
||||
if (element != null)
|
||||
return element;
|
||||
return getOrderMap().getBy(this, refP, assertExists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Order> getOrdersBy(StringListParameter refP) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
return getOrderMap().getBy(this, refP, false);
|
||||
return getOrdersBy(refP, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Order> getOrdersBy(StringListParameter refP, boolean assertExists) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
return getOrderMap().getBy(this, refP, assertExists);
|
||||
ElementMapHelpers.assertIsRefParam(INTERPRETATION_ORDER_REF, refP);
|
||||
List<Order> elements = new ArrayList<>();
|
||||
for (String id : refP.getValue()) {
|
||||
Order element = getOrderBy(refP.getUom(), id, assertExists);
|
||||
if (element != null)
|
||||
elements.add(element);
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -582,36 +591,43 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
|
||||
@Override
|
||||
public Resource getResourceBy(String type, String id, boolean assertExists) throws StrolchException {
|
||||
Resource resource = getResourceMap().getBy(this, type, id);
|
||||
if (assertExists && resource == null) {
|
||||
String msg = "No Resource exists with the id {0} with type {1}";
|
||||
throw new StrolchException(MessageFormat.format(msg, id, type));
|
||||
}
|
||||
return resource;
|
||||
Resource result = getElementFromFilter(Tags.RESOURCE, Resource.locatorFor(type, id));
|
||||
if (result != null)
|
||||
return result;
|
||||
return getResourceMap().getBy(this, type, id, assertExists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResourceBy(StringParameter refP) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
return getResourceBy(refP, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResourceBy(StringParameter refP, boolean assertExists) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
ElementMapHelpers.assertIsRefParam(INTERPRETATION_RESOURCE_REF, refP);
|
||||
Resource element = getElementFromFilter(Tags.RESOURCE, Resource.locatorFor(refP.getUom(), refP.getValue()));
|
||||
if (element != null)
|
||||
return element;
|
||||
return getResourceMap().getBy(this, refP, assertExists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resource> getResourcesBy(StringListParameter refP) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
return getResourceMap().getBy(this, refP, false);
|
||||
return getResourcesBy(refP, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resource> getResourcesBy(StringListParameter refP, boolean assertExists) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
return getResourceMap().getBy(this, refP, assertExists);
|
||||
ElementMapHelpers.assertIsRefParam(INTERPRETATION_RESOURCE_REF, refP);
|
||||
List<Resource> elements = new ArrayList<>();
|
||||
for (String id : refP.getValue()) {
|
||||
Resource element = getResourceBy(refP.getUom(), id, assertExists);
|
||||
if (element != null)
|
||||
elements.add(element);
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -621,36 +637,61 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
|
||||
@Override
|
||||
public Activity getActivityBy(String type, String id, boolean assertExists) throws StrolchException {
|
||||
Activity activity = getActivityMap().getBy(this, type, id);
|
||||
if (assertExists && activity == null) {
|
||||
String msg = "No Activity exists with the id {0} with type {1}";
|
||||
throw new StrolchException(MessageFormat.format(msg, id, type));
|
||||
}
|
||||
return activity;
|
||||
Activity result = getElementFromFilter(Tags.ACTIVITY, Activity.locatorFor(type, id));
|
||||
if (result != null)
|
||||
return result;
|
||||
return getActivityMap().getBy(this, type, id, assertExists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Activity getActivityBy(StringParameter refP) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
return getActivityBy(refP, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Activity getActivityBy(StringParameter refP, boolean assertExists) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
ElementMapHelpers.assertIsRefParam(INTERPRETATION_ACTIVITY_REF, refP);
|
||||
Activity element = getElementFromFilter(Tags.ACTIVITY, Activity.locatorFor(refP.getUom(), refP.getValue()));
|
||||
if (element != null)
|
||||
return element;
|
||||
return getActivityMap().getBy(this, refP, assertExists);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Activity> getActivitiesBy(StringListParameter refP) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
return getActivityMap().getBy(this, refP, false);
|
||||
return getActivitiesBy(refP, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Activity> getActivitiesBy(StringListParameter refP, boolean assertExists) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("refP", refP);
|
||||
return getActivityMap().getBy(this, refP, assertExists);
|
||||
ElementMapHelpers.assertIsRefParam(INTERPRETATION_ACTIVITY_REF, refP);
|
||||
List<Activity> elements = new ArrayList<>();
|
||||
for (String id : refP.getValue()) {
|
||||
Activity element = getActivityBy(refP.getUom(), id, assertExists);
|
||||
if (element != null)
|
||||
elements.add(element);
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasResource(String type, String id) {
|
||||
boolean inFilter = hasElementInFilter(Tags.RESOURCE, Resource.locatorFor(type, id));
|
||||
return inFilter || getResourceMap().hasElement(this, type, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOrder(String type, String id) {
|
||||
boolean inFilter = hasElementInFilter(Tags.ORDER, Order.locatorFor(type, id));
|
||||
return inFilter || getOrderMap().hasElement(this, type, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasActivity(String type, String id) {
|
||||
boolean inFilter = hasElementInFilter(Tags.ACTIVITY, Activity.locatorFor(type, id));
|
||||
return inFilter || getActivityMap().hasElement(this, type, id);
|
||||
}
|
||||
|
||||
private ObjectFilter getObjectFilter() {
|
||||
|
@ -670,55 +711,55 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
@Override
|
||||
public void add(Resource resource) throws StrolchModelException {
|
||||
DBC.PRE.assertNotNull("resource must not be null", resource);
|
||||
getObjectFilter().add(Tags.RESOURCE, resource);
|
||||
getObjectFilter().add(Tags.RESOURCE, resource.getLocator(), resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Order order) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("order must not be null", order);
|
||||
getObjectFilter().add(Tags.ORDER, order);
|
||||
getObjectFilter().add(Tags.ORDER, order.getLocator(), order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Activity activity) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("activity must not be null", activity);
|
||||
getObjectFilter().add(Tags.ACTIVITY, activity);
|
||||
getObjectFilter().add(Tags.ACTIVITY, activity.getLocator(), activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Resource resource) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("resource must not be null", resource);
|
||||
getObjectFilter().update(Tags.RESOURCE, resource);
|
||||
getObjectFilter().update(Tags.RESOURCE, resource.getLocator(), resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Order order) {
|
||||
DBC.PRE.assertNotNull("order must not be null", order);
|
||||
getObjectFilter().update(Tags.ORDER, order);
|
||||
getObjectFilter().update(Tags.ORDER, order.getLocator(), order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Activity activity) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("activity must not be null", activity);
|
||||
getObjectFilter().update(Tags.ACTIVITY, activity);
|
||||
getObjectFilter().update(Tags.ACTIVITY, activity.getLocator(), activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Resource resource) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("resource must not be null", resource);
|
||||
getObjectFilter().remove(Tags.RESOURCE, resource);
|
||||
getObjectFilter().remove(Tags.RESOURCE, resource.getLocator(), resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Order order) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("order must not be null", order);
|
||||
getObjectFilter().remove(Tags.ORDER, order);
|
||||
getObjectFilter().remove(Tags.ORDER, order.getLocator(), order);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Activity activity) throws StrolchException {
|
||||
DBC.PRE.assertNotNull("activity must not be null", activity);
|
||||
getObjectFilter().remove(Tags.ACTIVITY, activity);
|
||||
getObjectFilter().remove(Tags.ACTIVITY, activity.getLocator(), activity);
|
||||
}
|
||||
|
||||
private void addModelChangeCommands() {
|
||||
|
@ -923,6 +964,9 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
try {
|
||||
this.txResult.setState(TransactionState.CLOSING);
|
||||
|
||||
Thread.currentThread().getUncaughtExceptionHandler();
|
||||
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
|
||||
|
||||
if (!this.commands.isEmpty()) {
|
||||
autoCloseableRollback();
|
||||
String msg = "There are commands registered on a read-only transaction. Changing to rollback! Did you forget to commit?";
|
||||
|
@ -943,6 +987,13 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
handleReadOnly(start, auditTrailDuration);
|
||||
this.txResult.setState(TransactionState.CLOSED);
|
||||
} catch (Exception e) {
|
||||
this.txResult.setState(TransactionState.ROLLING_BACK);
|
||||
try {
|
||||
undoCommands();
|
||||
rollback();
|
||||
} catch (Exception e1) {
|
||||
logger.error("Failed to rollback after exception", e);
|
||||
}
|
||||
handleFailure(start, e);
|
||||
this.txResult.setState(TransactionState.FAILED);
|
||||
} finally {
|
||||
|
@ -1062,7 +1113,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
logger.error(sb.toString());
|
||||
}
|
||||
|
||||
protected void handleFailure(long closeStartNanos, Exception e) {
|
||||
private void handleFailure(long closeStartNanos, Exception e) {
|
||||
|
||||
long end = System.nanoTime();
|
||||
long txDuration = end - this.txResult.getStartNanos();
|
||||
|
@ -1099,7 +1150,13 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
|
||||
String msg = "Strolch Transaction for realm {0} failed due to {1}\n{2}"; //$NON-NLS-1$
|
||||
msg = MessageFormat.format(msg, getRealmName(), ExceptionHelper.getExceptionMessage(e), sb.toString());
|
||||
throw new StrolchTransactionException(msg, e);
|
||||
StrolchTransactionException ex = new StrolchTransactionException(msg, e);
|
||||
|
||||
if (this.closeStrategy == TransactionCloseStrategy.COMMIT)
|
||||
throw ex;
|
||||
else
|
||||
logger.error("Transaction failed in non-commit mode! Logging TX exception, so exception is not suppressed.",
|
||||
ex);
|
||||
}
|
||||
|
||||
private boolean isAuditTrailEnabled() {
|
||||
|
@ -1116,36 +1173,35 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
|
||||
if (this.resourceMap != null) {
|
||||
if (!this.resourceMap.getCreated().isEmpty())
|
||||
event.added.addList(Tags.RESOURCE, new ArrayList<StrolchRootElement>(this.resourceMap.getCreated()));
|
||||
event.added.addList(Tags.RESOURCE, new ArrayList<>(this.resourceMap.getCreated()));
|
||||
if (!this.resourceMap.getUpdated().isEmpty())
|
||||
event.updated.addList(Tags.RESOURCE, new ArrayList<StrolchRootElement>(this.resourceMap.getUpdated()));
|
||||
event.updated.addList(Tags.RESOURCE, new ArrayList<>(this.resourceMap.getUpdated()));
|
||||
if (!this.resourceMap.getDeleted().isEmpty())
|
||||
event.removed.addList(Tags.RESOURCE, new ArrayList<StrolchRootElement>(this.resourceMap.getDeleted()));
|
||||
event.removed.addList(Tags.RESOURCE, new ArrayList<>(this.resourceMap.getDeleted()));
|
||||
}
|
||||
|
||||
if (this.orderMap != null) {
|
||||
if (!this.orderMap.getCreated().isEmpty())
|
||||
event.added.addList(Tags.ORDER, new ArrayList<StrolchRootElement>(this.orderMap.getCreated()));
|
||||
event.added.addList(Tags.ORDER, new ArrayList<>(this.orderMap.getCreated()));
|
||||
if (!this.orderMap.getUpdated().isEmpty())
|
||||
event.updated.addList(Tags.ORDER, new ArrayList<StrolchRootElement>(this.orderMap.getUpdated()));
|
||||
event.updated.addList(Tags.ORDER, new ArrayList<>(this.orderMap.getUpdated()));
|
||||
if (!this.orderMap.getDeleted().isEmpty())
|
||||
event.removed.addList(Tags.ORDER, new ArrayList<StrolchRootElement>(this.orderMap.getDeleted()));
|
||||
event.removed.addList(Tags.ORDER, new ArrayList<>(this.orderMap.getDeleted()));
|
||||
}
|
||||
|
||||
if (this.activityMap != null) {
|
||||
if (!this.activityMap.getCreated().isEmpty())
|
||||
event.added.addList(Tags.ACTIVITY, new ArrayList<StrolchRootElement>(this.activityMap.getCreated()));
|
||||
event.added.addList(Tags.ACTIVITY, new ArrayList<>(this.activityMap.getCreated()));
|
||||
if (!this.activityMap.getUpdated().isEmpty())
|
||||
event.updated.addList(Tags.ACTIVITY, new ArrayList<StrolchRootElement>(this.activityMap.getUpdated()));
|
||||
event.updated.addList(Tags.ACTIVITY, new ArrayList<>(this.activityMap.getUpdated()));
|
||||
if (!this.activityMap.getDeleted().isEmpty())
|
||||
event.removed.addList(Tags.ACTIVITY, new ArrayList<StrolchRootElement>(this.activityMap.getDeleted()));
|
||||
event.removed.addList(Tags.ACTIVITY, new ArrayList<>(this.activityMap.getDeleted()));
|
||||
}
|
||||
|
||||
ObserverHandler observerHandler = this.realm.getObserverHandler();
|
||||
observerHandler.notify(event);
|
||||
|
||||
long observerUpdateDuration = System.nanoTime() - observerUpdateStart;
|
||||
return observerUpdateDuration;
|
||||
return System.nanoTime() - observerUpdateStart;
|
||||
}
|
||||
|
||||
private boolean isObserverUpdatesEnabled() {
|
||||
|
@ -1166,26 +1222,26 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
|
||||
if (this.orderMap != null) {
|
||||
if (this.realm.isAuditTrailEnabledForRead())
|
||||
auditsFor(audits, AccessType.READ, Tags.ORDER, this.orderMap.getRead());
|
||||
auditsFor(audits, AccessType.CREATE, Tags.ORDER, this.orderMap.getCreated());
|
||||
auditsFor(audits, AccessType.UPDATE, Tags.ORDER, this.orderMap.getUpdated());
|
||||
auditsFor(audits, AccessType.DELETE, Tags.ORDER, this.orderMap.getDeleted());
|
||||
auditsFor(audits, AccessType.READ, this.orderMap.getRead());
|
||||
auditsFor(audits, AccessType.CREATE, this.orderMap.getCreated());
|
||||
auditsFor(audits, AccessType.UPDATE, this.orderMap.getUpdated());
|
||||
auditsFor(audits, AccessType.DELETE, this.orderMap.getDeleted());
|
||||
}
|
||||
|
||||
if (this.resourceMap != null) {
|
||||
if (this.realm.isAuditTrailEnabledForRead())
|
||||
auditsFor(audits, AccessType.READ, Tags.RESOURCE, this.resourceMap.getRead());
|
||||
auditsFor(audits, AccessType.CREATE, Tags.RESOURCE, this.resourceMap.getCreated());
|
||||
auditsFor(audits, AccessType.UPDATE, Tags.RESOURCE, this.resourceMap.getUpdated());
|
||||
auditsFor(audits, AccessType.DELETE, Tags.RESOURCE, this.resourceMap.getDeleted());
|
||||
auditsFor(audits, AccessType.READ, this.resourceMap.getRead());
|
||||
auditsFor(audits, AccessType.CREATE, this.resourceMap.getCreated());
|
||||
auditsFor(audits, AccessType.UPDATE, this.resourceMap.getUpdated());
|
||||
auditsFor(audits, AccessType.DELETE, this.resourceMap.getDeleted());
|
||||
}
|
||||
|
||||
if (this.activityMap != null) {
|
||||
if (this.realm.isAuditTrailEnabledForRead())
|
||||
auditsFor(audits, AccessType.READ, Tags.ACTIVITY, this.activityMap.getRead());
|
||||
auditsFor(audits, AccessType.CREATE, Tags.ACTIVITY, this.activityMap.getCreated());
|
||||
auditsFor(audits, AccessType.UPDATE, Tags.ACTIVITY, this.activityMap.getUpdated());
|
||||
auditsFor(audits, AccessType.DELETE, Tags.ACTIVITY, this.activityMap.getDeleted());
|
||||
auditsFor(audits, AccessType.READ, this.activityMap.getRead());
|
||||
auditsFor(audits, AccessType.CREATE, this.activityMap.getCreated());
|
||||
auditsFor(audits, AccessType.UPDATE, this.activityMap.getUpdated());
|
||||
auditsFor(audits, AccessType.DELETE, this.activityMap.getDeleted());
|
||||
}
|
||||
|
||||
if (this.auditTrail != null && !isSuppressAuditsForAudits()) {
|
||||
|
@ -1199,23 +1255,16 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
if (!audits.isEmpty())
|
||||
this.realm.getAuditTrail().addAll(this, audits);
|
||||
|
||||
long auditTrailDuration = System.nanoTime() - auditTrailStart;
|
||||
return auditTrailDuration;
|
||||
return System.nanoTime() - auditTrailStart;
|
||||
}
|
||||
|
||||
private <T extends StrolchRootElement> void auditsFor(List<Audit> audits,
|
||||
AccessType accessType,
|
||||
String elementType,
|
||||
Set<T> elements) {
|
||||
private <T extends StrolchRootElement> void auditsFor(List<Audit> audits, AccessType accessType, Set<T> elements) {
|
||||
for (StrolchRootElement element : elements) {
|
||||
audits.add(auditFrom(accessType, element));
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends StrolchRootElement> void auditsForAudits(List<Audit> audits,
|
||||
AccessType accessType,
|
||||
String elementType,
|
||||
Set<Audit> elements) {
|
||||
private void auditsForAudits(List<Audit> audits, AccessType accessType, String elementType, Set<Audit> elements) {
|
||||
for (Audit element : elements) {
|
||||
audits.add(auditFrom(accessType, elementType, StringHelper.DASH, element.getId().toString()));
|
||||
}
|
||||
|
@ -1223,7 +1272,7 @@ public abstract class AbstractTransaction implements StrolchTransaction {
|
|||
|
||||
@Override
|
||||
public Audit auditFrom(AccessType accessType, StrolchRootElement element) {
|
||||
String type = element.accept(new ElementTypeVisitor());
|
||||
String type = element.getObjectType();
|
||||
String subType = element.getType();
|
||||
String id = element.getId();
|
||||
return auditFrom(accessType, type, subType, id);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* Copyright 2015 Robert von Burg <eitch@eitchnet.ch>
|
||||
*
|
||||
* 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 li.strolch.service;
|
||||
|
||||
import static li.strolch.model.ModelGenerator.BAG_ID;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import li.strolch.agent.api.StrolchAgent;
|
||||
import li.strolch.model.ModelGenerator;
|
||||
import li.strolch.model.Order;
|
||||
import li.strolch.model.Resource;
|
||||
import li.strolch.model.activity.Activity;
|
||||
import li.strolch.model.activity.TimeOrdering;
|
||||
import li.strolch.model.parameter.StringListParameter;
|
||||
import li.strolch.model.parameter.StringParameter;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.runtime.StrolchConstants;
|
||||
import li.strolch.service.api.AbstractService;
|
||||
import li.strolch.service.api.ServiceArgument;
|
||||
import li.strolch.service.api.ServiceResult;
|
||||
import li.strolch.service.test.AbstractRealmServiceTest;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TxExtendedTest extends AbstractRealmServiceTest {
|
||||
|
||||
@Test
|
||||
public void shouldCommit() {
|
||||
|
||||
runServiceInAllRealmTypes(CommitService.class, new ServiceArgument());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRollback() {
|
||||
|
||||
runServiceInAllRealmTypes(RollbackService.class, new ServiceArgument());
|
||||
}
|
||||
|
||||
public static class CommitService extends AbstractService<ServiceArgument, ServiceResult> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected ServiceResult getResultInstance() {
|
||||
return new ServiceResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceArgument getArgumentInstance() {
|
||||
return new ServiceArgument();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServiceResult internalDoService(ServiceArgument arg) throws Exception {
|
||||
|
||||
String type = "MyType";
|
||||
|
||||
String resId = StrolchAgent.getUniqueId();
|
||||
Resource resource = ModelGenerator.createResource(resId, resId, type);
|
||||
Resource resource1 = ModelGenerator.createResource(resId + "1", resId + "1", type);
|
||||
Resource resource2 = ModelGenerator.createResource(resId + "2", resId + "2", type);
|
||||
Resource resource3 = ModelGenerator.createResource(resId + "3", resId + "3", type);
|
||||
StringListParameter resRefsP = new StringListParameter("refP", "Ref P",
|
||||
Arrays.asList(resource1.getId(), resource2.getId(), resource3.getId()));
|
||||
resRefsP.setInterpretation(StrolchConstants.INTERPRETATION_RESOURCE_REF);
|
||||
resRefsP.setUom(type);
|
||||
resource.addParameter(BAG_ID, resRefsP);
|
||||
|
||||
StringParameter resRefP = new StringParameter("refP", "Ref P", resource.getId());
|
||||
resRefP.setInterpretation(StrolchConstants.INTERPRETATION_RESOURCE_REF);
|
||||
resRefP.setUom(type);
|
||||
resource1.addParameter(BAG_ID, resRefP.getClone());
|
||||
resource2.addParameter(BAG_ID, resRefP.getClone());
|
||||
resource3.addParameter(BAG_ID, resRefP.getClone());
|
||||
|
||||
String orderId = StrolchAgent.getUniqueId();
|
||||
Order order = ModelGenerator.createOrder(orderId, orderId, type);
|
||||
Order order1 = ModelGenerator.createOrder(orderId + "1", orderId + "1", type);
|
||||
Order order2 = ModelGenerator.createOrder(orderId + "2", orderId + "2", type);
|
||||
Order order3 = ModelGenerator.createOrder(orderId + "3", orderId + "3", type);
|
||||
StringListParameter orderRefsP = new StringListParameter("refP", "Ref P",
|
||||
Arrays.asList(order1.getId(), order2.getId(), order3.getId()));
|
||||
orderRefsP.setInterpretation(StrolchConstants.INTERPRETATION_ORDER_REF);
|
||||
orderRefsP.setUom(type);
|
||||
order.addParameter(BAG_ID, orderRefsP);
|
||||
|
||||
StringParameter orderRefP = new StringParameter("refP", "Ref P", order.getId());
|
||||
orderRefP.setInterpretation(StrolchConstants.INTERPRETATION_ORDER_REF);
|
||||
orderRefP.setUom(type);
|
||||
order1.addParameter(BAG_ID, orderRefP.getClone());
|
||||
order2.addParameter(BAG_ID, orderRefP.getClone());
|
||||
order3.addParameter(BAG_ID, orderRefP.getClone());
|
||||
|
||||
String activityId = StrolchAgent.getUniqueId();
|
||||
Activity activity = ModelGenerator.createActivity(activityId, activityId, type, TimeOrdering.SERIES);
|
||||
Activity activity1 = ModelGenerator
|
||||
.createActivity(activityId + "1", activityId + "1", type, TimeOrdering.SERIES);
|
||||
Activity activity2 = ModelGenerator
|
||||
.createActivity(activityId + "2", activityId + "2", type, TimeOrdering.SERIES);
|
||||
Activity activity3 = ModelGenerator
|
||||
.createActivity(activityId + "3", activityId + "3", type, TimeOrdering.SERIES);
|
||||
StringListParameter actRefsP = new StringListParameter("refP", "Ref P",
|
||||
Arrays.asList(activity1.getId(), activity2.getId(), activity3.getId()));
|
||||
actRefsP.setInterpretation(StrolchConstants.INTERPRETATION_ACTIVITY_REF);
|
||||
actRefsP.setUom(type);
|
||||
activity.addParameter(BAG_ID, actRefsP);
|
||||
|
||||
StringParameter actRefP = new StringParameter("refP", "Ref P", activity.getId());
|
||||
actRefP.setInterpretation(StrolchConstants.INTERPRETATION_ACTIVITY_REF);
|
||||
actRefP.setUom(type);
|
||||
activity1.addParameter(BAG_ID, actRefP.getClone());
|
||||
activity2.addParameter(BAG_ID, actRefP.getClone());
|
||||
activity3.addParameter(BAG_ID, actRefP.getClone());
|
||||
|
||||
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||
|
||||
// resource
|
||||
assertNull(tx.getResourceBy(type, resId));
|
||||
assertFalse(tx.hasResource(type, resId));
|
||||
assertEquals(0, tx.getResourcesBy(resRefsP).size());
|
||||
tx.add(resource);
|
||||
tx.add(resource1);
|
||||
tx.add(resource2);
|
||||
tx.add(resource3);
|
||||
tx.update(resource3);
|
||||
assertNotNull(tx.getResourceBy(type, resId));
|
||||
assertTrue(tx.hasResource(type, resId));
|
||||
List<Resource> resourcesBy = tx.getResourcesBy(resRefsP);
|
||||
assertEquals(3, resourcesBy.size());
|
||||
for (Resource res : resourcesBy) {
|
||||
assertEquals(resource, tx.getResourceBy(res.getParameter(BAG_ID, "refP")));
|
||||
}
|
||||
|
||||
// order
|
||||
assertNull(tx.getOrderBy(type, orderId));
|
||||
assertFalse(tx.hasOrder(type, orderId));
|
||||
assertEquals(0, tx.getOrdersBy(orderRefsP).size());
|
||||
tx.add(order);
|
||||
tx.add(order1);
|
||||
tx.add(order2);
|
||||
tx.add(order3);
|
||||
tx.update(order3);
|
||||
assertNotNull(tx.getOrderBy(type, orderId));
|
||||
assertTrue(tx.hasOrder(type, orderId));
|
||||
List<Order> ordersBy = tx.getOrdersBy(orderRefsP);
|
||||
assertEquals(3, ordersBy.size());
|
||||
for (Order o : ordersBy) {
|
||||
assertEquals(order, tx.getOrderBy(o.getParameter(BAG_ID, "refP")));
|
||||
}
|
||||
|
||||
// activity
|
||||
assertNull(tx.getActivityBy(type, activityId));
|
||||
assertFalse(tx.hasActivity(type, activityId));
|
||||
assertEquals(0, tx.getActivitiesBy(actRefsP).size());
|
||||
tx.add(activity);
|
||||
tx.add(activity1);
|
||||
tx.add(activity2);
|
||||
tx.add(activity3);
|
||||
tx.update(activity3);
|
||||
assertNotNull(tx.getActivityBy(type, activityId));
|
||||
assertTrue(tx.hasActivity(type, activityId));
|
||||
List<Activity> activitiesBy = tx.getActivitiesBy(actRefsP);
|
||||
assertEquals(3, activitiesBy.size());
|
||||
for (Activity a : activitiesBy) {
|
||||
assertEquals(activity, tx.getActivityBy(a.getParameter(BAG_ID, "refP")));
|
||||
}
|
||||
|
||||
tx.commitOnClose();
|
||||
}
|
||||
|
||||
// now make sure the new resource exists
|
||||
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||
|
||||
assertNotNull(tx.getResourceBy(type, resource.getId()));
|
||||
assertNotNull(tx.getOrderBy(type, order.getId()));
|
||||
assertNotNull(tx.getActivityBy(type, activity.getId()));
|
||||
}
|
||||
|
||||
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||
tx.remove(resource);
|
||||
tx.remove(order);
|
||||
tx.remove(activity);
|
||||
|
||||
tx.commitOnClose();
|
||||
}
|
||||
|
||||
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||
|
||||
assertNull(tx.getResourceBy(type, resource.getId()));
|
||||
assertNull(tx.getOrderBy(type, order.getId()));
|
||||
assertNull(tx.getActivityBy(type, activity.getId()));
|
||||
|
||||
}
|
||||
|
||||
return ServiceResult.success();
|
||||
}
|
||||
}
|
||||
|
||||
public static class RollbackService extends AbstractService<ServiceArgument, ServiceResult> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected ServiceResult getResultInstance() {
|
||||
return new ServiceResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceArgument getArgumentInstance() {
|
||||
return new ServiceArgument();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServiceResult internalDoService(ServiceArgument arg) throws Exception {
|
||||
|
||||
String type = "MyType";
|
||||
|
||||
String resId = StrolchAgent.getUniqueId();
|
||||
Resource resource = ModelGenerator.createResource(resId, resId, type);
|
||||
Resource resource1 = ModelGenerator.createResource(resId + "1", resId + "1", type);
|
||||
Resource resource2 = ModelGenerator.createResource(resId + "2", resId + "2", type);
|
||||
Resource resource3 = ModelGenerator.createResource(resId + "3", resId + "3", type);
|
||||
StringListParameter resRefP = new StringListParameter("refP", "Ref P",
|
||||
Arrays.asList(resource1.getId(), resource2.getId(), resource3.getId()));
|
||||
resRefP.setInterpretation(StrolchConstants.INTERPRETATION_RESOURCE_REF);
|
||||
resRefP.setUom(type);
|
||||
resource.addParameter(BAG_ID, resRefP);
|
||||
|
||||
String orderId = StrolchAgent.getUniqueId();
|
||||
Order order = ModelGenerator.createOrder(orderId, orderId, type);
|
||||
Order order1 = ModelGenerator.createOrder(orderId + "1", orderId + "1", type);
|
||||
Order order2 = ModelGenerator.createOrder(orderId + "2", orderId + "2", type);
|
||||
Order order3 = ModelGenerator.createOrder(orderId + "3", orderId + "3", type);
|
||||
StringListParameter orderRefP = new StringListParameter("refP", "Ref P",
|
||||
Arrays.asList(order1.getId(), order2.getId(), order3.getId()));
|
||||
orderRefP.setInterpretation(StrolchConstants.INTERPRETATION_ORDER_REF);
|
||||
orderRefP.setUom(type);
|
||||
order.addParameter(BAG_ID, orderRefP);
|
||||
|
||||
String activityId = StrolchAgent.getUniqueId();
|
||||
Activity activity = ModelGenerator.createActivity(activityId, activityId, type, TimeOrdering.SERIES);
|
||||
Activity activity1 = ModelGenerator
|
||||
.createActivity(activityId + "1", activityId + "1", type, TimeOrdering.SERIES);
|
||||
Activity activity2 = ModelGenerator
|
||||
.createActivity(activityId + "2", activityId + "2", type, TimeOrdering.SERIES);
|
||||
Activity activity3 = ModelGenerator
|
||||
.createActivity(activityId + "3", activityId + "3", type, TimeOrdering.SERIES);
|
||||
StringListParameter actRefP = new StringListParameter("refP", "Ref P",
|
||||
Arrays.asList(activity1.getId(), activity2.getId(), activity3.getId()));
|
||||
actRefP.setInterpretation(StrolchConstants.INTERPRETATION_ACTIVITY_REF);
|
||||
actRefP.setUom(type);
|
||||
activity.addParameter(BAG_ID, actRefP);
|
||||
|
||||
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||
|
||||
// resource
|
||||
assertNull(tx.getResourceBy(type, resId));
|
||||
assertFalse(tx.hasResource(type, resId));
|
||||
assertEquals(0, tx.getResourcesBy(resRefP).size());
|
||||
tx.add(resource);
|
||||
tx.add(resource1);
|
||||
tx.add(resource2);
|
||||
tx.add(resource3);
|
||||
assertNotNull(tx.getResourceBy(type, resId));
|
||||
assertTrue(tx.hasResource(type, resId));
|
||||
assertEquals(3, tx.getResourcesBy(resRefP).size());
|
||||
|
||||
// order
|
||||
assertNull(tx.getOrderBy(type, orderId));
|
||||
assertFalse(tx.hasOrder(type, orderId));
|
||||
assertEquals(0, tx.getOrdersBy(orderRefP).size());
|
||||
tx.add(order);
|
||||
tx.add(order1);
|
||||
tx.add(order2);
|
||||
tx.add(order3);
|
||||
assertNotNull(tx.getOrderBy(type, orderId));
|
||||
assertTrue(tx.hasOrder(type, orderId));
|
||||
assertEquals(3, tx.getOrdersBy(orderRefP).size());
|
||||
|
||||
// activity
|
||||
assertNull(tx.getActivityBy(type, activityId));
|
||||
assertFalse(tx.hasActivity(type, activityId));
|
||||
assertEquals(0, tx.getActivitiesBy(actRefP).size());
|
||||
tx.add(activity);
|
||||
tx.add(activity1);
|
||||
tx.add(activity2);
|
||||
tx.add(activity3);
|
||||
assertNotNull(tx.getActivityBy(type, activityId));
|
||||
assertTrue(tx.hasActivity(type, activityId));
|
||||
assertEquals(3, tx.getActivitiesBy(actRefP).size());
|
||||
|
||||
tx.rollbackOnClose();
|
||||
}
|
||||
|
||||
// now make sure the new resource does not exist
|
||||
try (StrolchTransaction tx = openTx(arg.realm)) {
|
||||
|
||||
assertNull(tx.getResourceBy(type, resource.getId()));
|
||||
assertNull(tx.getResourceBy(type, resource1.getId()));
|
||||
assertNull(tx.getResourceBy(type, resource2.getId()));
|
||||
assertNull(tx.getResourceBy(type, resource3.getId()));
|
||||
assertNull(tx.getOrderBy(type, order.getId()));
|
||||
assertNull(tx.getOrderBy(type, order1.getId()));
|
||||
assertNull(tx.getOrderBy(type, order2.getId()));
|
||||
assertNull(tx.getOrderBy(type, order3.getId()));
|
||||
assertNull(tx.getActivityBy(type, activity.getId()));
|
||||
assertNull(tx.getActivityBy(type, activity1.getId()));
|
||||
assertNull(tx.getActivityBy(type, activity2.getId()));
|
||||
assertNull(tx.getActivityBy(type, activity3.getId()));
|
||||
}
|
||||
|
||||
return ServiceResult.success();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,9 +18,6 @@ package li.strolch.service;
|
|||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import li.strolch.model.ModelGenerator;
|
||||
import li.strolch.model.Order;
|
||||
import li.strolch.model.Resource;
|
||||
|
@ -31,6 +28,7 @@ import li.strolch.service.api.ServiceArgument;
|
|||
import li.strolch.service.api.ServiceResult;
|
||||
import li.strolch.service.test.AbstractRealmServiceTest;
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TxTest extends AbstractRealmServiceTest {
|
||||
|
||||
|
@ -53,7 +51,6 @@ public class TxTest extends AbstractRealmServiceTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore("We have to re-think this. It does not work, throwing an exception if commands are registered on a read-only TX as then we don't know if we want to roll back or not - we probably need a ROLLBACK_ON_ERROR or something")
|
||||
public void shouldNotAllowCommandsOnDoNothing() {
|
||||
|
||||
runServiceInAllRealmTypes(ReadonlyFailService.class, new ServiceArgument());
|
||||
|
|
|
@ -27,28 +27,27 @@ import java.util.Set;
|
|||
* <p>
|
||||
* Collection to store a tree with a depth of 3 elements. This solves having to always write the declaration:
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <pre>
|
||||
* Map<String, Map<String, MyObject>> mapOfMaps = new HashMap<>;
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* <p>
|
||||
* As an example to persist a map of MyObject where the branches are String one would write it as follows:
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* <pre>
|
||||
* MapOfMaps<String, String, MyObject> mapOfMaps = new MapOfMaps<>();
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*
|
||||
*
|
||||
* @param <T>
|
||||
* The key to a map with U as the key and V as the value
|
||||
* The key to a map with U as the key and V as the value
|
||||
* @param <U>
|
||||
* The key to get a value (leaf)
|
||||
* The key to get a value (leaf)
|
||||
* @param <V>
|
||||
* The value stored in the tree (leaf)
|
||||
* The value stored in the tree (leaf)
|
||||
*
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class MapOfMaps<T, U, V> {
|
||||
|
||||
|
@ -58,6 +57,10 @@ public class MapOfMaps<T, U, V> {
|
|||
this.mapOfMaps = new HashMap<>();
|
||||
}
|
||||
|
||||
public MapOfMaps(int initialSize) {
|
||||
this.mapOfMaps = new HashMap<>(initialSize);
|
||||
}
|
||||
|
||||
public Set<T> keySet() {
|
||||
return this.mapOfMaps.keySet();
|
||||
}
|
||||
|
@ -74,11 +77,7 @@ public class MapOfMaps<T, U, V> {
|
|||
}
|
||||
|
||||
public V addElement(T t, U u, V v) {
|
||||
Map<U, V> map = this.mapOfMaps.get(t);
|
||||
if (map == null) {
|
||||
map = new HashMap<>();
|
||||
this.mapOfMaps.put(t, map);
|
||||
}
|
||||
Map<U, V> map = this.mapOfMaps.computeIfAbsent(t, k -> new HashMap<>());
|
||||
return map.put(u, v);
|
||||
}
|
||||
|
||||
|
@ -100,11 +99,7 @@ public class MapOfMaps<T, U, V> {
|
|||
}
|
||||
|
||||
public void addMap(T t, Map<U, V> u) {
|
||||
Map<U, V> map = this.mapOfMaps.get(t);
|
||||
if (map == null) {
|
||||
map = new HashMap<>();
|
||||
this.mapOfMaps.put(t, map);
|
||||
}
|
||||
Map<U, V> map = this.mapOfMaps.computeIfAbsent(t, k -> new HashMap<>());
|
||||
map.putAll(u);
|
||||
}
|
||||
|
||||
|
@ -140,9 +135,7 @@ public class MapOfMaps<T, U, V> {
|
|||
|
||||
public boolean containsElement(T t, U u) {
|
||||
Map<U, V> map = this.mapOfMaps.get(t);
|
||||
if (map == null)
|
||||
return false;
|
||||
return map.containsKey(u);
|
||||
return map != null && map.containsKey(u);
|
||||
}
|
||||
|
||||
public int sizeKeys() {
|
||||
|
@ -152,9 +145,8 @@ public class MapOfMaps<T, U, V> {
|
|||
public int size() {
|
||||
int size = 0;
|
||||
Set<Entry<T, Map<U, V>>> entrySet = this.mapOfMaps.entrySet();
|
||||
Iterator<Entry<T, Map<U, V>>> iter = entrySet.iterator();
|
||||
while (iter.hasNext()) {
|
||||
size += iter.next().getValue().size();
|
||||
for (Entry<T, Map<U, V>> anEntrySet : entrySet) {
|
||||
size += anEntrySet.getValue().size();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
|
|||
* <li>A reference to the current state of the object</li>
|
||||
* <li>An identifier of the operation that needs to be performed on this</li>
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @author Michael Gatto <michael@gatto.ch>
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
|
@ -60,16 +60,22 @@ public class ObjectCache {
|
|||
*/
|
||||
private Operation operation;
|
||||
|
||||
/**
|
||||
* object The objectKey that shall be cached
|
||||
*/
|
||||
private Object objectKey;
|
||||
|
||||
/**
|
||||
* object The object that shall be cached
|
||||
*/
|
||||
private Object object;
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
public ObjectCache(long id, String key, Object object, Operation operation) {
|
||||
public ObjectCache(long id, String key, Object objectKey, Object object, Operation operation) {
|
||||
|
||||
this.id = id;
|
||||
this.key = key;
|
||||
this.objectKey = objectKey;
|
||||
this.object = object;
|
||||
this.operation = operation;
|
||||
|
||||
|
@ -82,29 +88,30 @@ public class ObjectCache {
|
|||
sb.append(" OP: ");
|
||||
sb.append(this.operation);
|
||||
sb.append(" / ");
|
||||
sb.append(object.toString());
|
||||
sb.append(objectKey.toString());
|
||||
logger.debug(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the new object version of this cache.
|
||||
*
|
||||
*
|
||||
* @param object
|
||||
* the object to set
|
||||
* the object to set
|
||||
*/
|
||||
public void setObject(Object object) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(MessageFormat.format("Updating ID {0} to value {1}", this.id, object.toString())); //$NON-NLS-1$
|
||||
logger.debug(
|
||||
MessageFormat.format("Updating ID {0} to value {1}", this.id, object.toString())); //$NON-NLS-1$
|
||||
}
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the operation to execute for this object.
|
||||
*
|
||||
*
|
||||
* @param newOperation
|
||||
* the operation to set
|
||||
* the operation to set
|
||||
*/
|
||||
public void setOperation(Operation newOperation) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
@ -115,30 +122,22 @@ public class ObjectCache {
|
|||
this.operation = newOperation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the key
|
||||
*/
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the operation
|
||||
*/
|
||||
public Operation getOperation() {
|
||||
return this.operation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the object
|
||||
*/
|
||||
public Object getObjectKey() {
|
||||
return objectKey;
|
||||
}
|
||||
|
||||
public Object getObject() {
|
||||
return this.object;
|
||||
}
|
||||
|
|
|
@ -16,14 +16,9 @@
|
|||
package li.strolch.utils.objectfilter;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import li.strolch.utils.collections.MapOfMaps;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -71,7 +66,7 @@ import org.slf4j.LoggerFactory;
|
|||
* <td>Err!</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
*
|
||||
* @author Michael Gatto <michael@gatto.ch> (initial version)
|
||||
* @author Robert von Burg <eitch@eitchnet.ch> (minor modifications, refactorings)
|
||||
*/
|
||||
|
@ -81,17 +76,29 @@ public class ObjectFilter {
|
|||
|
||||
private static long id = ObjectCache.UNSET;
|
||||
|
||||
private final Map<Object, ObjectCache> cache;
|
||||
private final MapOfMaps<String, Object, ObjectCache> cache;
|
||||
private final Set<String> keySet;
|
||||
|
||||
/**
|
||||
* Default constructor initializing the filter
|
||||
*/
|
||||
public ObjectFilter() {
|
||||
this.cache = new HashMap<>(1);
|
||||
this.cache = new MapOfMaps<>(1);
|
||||
this.keySet = new HashSet<>(1);
|
||||
}
|
||||
|
||||
private void replaceKey(ObjectCache cached, Object newObjectKey, Object newObject) {
|
||||
if (cached.getObjectKey() != newObjectKey) {
|
||||
if (ObjectFilter.logger.isDebugEnabled()) {
|
||||
String msg = "Replacing key for object as they are not the same reference: old: {0} / new: {1}"; //$NON-NLS-1$
|
||||
msg = MessageFormat.format(msg, cached.getObjectKey(), newObjectKey);
|
||||
ObjectFilter.logger.warn(msg);
|
||||
}
|
||||
ObjectCache objectCache = this.cache.removeElement(cached.getKey(), cached.getObjectKey());
|
||||
this.cache.addElement(objectCache.getKey(), newObjectKey, objectCache);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register, under the given key, the addition of the given object.
|
||||
* <p>
|
||||
|
@ -112,33 +119,37 @@ public class ObjectFilter {
|
|||
* <td>Update(O2)</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* the key to register the object with
|
||||
* the key to register the object with
|
||||
* @param objectKey
|
||||
* 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 objectToAdd) {
|
||||
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.get(objectToAdd);
|
||||
ObjectCache cached = this.cache.getElement(key, objectKey);
|
||||
if (cached == null) {
|
||||
|
||||
// The object has not yet been added to the cache.
|
||||
// Hence, we add it now, with the ADD operation.
|
||||
ObjectCache cacheObj = new ObjectCache(dispenseID(), key, objectToAdd, Operation.ADD);
|
||||
this.cache.put(objectToAdd, cacheObj);
|
||||
ObjectCache cacheObj = new ObjectCache(dispenseID(), key, objectKey, objectToAdd, Operation.ADD);
|
||||
this.cache.addElement(key, objectKey, cacheObj);
|
||||
|
||||
} 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.ADD.toString(), existingKey, key, objectToAdd.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
|
||||
|
@ -151,7 +162,7 @@ public class ObjectFilter {
|
|||
throw new IllegalStateException("Stale State exception: Invalid + after +="); //$NON-NLS-1$
|
||||
case REMOVE:
|
||||
// replace key if necessary
|
||||
replaceKey(cached.getObject(), objectToAdd);
|
||||
replaceKey(cached, objectKey, objectToAdd);
|
||||
|
||||
// update operation's object
|
||||
cached.setObject(objectToAdd);
|
||||
|
@ -166,18 +177,6 @@ public class ObjectFilter {
|
|||
this.keySet.add(key);
|
||||
}
|
||||
|
||||
private void replaceKey(Object oldObject, Object newObject) {
|
||||
if (oldObject != newObject) {
|
||||
if (ObjectFilter.logger.isDebugEnabled()) {
|
||||
String msg = "Replacing key for object as they are not the same reference: old: {0} / new: {1}"; //$NON-NLS-1$
|
||||
msg = MessageFormat.format(msg, oldObject, newObject);
|
||||
ObjectFilter.logger.warn(msg);
|
||||
}
|
||||
ObjectCache objectCache = this.cache.remove(oldObject);
|
||||
this.cache.put(newObject, objectCache);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register, under the given key, the update of the given object. *
|
||||
* </p>
|
||||
|
@ -197,33 +196,37 @@ public class ObjectFilter {
|
|||
* <td>Err!</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* the key to register the object with
|
||||
* the key to register the object with
|
||||
* @param objectKey
|
||||
* 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 objectToUpdate) {
|
||||
public void update(String key, Object objectKey, Object objectToUpdate) {
|
||||
|
||||
if (ObjectFilter.logger.isDebugEnabled())
|
||||
ObjectFilter.logger.debug(MessageFormat.format("update object {0} with key {1}", objectToUpdate, 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.get(objectToUpdate);
|
||||
ObjectCache cached = this.cache.getElement(key, objectKey);
|
||||
if (cached == null) {
|
||||
|
||||
// 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, objectToUpdate, Operation.MODIFY);
|
||||
this.cache.put(objectToUpdate, cacheObj);
|
||||
ObjectCache cacheObj = new ObjectCache(dispenseID(), key, objectKey, objectToUpdate, Operation.MODIFY);
|
||||
this.cache.addElement(key, objectKey, cacheObj);
|
||||
|
||||
} 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()));
|
||||
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.
|
||||
|
@ -232,7 +235,7 @@ public class ObjectFilter {
|
|||
case ADD:
|
||||
case MODIFY:
|
||||
// replace key if necessary
|
||||
replaceKey(cached.getObject(), objectToUpdate);
|
||||
replaceKey(cached, objectKey, objectToUpdate);
|
||||
|
||||
// update operation's object
|
||||
cached.setObject(objectToUpdate);
|
||||
|
@ -267,31 +270,35 @@ public class ObjectFilter {
|
|||
* <td>Err!</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
*
|
||||
* @param key
|
||||
* the key to register the object with
|
||||
* the key to register the object with
|
||||
* @param objectKey
|
||||
* 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 objectToRemove) {
|
||||
public void remove(String key, Object objectKey, Object objectToRemove) {
|
||||
|
||||
if (ObjectFilter.logger.isDebugEnabled())
|
||||
ObjectFilter.logger.debug(MessageFormat.format("remove object {0} with key {1}", objectToRemove, 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.get(objectToRemove);
|
||||
ObjectCache cached = this.cache.getElement(key, objectKey);
|
||||
if (cached == null) {
|
||||
// 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, objectToRemove, Operation.REMOVE);
|
||||
this.cache.put(objectToRemove, cacheObj);
|
||||
ObjectCache cacheObj = new ObjectCache(dispenseID(), key, objectKey, objectToRemove, Operation.REMOVE);
|
||||
this.cache.addElement(key, objectKey, cacheObj);
|
||||
} 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.REMOVE.toString(), existingKey, key, objectToRemove.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.
|
||||
|
@ -300,11 +307,11 @@ public class ObjectFilter {
|
|||
case ADD:
|
||||
// this is a case where we're removing the object from the cache, since we are
|
||||
// removing it now and it was added previously.
|
||||
this.cache.remove(objectToRemove);
|
||||
this.cache.removeElement(key, objectKey);
|
||||
break;
|
||||
case MODIFY:
|
||||
// replace key if necessary
|
||||
replaceKey(cached.getObject(), objectToRemove);
|
||||
replaceKey(cached, objectKey, objectToRemove);
|
||||
|
||||
// update operation's object
|
||||
cached.setObject(objectToRemove);
|
||||
|
@ -322,129 +329,133 @@ public class ObjectFilter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Register, under the given key, the addition of the given list of objects.
|
||||
*
|
||||
* @param key
|
||||
* the key to register the objects with
|
||||
* @param addedObjects
|
||||
* The objects for which addition shall be registered.
|
||||
* 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
|
||||
*/
|
||||
public void addAll(String key, Collection<Object> addedObjects) {
|
||||
for (Object addObj : addedObjects) {
|
||||
add(key, addObj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register, under the given key, the update of the given list of objects.
|
||||
*
|
||||
* @param key
|
||||
* the key to register the objects with
|
||||
* @param updatedObjects
|
||||
* The objects for which update shall be registered.
|
||||
*/
|
||||
public void updateAll(String key, Collection<Object> updatedObjects) {
|
||||
for (Object update : updatedObjects) {
|
||||
update(key, update);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register, under the given key, the removal of the given list of objects.
|
||||
*
|
||||
* @param key
|
||||
* the key to register the objects with
|
||||
* @param removedObjects
|
||||
* The objects for which removal shall be registered.
|
||||
*/
|
||||
public void removeAll(String key, Collection<Object> removedObjects) {
|
||||
for (Object removed : removedObjects) {
|
||||
remove(key, removed);
|
||||
}
|
||||
public void add(Object object) {
|
||||
add(object.getClass().getName(), object, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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);
|
||||
public void add(Object objectKey, Object object) {
|
||||
add(object.getClass().getName(), objectKey, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
update(object.getClass().getName(), object, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param object
|
||||
* The object that shall be registered for updating
|
||||
*/
|
||||
public void update(Object objectKey, Object object) {
|
||||
update(object.getClass().getName(), objectKey, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
remove(object.getClass().getName(), object, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the addition of all objects in the list. Since no key is provided, the class name of each object is used
|
||||
* as a key.
|
||||
*
|
||||
* @param objects
|
||||
* The objects that shall be registered for addition
|
||||
* 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
|
||||
* @param object
|
||||
* The object that shall be registered for removal
|
||||
*/
|
||||
public void addAll(List<Object> objects) {
|
||||
for (Object addedObj : objects) {
|
||||
add(addedObj.getClass().getName(), addedObj);
|
||||
}
|
||||
public void remove(Object objectKey, Object object) {
|
||||
remove(object.getClass().getName(), objectKey, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the updating of all objects in the list. Since no key is provided, the class name of each object is used
|
||||
* as a key.
|
||||
*
|
||||
* @param updateObjects
|
||||
* The objects that shall be registered for updating
|
||||
* Returns the ObjectCache for the given key and objectKey
|
||||
*
|
||||
* @param key
|
||||
* the key under which it was registered
|
||||
* @param objectKey
|
||||
* the objectKey
|
||||
*
|
||||
* @return the ObjectCache, or null
|
||||
*/
|
||||
public void updateAll(List<Object> updateObjects) {
|
||||
for (Object update : updateObjects) {
|
||||
update(update.getClass().getName(), update);
|
||||
}
|
||||
public ObjectCache getCache(String key, Object objectKey) {
|
||||
return this.cache.getElement(key, objectKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the removal of all objects in the list. Since no key is provided, the class name of each object is used
|
||||
* as a key.
|
||||
*
|
||||
* @param removedObjects
|
||||
* The objects that shall be registered for removal
|
||||
* Returns the element with the given key and objectKey
|
||||
*
|
||||
* @param key
|
||||
* the key under which it was registered
|
||||
* @param objectKey
|
||||
* the objectKey
|
||||
* @param <V>
|
||||
* the class to which to cast the element to
|
||||
*
|
||||
* @return the element, or null
|
||||
*/
|
||||
public void removeAll(List<Object> removedObjects) {
|
||||
for (Object removed : removedObjects) {
|
||||
remove(removed.getClass().getName(), removed);
|
||||
}
|
||||
public <V> V getElement(String key, Object objectKey) {
|
||||
ObjectCache cache = this.cache.getElement(key, objectKey);
|
||||
if (cache == null)
|
||||
return null;
|
||||
@SuppressWarnings("unchecked")
|
||||
V element = (V) cache.getObject();
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the element with the given key and objectKey exist
|
||||
*
|
||||
* @param key
|
||||
* the key under which it was registered
|
||||
* @param objectKey
|
||||
* the objectKey
|
||||
*
|
||||
* @return true if the element with the given key and objectKey exist
|
||||
*/
|
||||
public boolean hasElement(String key, Object objectKey) {
|
||||
return this.cache.containsElement(key, objectKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public List<Object> getAdded(String key) {
|
||||
List<Object> addedObjects = new LinkedList<>();
|
||||
Collection<ObjectCache> allObjs = this.cache.values();
|
||||
List<ObjectCache> allObjs = this.cache.getAllElements(key);
|
||||
for (ObjectCache objectCache : allObjs) {
|
||||
if (objectCache.getOperation() == Operation.ADD && (objectCache.getKey().equals(key))) {
|
||||
if (objectCache.getOperation() == Operation.ADD) {
|
||||
addedObjects.add(objectCache.getObject());
|
||||
}
|
||||
}
|
||||
|
@ -453,19 +464,19 @@ 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.
|
||||
*/
|
||||
public <V extends Object> List<V> getAdded(Class<V> clazz, String key) {
|
||||
public <V> List<V> getAdded(Class<V> clazz, String key) {
|
||||
List<V> addedObjects = new LinkedList<>();
|
||||
Collection<ObjectCache> allObjs = this.cache.values();
|
||||
List<ObjectCache> allObjs = this.cache.getAllElements(key);
|
||||
for (ObjectCache objectCache : allObjs) {
|
||||
if (objectCache.getOperation() == Operation.ADD && (objectCache.getKey().equals(key))) {
|
||||
if (objectCache.getOperation() == Operation.ADD) {
|
||||
if (objectCache.getObject().getClass() == clazz) {
|
||||
@SuppressWarnings("unchecked")
|
||||
V object = (V) objectCache.getObject();
|
||||
|
@ -478,17 +489,17 @@ 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.
|
||||
*/
|
||||
public List<Object> getUpdated(String key) {
|
||||
List<Object> updatedObjects = new LinkedList<>();
|
||||
Collection<ObjectCache> allObjs = this.cache.values();
|
||||
List<ObjectCache> allObjs = this.cache.getAllElements(key);
|
||||
for (ObjectCache objectCache : allObjs) {
|
||||
if (objectCache.getOperation() == Operation.MODIFY && (objectCache.getKey().equals(key))) {
|
||||
if (objectCache.getOperation() == Operation.MODIFY) {
|
||||
updatedObjects.add(objectCache.getObject());
|
||||
}
|
||||
}
|
||||
|
@ -497,19 +508,19 @@ 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.
|
||||
*/
|
||||
public <V extends Object> List<V> getUpdated(Class<V> clazz, String key) {
|
||||
public <V> List<V> getUpdated(Class<V> clazz, String key) {
|
||||
List<V> updatedObjects = new LinkedList<>();
|
||||
Collection<ObjectCache> allObjs = this.cache.values();
|
||||
List<ObjectCache> allObjs = this.cache.getAllElements(key);
|
||||
for (ObjectCache objectCache : allObjs) {
|
||||
if (objectCache.getOperation() == Operation.MODIFY && (objectCache.getKey().equals(key))) {
|
||||
if (objectCache.getOperation() == Operation.MODIFY) {
|
||||
if (objectCache.getObject().getClass() == clazz) {
|
||||
@SuppressWarnings("unchecked")
|
||||
V object = (V) objectCache.getObject();
|
||||
|
@ -522,17 +533,17 @@ 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.
|
||||
*/
|
||||
public List<Object> getRemoved(String key) {
|
||||
List<Object> removedObjects = new LinkedList<>();
|
||||
Collection<ObjectCache> allObjs = this.cache.values();
|
||||
List<ObjectCache> allObjs = this.cache.getAllElements(key);
|
||||
for (ObjectCache objectCache : allObjs) {
|
||||
if (objectCache.getOperation() == Operation.REMOVE && (objectCache.getKey().equals(key))) {
|
||||
if (objectCache.getOperation() == Operation.REMOVE) {
|
||||
removedObjects.add(objectCache.getObject());
|
||||
}
|
||||
}
|
||||
|
@ -541,19 +552,19 @@ 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.
|
||||
*/
|
||||
public <V extends Object> List<V> getRemoved(Class<V> clazz, String key) {
|
||||
public <V> List<V> getRemoved(Class<V> clazz, String key) {
|
||||
List<V> removedObjects = new LinkedList<>();
|
||||
Collection<ObjectCache> allObjs = this.cache.values();
|
||||
List<ObjectCache> allObjs = this.cache.getAllElements(key);
|
||||
for (ObjectCache objectCache : allObjs) {
|
||||
if (objectCache.getOperation() == Operation.REMOVE && (objectCache.getKey().equals(key))) {
|
||||
if (objectCache.getOperation() == Operation.REMOVE) {
|
||||
if (objectCache.getObject().getClass() == clazz) {
|
||||
@SuppressWarnings("unchecked")
|
||||
V object = (V) objectCache.getObject();
|
||||
|
@ -566,24 +577,22 @@ 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.
|
||||
*/
|
||||
public <V extends Object> List<V> getAll(Class<V> clazz, String key) {
|
||||
public <V> List<V> getAll(Class<V> clazz, String key) {
|
||||
List<V> objects = new LinkedList<>();
|
||||
Collection<ObjectCache> allObjs = this.cache.values();
|
||||
List<ObjectCache> allObjs = this.cache.getAllElements(key);
|
||||
for (ObjectCache objectCache : allObjs) {
|
||||
if (objectCache.getKey().equals(key)) {
|
||||
if (objectCache.getObject().getClass() == clazz) {
|
||||
@SuppressWarnings("unchecked")
|
||||
V object = (V) objectCache.getObject();
|
||||
objects.add(object);
|
||||
}
|
||||
if (objectCache.getObject().getClass() == clazz) {
|
||||
@SuppressWarnings("unchecked")
|
||||
V object = (V) objectCache.getObject();
|
||||
objects.add(object);
|
||||
}
|
||||
}
|
||||
return objects;
|
||||
|
@ -591,15 +600,15 @@ 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
|
||||
*/
|
||||
public <V extends Object> List<V> getAll(Class<V> clazz) {
|
||||
public <V> List<V> getAll(Class<V> clazz) {
|
||||
List<V> objects = new LinkedList<>();
|
||||
Collection<ObjectCache> allObjs = this.cache.values();
|
||||
Collection<ObjectCache> allObjs = this.cache.getAllElements();
|
||||
for (ObjectCache objectCache : allObjs) {
|
||||
if (objectCache.getObject().getClass() == clazz) {
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -613,19 +622,17 @@ public class ObjectFilter {
|
|||
/**
|
||||
* Get all the objects that were processed in this transaction, that were registered under the given key. No action
|
||||
* 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.
|
||||
*/
|
||||
public List<Object> getAll(String key) {
|
||||
List<Object> allObjects = new LinkedList<>();
|
||||
Collection<ObjectCache> allObjs = this.cache.values();
|
||||
List<ObjectCache> allObjs = this.cache.getAllElements(key);
|
||||
for (ObjectCache objectCache : allObjs) {
|
||||
if (objectCache.getKey().equals(key)) {
|
||||
allObjects.add(objectCache.getObject());
|
||||
}
|
||||
allObjects.add(objectCache.getObject());
|
||||
}
|
||||
return allObjects;
|
||||
}
|
||||
|
@ -633,26 +640,19 @@ public class ObjectFilter {
|
|||
/**
|
||||
* Get all the objects that were processed in this transaction, that were registered under the given key. No action
|
||||
* 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.
|
||||
*/
|
||||
public List<ObjectCache> getCache(String key) {
|
||||
List<ObjectCache> allCache = new LinkedList<>();
|
||||
Collection<ObjectCache> allObjs = this.cache.values();
|
||||
for (ObjectCache objectCache : allObjs) {
|
||||
if (objectCache.getKey().equals(key)) {
|
||||
allCache.add(objectCache);
|
||||
}
|
||||
}
|
||||
return allCache;
|
||||
return this.cache.getAllElements(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the set of keys that are currently present in the object filter.
|
||||
*
|
||||
*
|
||||
* @return The set containing the keys of that have been added to the filter.
|
||||
*/
|
||||
public Set<String> keySet() {
|
||||
|
|
|
@ -15,16 +15,12 @@
|
|||
*/
|
||||
package li.strolch.utils.objectfilter;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import li.strolch.utils.objectfilter.ObjectFilter;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
|
@ -37,7 +33,7 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.add(myObj);
|
||||
filter.add(myObj, myObj);
|
||||
|
||||
testAssertions(filter, 1, 1, 1, 0, 0);
|
||||
}
|
||||
|
@ -48,7 +44,7 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.update(myObj);
|
||||
filter.update(myObj, myObj);
|
||||
|
||||
testAssertions(filter, 1, 1, 0, 1, 0);
|
||||
}
|
||||
|
@ -59,7 +55,7 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.remove(myObj);
|
||||
filter.remove(myObj, myObj);
|
||||
|
||||
testAssertions(filter, 1, 1, 0, 0, 1);
|
||||
}
|
||||
|
@ -72,9 +68,9 @@ public class ObjectFilterTest {
|
|||
Object objToRemove = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.add(objToAdd);
|
||||
filter.update(objToUpdate);
|
||||
filter.remove(objToRemove);
|
||||
filter.add(objToAdd, objToAdd);
|
||||
filter.update(objToUpdate, objToUpdate);
|
||||
filter.remove(objToRemove, objToRemove);
|
||||
|
||||
testAssertions(filter, 3, 1, 1, 1, 1);
|
||||
}
|
||||
|
@ -85,9 +81,9 @@ public class ObjectFilterTest {
|
|||
Object objToAddUpdateRemove = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.add(objToAddUpdateRemove);
|
||||
filter.update(objToAddUpdateRemove);
|
||||
filter.remove(objToAddUpdateRemove);
|
||||
filter.add(objToAddUpdateRemove, objToAddUpdateRemove);
|
||||
filter.update(objToAddUpdateRemove, objToAddUpdateRemove);
|
||||
filter.remove(objToAddUpdateRemove, objToAddUpdateRemove);
|
||||
|
||||
testAssertions(filter, 0, 1, 0, 0, 0);
|
||||
}
|
||||
|
@ -98,10 +94,10 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.add(myObj);
|
||||
filter.add(myObj, myObj);
|
||||
|
||||
try {
|
||||
filter.add(myObj);
|
||||
filter.add(myObj, myObj);
|
||||
fail("Should have failed adding twice!");
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("Stale State exception: Invalid + after +", e.getMessage());
|
||||
|
@ -116,10 +112,10 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.remove(myObj);
|
||||
filter.remove(myObj, myObj);
|
||||
|
||||
try {
|
||||
filter.remove(myObj);
|
||||
filter.remove(myObj, myObj);
|
||||
fail("Should have failed removing twice!");
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("Stale State exception: Invalid - after -", e.getMessage());
|
||||
|
@ -134,8 +130,8 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.update(myObj);
|
||||
filter.update(myObj);
|
||||
filter.update(myObj, myObj);
|
||||
filter.update(myObj, myObj);
|
||||
testAssertions(filter, 1, 1, 0, 1, 0);
|
||||
}
|
||||
|
||||
|
@ -145,9 +141,9 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.add(myObj);
|
||||
filter.update(myObj);
|
||||
filter.update(myObj);
|
||||
filter.add(myObj, myObj);
|
||||
filter.update(myObj, myObj);
|
||||
filter.update(myObj, myObj);
|
||||
testAssertions(filter, 1, 1, 1, 0, 0);
|
||||
}
|
||||
|
||||
|
@ -156,10 +152,10 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.update(myObj);
|
||||
filter.update(myObj, myObj);
|
||||
|
||||
try {
|
||||
filter.add(myObj);
|
||||
filter.add(myObj, myObj);
|
||||
fail("Should have failed add after modify");
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("Stale State exception: Invalid + after +=", e.getMessage());
|
||||
|
@ -173,8 +169,8 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.remove(myObj);
|
||||
filter.add(myObj);
|
||||
filter.remove(myObj, myObj);
|
||||
filter.add(myObj, myObj);
|
||||
|
||||
testAssertions(filter, 1, 1, 0, 1, 0);
|
||||
}
|
||||
|
@ -184,10 +180,10 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.remove(myObj);
|
||||
filter.remove(myObj, myObj);
|
||||
|
||||
try {
|
||||
filter.update(myObj);
|
||||
filter.update(myObj, myObj);
|
||||
fail("Should have failed modify after remove");
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("Stale State exception: Invalid += after -", e.getMessage());
|
||||
|
@ -201,10 +197,10 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.add(myObj);
|
||||
filter.add(myObj, myObj);
|
||||
|
||||
try {
|
||||
filter.update("different_key", myObj);
|
||||
filter.update("different_key", myObj, myObj);
|
||||
fail("Should have failed because of different key for already registered object");
|
||||
} catch (RuntimeException e) {
|
||||
String msg = "Object may be present in the same filter instance only once, registered using one key only";
|
||||
|
@ -222,8 +218,8 @@ public class ObjectFilterTest {
|
|||
assertEquals("Test objects are not equal!", obj1, obj2);
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.remove(Object.class.getName(), obj1);
|
||||
filter.add(Object.class.getName(), obj2);
|
||||
filter.remove(Object.class.getName(), obj1, obj1);
|
||||
filter.add(Object.class.getName(), obj2, obj2);
|
||||
|
||||
testAssertions(filter, 1, 1, 0, 1, 0);
|
||||
|
||||
|
@ -241,8 +237,8 @@ public class ObjectFilterTest {
|
|||
assertEquals("Test objects are not equal!", obj1, obj2);
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.add(Object.class.getName(), obj1);
|
||||
filter.update(Object.class.getName(), obj2);
|
||||
filter.add(Object.class.getName(), obj1, obj1);
|
||||
filter.update(Object.class.getName(), obj2, obj2);
|
||||
|
||||
testAssertions(filter, 1, 1, 1, 0, 0);
|
||||
|
||||
|
@ -260,8 +256,8 @@ public class ObjectFilterTest {
|
|||
assertEquals("Test objects are not equal!", obj1, obj2);
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.update(Object.class.getName(), obj1);
|
||||
filter.update(Object.class.getName(), obj2);
|
||||
filter.update(Object.class.getName(), obj1, obj1);
|
||||
filter.update(Object.class.getName(), obj2, obj2);
|
||||
|
||||
testAssertions(filter, 1, 1, 0, 1, 0);
|
||||
|
||||
|
@ -279,8 +275,8 @@ public class ObjectFilterTest {
|
|||
assertEquals("Test objects are not equal!", obj1, obj2);
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.update(Object.class.getName(), obj1);
|
||||
filter.remove(Object.class.getName(), obj2);
|
||||
filter.update(Object.class.getName(), obj1, obj1);
|
||||
filter.remove(Object.class.getName(), obj2, obj2);
|
||||
|
||||
testAssertions(filter, 1, 1, 0, 0, 1);
|
||||
|
||||
|
@ -296,8 +292,8 @@ public class ObjectFilterTest {
|
|||
Object myObj = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.add(myObj);
|
||||
filter.remove(myObj);
|
||||
filter.add(myObj, myObj);
|
||||
filter.remove(myObj, myObj);
|
||||
testAssertions(filter, 0, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
@ -309,9 +305,9 @@ public class ObjectFilterTest {
|
|||
Object myObj3 = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.add(myObj1);
|
||||
filter.update(myObj2);
|
||||
filter.remove(myObj3);
|
||||
filter.add(myObj1, myObj1);
|
||||
filter.update(myObj2, myObj2);
|
||||
filter.remove(myObj3, myObj3);
|
||||
|
||||
filter.clearCache();
|
||||
|
||||
|
@ -326,9 +322,9 @@ public class ObjectFilterTest {
|
|||
Object myObj3 = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.add(myObj1);
|
||||
filter.update(myObj2);
|
||||
filter.remove(myObj3);
|
||||
filter.add(myObj1, myObj1);
|
||||
filter.update(myObj2, myObj2);
|
||||
filter.remove(myObj3, myObj3);
|
||||
|
||||
testAssertions(filter, 3, 1, 1, 1, 1);
|
||||
|
||||
|
@ -345,7 +341,7 @@ public class ObjectFilterTest {
|
|||
Object myObj1 = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.add(myObj1);
|
||||
filter.add(myObj1, myObj1);
|
||||
|
||||
testAssertions(filter, 1, 1, 1, 0, 0);
|
||||
|
||||
|
@ -360,7 +356,7 @@ public class ObjectFilterTest {
|
|||
Object myObj1 = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.update(myObj1);
|
||||
filter.update(myObj1, myObj1);
|
||||
|
||||
testAssertions(filter, 1, 1, 0, 1, 0);
|
||||
|
||||
|
@ -375,7 +371,7 @@ public class ObjectFilterTest {
|
|||
Object myObj1 = new Object();
|
||||
|
||||
ObjectFilter filter = new ObjectFilter();
|
||||
filter.remove(myObj1);
|
||||
filter.remove(myObj1, myObj1);
|
||||
|
||||
testAssertions(filter, 1, 1, 0, 0, 1);
|
||||
|
||||
|
|
Loading…
Reference in New Issue