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:
+ *
+ *
+ * - {@link Tags#RESOURCE}
+ * - {@link Tags#ORDER}
+ * - {@link Tags#ACTIVITY}
+ *
+ *
+ *
+ * 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());