You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2013/06/28 19:04:56 UTC

[2/3] git commit: ISIS-450: new EventBusService

ISIS-450: new EventBusService


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/d068fbed
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/d068fbed
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/d068fbed

Branch: refs/heads/master
Commit: d068fbed43dba0f694cd8962591a0194cd3cf030
Parents: 496c8ed
Author: Dan Haywood <da...@apache.org>
Authored: Fri Jun 28 17:34:22 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Fri Jun 28 17:34:22 2013 +0100

----------------------------------------------------------------------
 .../applib/service/support/IsisJdoSupport.java  |   6 +
 .../jdo/datanucleus/JDOStateManagerForIsis.java | 176 +++++++++++++------
 .../service/eventbus/EventBusServiceJdo.java    |  60 +++++++
 .../service/support/IsisJdoSupportImpl.java     |  10 ++
 .../applib/services/eventbus/ChangedEvent.java  |  49 ++++++
 .../services/eventbus/EventBusService.java      | 120 +++++++++++++
 .../runtime/system/session/IsisSession.java     |  13 ++
 .../system/session/IsisSessionDefault.java      |  15 ++
 8 files changed, 391 insertions(+), 58 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/d068fbed/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/support/IsisJdoSupport.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/support/IsisJdoSupport.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/support/IsisJdoSupport.java
index 5a65f53..598c3f0 100644
--- a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/support/IsisJdoSupport.java
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/support/IsisJdoSupport.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.objectstore.jdo.applib.service.support;
 
+import java.util.Collection;
+
 import javax.jdo.PersistenceManager;
 
 import org.apache.isis.applib.annotation.Programmatic;
