diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/api/ObserverHandler.java b/li.strolch.agent/src/main/java/li/strolch/agent/api/ObserverHandler.java index 47d5e9a22..f76dc9d66 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/api/ObserverHandler.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/api/ObserverHandler.java @@ -18,16 +18,81 @@ package li.strolch.agent.api; import java.util.List; import li.strolch.model.StrolchRootElement; +import li.strolch.model.Tags; +/** + *

+ * Implementing the observer pattern by allowing {@link Observer} to register themselves for updates to + * {@link StrolchRootElement} + *

+ * + *

+ * Note: The key in all the methods can be any string, but as a convenience it is mostly one of the following: + *

+ * + * + *

+ * Should a special case arise, then it a contract must be defined by which a key is negotiated between an event + * distributer and the observer + *

+ * + * @author Robert von Burg + */ public interface ObserverHandler { + /** + * Notifies any registered {@link Observer} that the given elements under the given key have been added i.e. created + * + * @param key + * the key for which to notify observers + * @param elements + * the elements to notify observers with + */ public void add(String key, List elements); + /** + * Notifies any registered {@link Observer} that the given elements under the given key have been updated i.e. + * modified + * + * @param key + * the key for which to notify observers + * @param elements + * the elements to notify observers with + */ public void update(String key, List elements); + /** + * Notifies any registered {@link Observer} that the given elements under the given key have been removed i.e. + * deleted + * + * @param key + * the key for which to notify observers + * @param elements + * the elements to notify observers with + */ public void remove(String key, List elements); + /** + * Registers the {@link Observer} for notification of objects under the given key + * + * @param key + * the key for which to the observer wants to be notified + * @param observer + * the observer to register + */ public void registerObserver(String key, Observer observer); + /** + * Unregister the given {@link Observer} + * + * @param key + * the key for which to the observer was registered + * @param observer + * the observer unregister + */ public void unregisterObserver(String key, Observer observer); } diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/impl/DefaultObserverHandler.java b/li.strolch.agent/src/main/java/li/strolch/agent/impl/DefaultObserverHandler.java index 1f5126275..7c00c67fc 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/impl/DefaultObserverHandler.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/impl/DefaultObserverHandler.java @@ -21,14 +21,17 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import li.strolch.agent.api.Observer; import li.strolch.agent.api.ObserverHandler; import li.strolch.model.StrolchRootElement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** + * A simple {@link ObserverHandler} which keeps a reference to all registered {@link Observer} and notifies them when + * one of the notify methods are called + * * @author Robert von Burg */ public class DefaultObserverHandler implements ObserverHandler { @@ -43,6 +46,9 @@ public class DefaultObserverHandler implements ObserverHandler { @Override public void add(String key, List elements) { + if (elements == null || elements.isEmpty()) + return; + List observerList = this.observerMap.get(key); if (observerList != null && !observerList.isEmpty()) { for (Observer observer : observerList) { @@ -59,6 +65,9 @@ public class DefaultObserverHandler implements ObserverHandler { @Override public void update(String key, List elements) { + if (elements == null || elements.isEmpty()) + return; + List observerList = this.observerMap.get(key); if (observerList != null && !observerList.isEmpty()) { for (Observer observer : observerList) { @@ -75,6 +84,9 @@ public class DefaultObserverHandler implements ObserverHandler { @Override public void remove(String key, List elements) { + if (elements == null || elements.isEmpty()) + return; + List observerList = this.observerMap.get(key); if (observerList != null && !observerList.isEmpty()) { for (Observer observer : observerList) { diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java index f8b9956d6..7f50f17f1 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java @@ -871,15 +871,30 @@ public abstract class AbstractTransaction implements StrolchTransaction { ObserverHandler observerHandler = this.realm.getObserverHandler(); if (this.orderMap != null) { - observerHandler.add(Tags.ORDER, new ArrayList(this.orderMap.getCreated())); - observerHandler.update(Tags.ORDER, new ArrayList(this.orderMap.getUpdated())); - observerHandler.remove(Tags.ORDER, new ArrayList(this.orderMap.getDeleted())); + if (!this.orderMap.getCreated().isEmpty()) + observerHandler.add(Tags.ORDER, new ArrayList(this.orderMap.getCreated())); + if (!this.orderMap.getUpdated().isEmpty()) + observerHandler.update(Tags.ORDER, new ArrayList(this.orderMap.getUpdated())); + if (!this.orderMap.getDeleted().isEmpty()) + observerHandler.remove(Tags.ORDER, new ArrayList(this.orderMap.getDeleted())); } if (this.resourceMap != null) { - observerHandler.add(Tags.RESOURCE, new ArrayList(this.resourceMap.getCreated())); - observerHandler.update(Tags.RESOURCE, new ArrayList(this.resourceMap.getUpdated())); - observerHandler.remove(Tags.RESOURCE, new ArrayList(this.resourceMap.getDeleted())); + if (!this.resourceMap.getCreated().isEmpty()) + observerHandler.add(Tags.RESOURCE, new ArrayList(this.resourceMap.getCreated())); + if (!this.resourceMap.getUpdated().isEmpty()) + observerHandler.update(Tags.RESOURCE, new ArrayList(this.resourceMap.getUpdated())); + if (!this.resourceMap.getDeleted().isEmpty()) + observerHandler.remove(Tags.RESOURCE, new ArrayList(this.resourceMap.getDeleted())); + } + + if (this.activityMap != null) { + if (!this.activityMap.getCreated().isEmpty()) + observerHandler.add(Tags.ACTIVITY, new ArrayList(this.activityMap.getCreated())); + if (!this.activityMap.getUpdated().isEmpty()) + observerHandler.update(Tags.ACTIVITY, new ArrayList(this.activityMap.getUpdated())); + if (!this.activityMap.getDeleted().isEmpty()) + observerHandler.remove(Tags.ACTIVITY, new ArrayList(this.activityMap.getDeleted())); } long observerUpdateDuration = System.nanoTime() - observerUpdateStart; @@ -918,6 +933,14 @@ public abstract class AbstractTransaction implements StrolchTransaction { auditsFor(audits, AccessType.DELETE, Tags.RESOURCE, 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()); + } + if (this.auditTrail != null && !isSuppressAuditsForAudits()) { if (this.realm.isAuditTrailEnabledForRead()) auditsForAudits(audits, AccessType.READ, Tags.AUDIT, this.auditTrail.getRead());