@@ -47,5 +49,9 @@ public interface IsisJdoSupport {
     <T> T refresh(T domainObject);
     
     @Programmatic
+    void ensureLoaded(Collection<?> collectionOfDomainObjects);
+    
+    @Programmatic
     PersistenceManager getJdoPersistenceManager();
+    
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/d068fbed/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/JDOStateManagerForIsis.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/JDOStateManagerForIsis.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/JDOStateManagerForIsis.java
index f87e2ba..9af351c 100644
--- a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/JDOStateManagerForIsis.java
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/JDOStateManagerForIsis.java
@@ -28,70 +28,130 @@ import org.datanucleus.metadata.AbstractClassMetaData;
 import org.datanucleus.state.JDOStateManager;
 import org.datanucleus.state.ObjectProvider;
 import org.datanucleus.store.FieldValues;
+import org.datanucleus.store.fieldmanager.FieldManager;
 
 import org.apache.isis.core.metamodel.services.ServicesInjectorSpi;
 import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.objectstore.jdo.datanucleus.service.eventbus.EventBusServiceJdo;
 
 public class JDOStateManagerForIsis extends JDOStateManager implements StateManager, ObjectProvider {
 
-	public JDOStateManagerForIsis(ExecutionContext ec, AbstractClassMetaData cmd) {
-		super(ec, cmd);
-	}
-
-	public void initialiseForHollow(Object id, FieldValues fv, Class pcClass) {
-		super.initialiseForHollow(id, fv, pcClass);
-		mapIntoIsis(myPC);
-	}
-
-	public void initialiseForHollowAppId(FieldValues fv, Class pcClass) {
-		super.initialiseForHollowAppId(fv, pcClass);
-		mapIntoIsis(myPC);
-	}
-
-	public void initialiseForHollowPreConstructed(Object id, Object pc) {
-		super.initialiseForHollowPreConstructed(id, pc);
-		mapIntoIsis(myPC);
-	}
-
-	public void initialiseForPersistentClean(Object id, Object pc) {
-		super.initialiseForPersistentClean(id, pc);
-		mapIntoIsis(myPC);
-	}
-
-	public void initialiseForEmbedded(Object pc, boolean copyPc) {
-		super.initialiseForEmbedded(pc, copyPc);
-		mapIntoIsis(myPC);
-	}
-
-	public void initialiseForPersistentNew(Object pc,
-			FieldValues preInsertChanges) {
-		super.initialiseForPersistentNew(pc, preInsertChanges);
-		mapIntoIsis(myPC);
-	}
-
-	public void initialiseForTransactionalTransient(Object pc) {
-		super.initialiseForTransactionalTransient(pc);
-		mapIntoIsis(myPC);
-	}
-
-	public void initialiseForDetached(Object pc, Object id, Object version) {
-		super.initialiseForDetached(pc, id, version);
-		mapIntoIsis(myPC);
-	}
-
-	public void initialiseForPNewToBeDeleted(Object pc) {
-		super.initialiseForPNewToBeDeleted(pc);
-		mapIntoIsis(myPC);
-	}
-
-	public void initialiseForCachedPC(CachedPC cachedPC, Object id) {
-		super.initialiseForCachedPC(cachedPC, id);
-		mapIntoIsis(myPC);
-	}
-	
-	protected void mapIntoIsis(PersistenceCapable pc) {
-	    getServicesInjector().injectServicesInto(pc);
-	}
+    public JDOStateManagerForIsis(ExecutionContext ec, AbstractClassMetaData cmd) {
+        super(ec, cmd);
+    }
+
+    public enum Hint {
+        NONE,
+        REPLACE_FIELDS,
+        POST_COMMIT
+    }
+
+    /**
+     * Tunnel down the thread stack as a hint to the {@link EventBusServiceJdo}.
+     */
+    public final static ThreadLocal<Hint> hint = new ThreadLocal<JDOStateManagerForIsis.Hint>() {
+        protected Hint initialValue() {
+            return Hint.NONE;
+        };
+    };
+
+    public void initialiseForHollow(Object id, FieldValues fv, Class pcClass) {
+        super.initialiseForHollow(id, fv, pcClass);
+        mapIntoIsis(myPC);
+    }
+
+    public void initialiseForHollowAppId(FieldValues fv, Class pcClass) {
+        super.initialiseForHollowAppId(fv, pcClass);
+        mapIntoIsis(myPC);
+    }
+
+    public void initialiseForHollowPreConstructed(Object id, Object pc) {
+        super.initialiseForHollowPreConstructed(id, pc);
+        mapIntoIsis(myPC);
+    }
+
+    public void initialiseForPersistentClean(Object id, Object pc) {
+        super.initialiseForPersistentClean(id, pc);
+        mapIntoIsis(myPC);
+    }
+
+    public void initialiseForEmbedded(Object pc, boolean copyPc) {
+        super.initialiseForEmbedded(pc, copyPc);
+        mapIntoIsis(myPC);
+    }
+
+    public void initialiseForPersistentNew(Object pc,
+            FieldValues preInsertChanges) {
+        super.initialiseForPersistentNew(pc, preInsertChanges);
+        mapIntoIsis(myPC);
+    }
+
+    public void initialiseForTransactionalTransient(Object pc) {
+        super.initialiseForTransactionalTransient(pc);
+        mapIntoIsis(myPC);
+    }
+
+    public void initialiseForDetached(Object pc, Object id, Object version) {
+        super.initialiseForDetached(pc, id, version);
+        mapIntoIsis(myPC);
+    }
+
+    public void initialiseForPNewToBeDeleted(Object pc) {
+        super.initialiseForPNewToBeDeleted(pc);
+        mapIntoIsis(myPC);
+    }
+
+    public void initialiseForCachedPC(CachedPC cachedPC, Object id) {
+        super.initialiseForCachedPC(cachedPC, id);
+        mapIntoIsis(myPC);
+    }
+
+    @Override
+    public void replaceField(int fieldNumber, Object value) {
+        final Hint previous = hint.get();
+        try {
+            hint.set(Hint.REPLACE_FIELDS);
+            super.replaceField(fieldNumber, value);
+        } finally {
+            hint.set(previous);
+        }
+    }
+    
+    @Override
+    public void replaceFields(int[] fieldNumbers, FieldManager fm) {
+        final Hint previous = hint.get();
+        try {
+            hint.set(Hint.REPLACE_FIELDS);
+            super.replaceFields(fieldNumbers, fm);
+        } finally {
+            hint.set(previous);
+        }
+    }
+    
+    @Override
+    public void replaceFields(int[] fieldNumbers, FieldManager fm, boolean replaceWhenDirty) {
+        final Hint previous = hint.get();
+        try {
+            hint.set(Hint.REPLACE_FIELDS);
+            super.replaceFields(fieldNumbers, fm, replaceWhenDirty);
+        } finally {
+            hint.set(previous);
+        }
+    }
+
+    public void postCommit(org.datanucleus.Transaction tx) {
+        final Hint previous = hint.get();
+        try {
+            hint.set(Hint.POST_COMMIT);
+            super.postCommit(tx);
+        } finally {
+            hint.set(previous);
+        }
+    }
+
+    protected void mapIntoIsis(PersistenceCapable pc) {
+        getServicesInjector().injectServicesInto(pc);
+    }
 
     protected ServicesInjectorSpi getServicesInjector() {
         return IsisContext.getPersistenceSession().getServicesInjector();

http://git-wip-us.apache.org/repos/asf/isis/blob/d068fbed/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java
new file mode 100644
index 0000000..510f7d2
--- /dev/null
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java
@@ -0,0 +1,60 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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 org.apache.isis.objectstore.jdo.datanucleus.service.eventbus;
+
+import java.util.Collection;
+
+import com.google.common.eventbus.EventBus;
+
+import org.apache.isis.applib.services.eventbus.EventBusService;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.objectstore.jdo.applib.service.support.IsisJdoSupport;
+import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis;
+import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis.Hint;
+
+public class EventBusServiceJdo extends EventBusService {
+
+    
+    @Override
+    protected EventBus getEventBus() {
+        return IsisContext.getSession().getEventBus();
+    }
+
+    // //////////////////////////////////////
+
+    @Override
+    protected void ensureLoaded(final Collection<?> collection) {
+        isisJdoSupport.ensureLoaded(collection);
+    }
+
+    /**
+     * skip if called in any way by way of the {@link JDOStateManagerForIsis}.
+     */
+    @Override
+    protected boolean skip(Object event) {
+        return JDOStateManagerForIsis.hint.get() != Hint.NONE;
+    }
+    
+    // //////////////////////////////////////
+
+    private IsisJdoSupport isisJdoSupport;
+    public void setIsisJdoSupport(IsisJdoSupport isisJdoSupport) {
+        this.isisJdoSupport = isisJdoSupport;
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/d068fbed/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/IsisJdoSupportImpl.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/IsisJdoSupportImpl.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/IsisJdoSupportImpl.java
index d9cb319..dc1ac24 100644
--- a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/IsisJdoSupportImpl.java
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/support/IsisJdoSupportImpl.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.objectstore.jdo.datanucleus.service.support;
 
+import java.util.Collection;
+
 import javax.jdo.PersistenceManager;
 
 import org.apache.isis.applib.annotation.Hidden;
@@ -34,6 +36,7 @@ import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore;
 @Hidden
 public class IsisJdoSupportImpl implements IsisJdoSupport {
     
+    @Programmatic
     @Override
     public <T> T refresh(T domainObject) {
         DataNucleusObjectStore objectStore = getObjectStore();
@@ -42,6 +45,12 @@ public class IsisJdoSupportImpl implements IsisJdoSupport {
         return domainObject;
     }
 
+    @Programmatic
+    @Override
+    public void ensureLoaded(Collection<?> domainObjects) {
+        getObjectStore().getPersistenceManager().retrieveAll(domainObjects);
+    }
+
     protected DataNucleusObjectStore getObjectStore() {
         return (DataNucleusObjectStore) getPersistenceSession().getObjectStore();
     }
@@ -64,4 +73,5 @@ public class IsisJdoSupportImpl implements IsisJdoSupport {
         return getObjectStore().getPersistenceManager();
     }
 
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/d068fbed/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ChangedEvent.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ChangedEvent.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ChangedEvent.java
new file mode 100644
index 0000000..d023d15
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/ChangedEvent.java
@@ -0,0 +1,49 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.isis.applib.services.eventbus;
+
+import org.apache.isis.applib.util.ObjectContracts;
+
+public abstract class ChangedEvent<S,T> {
+    private final S source;
+    private final T oldValue;
+    private final T newValue;
+    
+    public ChangedEvent(S source, T oldValue, T newValue) {
+        this.source = source;
+        this.oldValue = oldValue;
+        this.newValue = newValue;
+    }
+
+    public S getSource() {
+        return source;
+    }
+    
+    public T getOldValue() {
+        return oldValue;
+    }
+    public T getNewValue() {
+        return newValue;
+    }
+    
+    @Override
+    public String toString() {
+        return ObjectContracts.toString(this, "source,oldValue,newValue");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/d068fbed/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
new file mode 100644
index 0000000..3414a22
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
@@ -0,0 +1,120 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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 org.apache.isis.applib.services.eventbus;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+
+import com.google.common.collect.Lists;
+import com.google.common.eventbus.EventBus;
+
+import org.apache.isis.applib.annotation.Programmatic;
+
+public abstract class EventBusService {
+
+    /**
+     * A no-op implementation to use as a default for domain objects that are being
+     * instantiated and for which the event bus service has not yet been injected. 
+     */
+    public static final EventBusService NOOP = new EventBusService() {
+        @Override
+        public void register(Object domainObject) {};
+        @Override
+        public void unregister(Object domainObject) {};
+        @Override
+        public void post(Object event, java.util.Collection<?>... collections) {}
+        @Override
+        protected EventBus getEventBus() {
+            return null;
+        }
+    };
+    
+    /**
+     * @return an {@link EventBus} scoped to the current session.
+     */
+    protected abstract EventBus getEventBus();
+    
+    /**
+     * Register the domain object with the service.
+     * 
+     * <p>
+     * This must be called manually, but a good technique is for the domain object to call
+     * this method when the service is injected into it.
+     * 
+     * <p>
+     * For example:
+     * <pre>
+     * private EventBusService eventBusService;
+     * public void injectEventBusService(final EventBusService eventBusService) {
+     *     this.eventBusService = eventBusService;
+     *     eventBusService.register(this);
+     * }
+     * </pre>
+     */
+    @Programmatic
+    public void register(Object domainObject) {
+        getEventBus().register(domainObject);
+    }
+    
+    @Programmatic
+    public void unregister(Object domainObject) {
+        getEventBus().unregister(domainObject);
+    }
+    
+    /**
+     * Post an event, but ensuring that any possible subscribers 
+     * to that event have been brought into memory.
+     */
+    @Programmatic
+    public void post(Object event, Collection<?>... collections ) {
+        if(skip(event)) {
+            return;
+        }
+        final List<Object> list = Lists.newArrayList();
+        for (Collection<?> collection : collections) {
+            list.addAll(collection);
+        }
+        ensureLoaded(list);
+        getEventBus().post(event);
+    }
+
+    /**
+     * A hook to allow subclass implementations to skip the publication of certain events.
+     * 
+     * <p>
+     * For example, the <tt>EventBusServiceJdo</tt> does not publish events if the method
+     * is called by JDO/DataNucleus infrastructure, eg during hydration or commits.
+     */
+    protected boolean skip(Object event) {
+        return false;
+    }
+
+    /**
+     * Overrideable hook method.
+     * 
+     * <p>
+     * If using JDO objectstore, then use the <tt>EventBusServiceJdo</tt> implementation, 
+     * which overrides this method to load objects from the database.
+     */
+    protected void ensureLoaded(final Collection<?> collection) {
+    }
+    
+}
+

http://git-wip-us.apache.org/repos/asf/isis/blob/d068fbed/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSession.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSession.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSession.java
index 1b61d84..fed9302 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSession.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSession.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.runtime.system.session;
 
+import com.google.common.eventbus.EventBus;
+
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.components.ApplicationScopedComponent;
 import org.apache.isis.core.commons.components.SessionScopedComponent;
@@ -111,6 +113,16 @@ public interface IsisSession extends SessionScopedComponent {
 
     public UserProfile getUserProfile();
 
+    
+    // //////////////////////////////////////////////////////
+    // EventBus
+    // //////////////////////////////////////////////////////
+
+    /**
+     * Guava {@link EventBus}, scoped to this session.
+     */
+    public EventBus getEventBus();
+
     // //////////////////////////////////////////////////////
     // Transaction (if in progress)
     // //////////////////////////////////////////////////////
@@ -127,4 +139,5 @@ public interface IsisSession extends SessionScopedComponent {
 
     public void debugState(DebugBuilder debug);
 
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/d068fbed/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionDefault.java
index 7e40918..b7add81 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionDefault.java
@@ -27,6 +27,8 @@ import static org.hamcrest.CoreMatchers.nullValue;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
+import com.google.common.eventbus.EventBus;
+
 import org.apache.log4j.Logger;
 
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
@@ -72,6 +74,8 @@ public class IsisSessionDefault implements IsisSession {
     private long accessTime;
     private String debugSnapshot;
 
+    private EventBus eventBus;
+
     public IsisSessionDefault(final IsisSessionFactory sessionFactory, final AuthenticationSession authenticationSession, final PersistenceSession persistenceSession, final UserProfile userProfile) {
 
         // global context
@@ -91,6 +95,7 @@ public class IsisSessionDefault implements IsisSession {
         setSessionOpenTime(System.currentTimeMillis());
 
         this.id = nextId++;
+        
     }
 
     // //////////////////////////////////////////////////////
@@ -99,6 +104,8 @@ public class IsisSessionDefault implements IsisSession {
 
     @Override
     public void open() {
+        this.eventBus = new EventBus();
+        
         persistenceSession.open();
     }
 
@@ -109,6 +116,8 @@ public class IsisSessionDefault implements IsisSession {
     public void close() {
         takeSnapshot();
         getPersistenceSession().close();
+        
+        eventBus = null;
     }
 
     // //////////////////////////////////////////////////////
@@ -241,6 +250,11 @@ public class IsisSessionDefault implements IsisSession {
         return getTransactionManager().getTransaction();
     }
 
+    @Override
+    public EventBus getEventBus() {
+        return eventBus;
+    }
+
     // //////////////////////////////////////////////////////
     // testSetObjectPersistor
     // //////////////////////////////////////////////////////
@@ -342,4 +356,5 @@ public class IsisSessionDefault implements IsisSession {
         return getPersistenceSession().getTransactionManager();
     }
 
+
 }