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 2016/03/16 01:01:58 UTC

[2/3] isis git commit: ISIS-1324: have EntityCollectionModel hold a reference to EntityModel (if it is parented)... the idea being that we will associate hints only with EntityModels.

ISIS-1324: have EntityCollectionModel hold a reference to EntityModel (if it is parented)... the idea being that we will associate hints only with EntityModels.


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

Branch: refs/heads/master
Commit: be5b3384ec03e316342f79c40250a61590345fdd
Parents: daf7ad7
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Tue Mar 15 23:25:12 2016 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Tue Mar 15 23:25:12 2016 +0000

----------------------------------------------------------------------
 .../wicket/model/hints/UiHintContainer.java     |   6 +-
 .../model/models/EntityCollectionModel.java     |  75 +++++-----
 .../viewer/wicket/model/models/EntityModel.java |  92 ++++++++++--
 .../wicket/model/models/ModelAbstract.java      |  88 +-----------
 .../model/models/EntityModel_hintsTest.java     | 137 ++++++++++++++++++
 .../wicket/model/models/ModelAbstractTest.java  | 142 -------------------
 .../components/collection/CollectionPanel.java  |  18 +--
 .../selector/CollectionSelectorHelper.java      |   2 +-
 .../CollectionContentsMultipleViewsPanel.java   |  14 +-
 9 files changed, 287 insertions(+), 287 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/be5b3384/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintContainer.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintContainer.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintContainer.java
index 4b65489..902512a 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintContainer.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/hints/UiHintContainer.java
@@ -23,11 +23,11 @@ import org.apache.wicket.util.string.Strings;
 
 public interface UiHintContainer {
 
-    String getHint(Component component, String key);
+    String getHint(Component component, String attributeName);
     
-    void setHint(Component component, String key, String value);
+    void setHint(Component component, String attributeName, String attributeValue);
 
-    void clearHint(Component component, String key);
+    void clearHint(Component component, String attributeName);
 
     public static class Util {
         private Util(){}

http://git-wip-us.apache.org/repos/asf/isis/blob/be5b3384/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
index 72ec1cc..aed3c71 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
@@ -29,6 +29,8 @@ import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 
+import org.apache.wicket.Component;
+
 import org.apache.isis.applib.layout.component.CollectionLayoutData;
 import org.apache.isis.core.commons.factory.InstanceUtil;
 import org.apache.isis.core.commons.lang.ClassUtil;
@@ -49,11 +51,11 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
 import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
 import org.apache.isis.viewer.wicket.model.links.LinksProvider;
 import org.apache.isis.viewer.wicket.model.mementos.CollectionMemento;
 import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
-import org.apache.isis.viewer.wicket.model.util.ScopedSessionAttribute;
 
 /**
  * Model representing a collection of entities, either {@link Type#STANDALONE
@@ -64,13 +66,15 @@ import org.apache.isis.viewer.wicket.model.util.ScopedSessionAttribute;
  * So that the model is {@link Serializable}, the {@link ObjectAdapter}s within
  * the collection are stored as {@link ObjectAdapterMemento}s.
  */
-public class EntityCollectionModel extends ModelAbstract<List<ObjectAdapter>> implements LinksProvider {
+public class EntityCollectionModel extends ModelAbstract<List<ObjectAdapter>> implements LinksProvider,
+        UiHintContainer {
 
     private static final long serialVersionUID = 1L;
 
     private static final int PAGE_SIZE_DEFAULT_FOR_PARENTED = 12;
     private static final int PAGE_SIZE_DEFAULT_FOR_STANDALONE = 25;
 
+
     public enum Type {
         /**
          * A simple list of object mementos, eg the result of invoking an action
@@ -114,7 +118,7 @@ public class EntityCollectionModel extends ModelAbstract<List<ObjectAdapter>> im
         PARENTED {
             @Override
             List<ObjectAdapter> load(final EntityCollectionModel entityCollectionModel) {
-                final ObjectAdapter adapter = entityCollectionModel.parentObjectAdapterMemento.getObjectAdapter(
+                final ObjectAdapter adapter = entityCollectionModel.getParentObjectAdapterMemento().getObjectAdapter(
                         ConcurrencyChecking.NO_CHECK);
                 final OneToManyAssociation collection = entityCollectionModel.collectionMemento.getCollection();
                 final ObjectAdapter collectionAsAdapter = collection.get(adapter, InteractionInitiatedBy.USER);
@@ -272,12 +276,9 @@ public class EntityCollectionModel extends ModelAbstract<List<ObjectAdapter>> im
     /**
      * Populated only if {@link Type#PARENTED}.
      */
-    private ObjectAdapterMemento parentObjectAdapterMemento;
+    private final EntityModel entityModel;
+
 
-    /**
-     * Populated only if {@link Type#PARENTED}.
-     */
-    private final CollectionLayoutData collectionLayoutData;
     /**
      * Populated only if {@link Type#PARENTED}.
      */
@@ -302,34 +303,24 @@ public class EntityCollectionModel extends ModelAbstract<List<ObjectAdapter>> im
 
     private EntityCollectionModel(final Class<?> typeOf, final List<ObjectAdapterMemento> mementoList, final int pageSize) {
         this.type = Type.STANDALONE;
+        this.entityModel = null;
         this.typeOf = typeOf;
         this.mementoList = mementoList;
         this.pageSize = pageSize;
         this.toggledMementosList = Lists.newArrayList();
-        this.collectionLayoutData = null;
     }
 
-    private EntityCollectionModel(
-            final ObjectAdapterMemento parentAdapterMemento,
-            final OneToManyAssociation collection,
-            final CollectionLayoutData collectionLayoutData) {
+    private EntityCollectionModel(final EntityModel entityModel) {
+        this.entityModel = entityModel;
+        final OneToManyAssociation collection = collectionFor(entityModel.getObjectAdapterMemento(), getLayoutData());
         this.type = Type.PARENTED;
         this.typeOf = forName(collection.getSpecification());
-        this.parentObjectAdapterMemento = parentAdapterMemento;
         this.collectionMemento = new CollectionMemento(collection);
         this.pageSize = pageSize(collection.getFacet(PagedFacet.class), PAGE_SIZE_DEFAULT_FOR_PARENTED);
         final SortedByFacet sortedByFacet = collection.getFacet(SortedByFacet.class);
-        this.sortedBy = sortedByFacet != null?sortedByFacet.value(): null;
-        this.collectionLayoutData = collectionLayoutData;
+        this.sortedBy = sortedByFacet != null ? sortedByFacet.value(): null;
     }
     
-    private EntityCollectionModel(final EntityModel entityModel) {
-        this(entityModel.getObjectAdapterMemento(), (CollectionLayoutData) entityModel.getLayoutMetadata());
-    }
-
-    private EntityCollectionModel(final ObjectAdapterMemento parentObjectAdapterMemento, final CollectionLayoutData collectionLayoutData) {
-        this(parentObjectAdapterMemento, collectionFor(parentObjectAdapterMemento, collectionLayoutData), collectionLayoutData);
-    }
 
     private static OneToManyAssociation collectionFor(
             final ObjectAdapterMemento parentObjectAdapterMemento, final CollectionLayoutData collectionLayoutData) {
@@ -385,7 +376,7 @@ public class EntityCollectionModel extends ModelAbstract<List<ObjectAdapter>> im
      * Populated only if {@link Type#PARENTED}.
      */
     public CollectionLayoutData getLayoutData() {
-        return collectionLayoutData;
+        return (CollectionLayoutData) entityModel.getLayoutMetadata();
     }
 
     @Override
@@ -418,8 +409,15 @@ public class EntityCollectionModel extends ModelAbstract<List<ObjectAdapter>> im
     /**
      * Populated only if {@link Type#PARENTED}.
      */
+    public EntityModel getEntityModel() {
+        return entityModel;
+    }
+
+    /**
+     * Populated only if {@link Type#PARENTED}.
+     */
     public ObjectAdapterMemento getParentObjectAdapterMemento() {
-        return parentObjectAdapterMemento;
+        return entityModel != null? entityModel.getObjectAdapterMemento(): null;
     }
 
     /**
@@ -471,17 +469,28 @@ public class EntityCollectionModel extends ModelAbstract<List<ObjectAdapter>> im
     public static final String SESSION_ATTRIBUTE_SELECTED_ITEM = "selectedItem";
 
 
+    @Override
+    public String getHint(final Component component, final String attributeName) {
+        if(getEntityModel() == null) {
+            return null;
+        }
+        return getEntityModel().getHint(component, attributeName);
+    }
+
+    @Override
+    public void setHint(final Component component, final String attributeName, final String attributeValue) {
+        if(getEntityModel() == null) {
+            return;
+        }
+        getEntityModel().setHint(component, attributeName, attributeValue);
+    }
 
     @Override
-    protected void doSetHint(final String scopeKey, final String attributeName, final String value) {
-        if(isParented()) {
-            // same logic as in EntityModel's similar override
-            ScopedSessionAttribute scopedSessionAttribute = getSessionAttribute(attributeName);
-            if(scopedSessionAttribute == null) {
-                scopedSessionAttribute = ScopedSessionAttribute.create(parentObjectAdapterMemento, scopeKey, attributeName);
-            }
-            scopedSessionAttribute.set(value);
+    public void clearHint(final Component component, final String attributeName) {
+        if(getEntityModel() == null) {
+            return;
         }
+        getEntityModel().clearHint(component, attributeName);
     }
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/be5b3384/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
index 3f58b9e..6f6d59d 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
@@ -25,6 +25,7 @@ import java.util.Set;
 
 import com.google.common.collect.Maps;
 
+import org.apache.wicket.Component;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 
@@ -43,6 +44,7 @@ import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
 import org.apache.isis.core.runtime.services.memento.MementoServiceDefault;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.viewer.wicket.model.common.PageParametersUtils;
+import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
 import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
 import org.apache.isis.viewer.wicket.model.mementos.PageParameterNames;
 import org.apache.isis.viewer.wicket.model.mementos.PropertyMemento;
@@ -55,7 +57,7 @@ import org.apache.isis.viewer.wicket.model.util.ScopedSessionAttribute;
  * So that the model is {@link Serializable}, the {@link ObjectAdapter} is
  * stored as a {@link ObjectAdapterMemento}.
  */
-public class EntityModel extends BookmarkableModel<ObjectAdapter> {
+public class EntityModel extends BookmarkableModel<ObjectAdapter> implements UiHintContainer {
 
     private static final long serialVersionUID = 1L;
 
@@ -261,6 +263,86 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
     }
 
 
+    // //////////////////////////////////////////////////////////
+    // Hint support
+    // //////////////////////////////////////////////////////////
+
+    private final Map<String,ScopedSessionAttribute> sessionAttributeByName = Maps.newHashMap();
+
+    /**
+     * provides a mechanism to retrieve hints (identified by an attribute name) from the session.
+     */
+    public <T extends Serializable> ScopedSessionAttribute<T> getSessionAttribute(final String attributionName) {
+        return sessionAttributeByName.get(attributionName);
+    }
+
+    public void putSessionAttribute(final ScopedSessionAttribute<String> sessionAttribute) {
+        if(sessionAttribute == null || sessionAttribute.getAttributeName() == null) {
+            return;
+        }
+        this.sessionAttributeByName.put(sessionAttribute.getAttributeName(), sessionAttribute);
+    }
+
+    public void clearSelectedItemSessionAttribute(final String attributeName) {
+        this.sessionAttributeByName.remove(attributeName);
+    }
+
+
+    private final Map<String, String> hints = Maps.newTreeMap();
+
+    @Override
+    public String getHint(final Component component, final String attributeName) {
+        if(component == null) {
+            return null;
+        }
+        String hintKey = hintPathFor(component) + "-" + attributeName;
+        final ScopedSessionAttribute<String> sessionAttribute = getSessionAttribute(attributeName);
+        if(sessionAttribute != null) {
+            final String sessionHint = sessionAttribute.get();
+            if(sessionHint != null) {
+                return sessionHint;
+            }
+        }
+        return hints.get(hintKey);
+    }
+
+    @Override
+    public void setHint(Component component, String attributeName, String attributeValue) {
+        if(component == null) {
+            return;
+        }
+        final String scopeKey = hintPathFor(component);
+        String hintKey = scopeKey + "-" + attributeName;
+        if(attributeValue != null) {
+            hints.put(hintKey, attributeValue);
+        } else {
+            hints.remove(hintKey);
+        }
+
+        //
+
+        ScopedSessionAttribute scopedSessionAttribute = getSessionAttribute(attributeName);
+        if(scopedSessionAttribute == null) {
+            scopedSessionAttribute = ScopedSessionAttribute.create(this, scopeKey, attributeName);
+        }
+        scopedSessionAttribute.set(attributeValue);
+    }
+
+    @Override
+    public void clearHint(Component component, String attributeName) {
+        setHint(component, attributeName, null);
+    }
+
+    private static String hintPathFor(Component component)
+    {
+        return Util.hintPathFor(component);
+    }
+
+    protected Map<String, String> getHints() {
+        return hints;
+    }
+
+
     @Override
     public String getTitle() {
         return getObject().titleString(null);
@@ -570,14 +652,6 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
 
 
 
-    @Override
-    protected void doSetHint(final String scopeKey, final String attributeName, final String value) {
-        ScopedSessionAttribute scopedSessionAttribute = getSessionAttribute(attributeName);
-        if(scopedSessionAttribute == null) {
-            scopedSessionAttribute = ScopedSessionAttribute.create(this, scopeKey, attributeName);
-        }
-        scopedSessionAttribute.set(value);
-    }
 
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/be5b3384/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ModelAbstract.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ModelAbstract.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ModelAbstract.java
index cb06374..52b0d58 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ModelAbstract.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ModelAbstract.java
@@ -19,26 +19,18 @@
 
 package org.apache.isis.viewer.wicket.model.models;
 
-import java.io.Serializable;
-import java.util.Map;
-
-import com.google.common.collect.Maps;
-
-import org.apache.wicket.Component;
 import org.apache.wicket.model.LoadableDetachableModel;
 
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
-import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
-import org.apache.isis.viewer.wicket.model.util.ScopedSessionAttribute;
 
 /**
  * Adapter for {@link LoadableDetachableModel}s, providing access to some of the
  * Isis' dependencies.
  */
-public abstract class ModelAbstract<T> extends LoadableDetachableModel<T> implements UiHintContainer {
+public abstract class ModelAbstract<T> extends LoadableDetachableModel<T> {
 
     private static final long serialVersionUID = 1L;
 
@@ -50,84 +42,6 @@ public abstract class ModelAbstract<T> extends LoadableDetachableModel<T> implem
     }
 
 
-    // //////////////////////////////////////////////////////////
-    // Hint support
-    // //////////////////////////////////////////////////////////
-
-    private final Map<String,ScopedSessionAttribute> sessionAttributeByName = Maps.newHashMap();
-
-    /**
-     * provides a mechanism to retrieve hints (identified by an attribute name) from the session.
-     */
-    public <T extends Serializable> ScopedSessionAttribute<T> getSessionAttribute(final String attributionName) {
-        return sessionAttributeByName.get(attributionName);
-    }
-
-    public void putSessionAttribute(final ScopedSessionAttribute<String> sessionAttribute) {
-        if(sessionAttribute == null || sessionAttribute.getAttributeName() == null) {
-            return;
-        }
-        this.sessionAttributeByName.put(sessionAttribute.getAttributeName(), sessionAttribute);
-    }
-
-    public void clearSelectedItemSessionAttribute(final String attributeName) {
-        this.sessionAttributeByName.remove(attributeName);
-    }
-
-
-    private final Map<String, String> hints = Maps.newTreeMap();
-
-    public String getHint(final Component component, final String key) {
-        if(component == null) {
-            return null;
-        }
-        String hintKey = hintPathFor(component) + "-" + key;
-        final ScopedSessionAttribute<String> sessionAttribute = getSessionAttribute(key);
-        if(sessionAttribute != null) {
-            final String sessionHint = sessionAttribute.get();
-            if(sessionHint != null) {
-                return sessionHint;
-            }
-        }
-        return hints.get(hintKey);
-    }
-
-    @Override
-    public void setHint(Component component, String key, String value) {
-        if(component == null) {
-            return;
-        }
-        final String scopeKey = hintPathFor(component);
-        String hintKey = scopeKey + "-" + key;
-        if(value != null) {
-            hints.put(hintKey, value);
-        } else {
-            hints.remove(hintKey);
-        }
-        doSetHint(scopeKey, key, value);
-    }
-
-    /**
-     * Optional hook, eg to also store the hint in the session.
-     */
-    protected void doSetHint(final String scopeKey, final String attribute, final String value) {
-
-    }
-
-    @Override
-    public void clearHint(Component component, String key) {
-        setHint(component, key, null);
-    }
-
-    private static String hintPathFor(Component component)
-    {
-        return Util.hintPathFor(component);
-    }
-
-    protected Map<String, String> getHints() {
-        return hints;
-    }
-
     // //////////////////////////////////////////////////////////////
     // Dependencies
     // //////////////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/isis/blob/be5b3384/core/viewer-wicket-model/src/test/java/org/apache/isis/viewer/wicket/model/models/EntityModel_hintsTest.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/test/java/org/apache/isis/viewer/wicket/model/models/EntityModel_hintsTest.java b/core/viewer-wicket-model/src/test/java/org/apache/isis/viewer/wicket/model/models/EntityModel_hintsTest.java
new file mode 100644
index 0000000..4c48744
--- /dev/null
+++ b/core/viewer-wicket-model/src/test/java/org/apache/isis/viewer/wicket/model/models/EntityModel_hintsTest.java
@@ -0,0 +1,137 @@
+/**
+ *  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.viewer.wicket.model.models;
+
+import java.util.Map;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.jmock.Expectations;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+public class EntityModel_hintsTest {
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(JUnitRuleMockery2.Mode.INTERFACES_AND_CLASSES);
+
+    EntityModel target;
+
+    MarkupContainer mockParent;
+    Component mockComponent1;
+    Component mockComponent2;
+
+    @Before
+    public void setUp() throws Exception {
+        target = new EntityModel();
+
+        mockParent = context.mock(MarkupContainer.class, "parent");
+        mockComponent1 = context.mock(Component.class, "component1");
+        mockComponent2 = context.mock(Component.class, "component2");
+
+        context.checking(new Expectations() {{
+            allowing(mockParent).getId();
+            will(returnValue("parent"));
+
+            allowing(mockComponent1).getId();
+            will(returnValue("id1"));
+
+            allowing(mockComponent2).getId();
+            will(returnValue("id2"));
+
+            ignoring(mockComponent1);
+            ignoring(mockComponent2);
+
+        }});
+
+        mockComponent1.setParent(mockParent);
+        mockComponent2.setParent(mockParent);
+    }
+
+    public static class Hints extends EntityModel_hintsTest {
+
+        @Test
+        public void empty() throws Exception {
+            assertThat(target.getHint(mockComponent1, "key1"), is(nullValue()));
+        }
+
+        @Test
+        public void single() throws Exception {
+            target.setHint(mockComponent1, "key1", "value1");
+            assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
+        }
+
+        @Test
+        public void clear() throws Exception {
+            target.setHint(mockComponent1, "key1", "value1");
+            assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
+            target.clearHint(mockComponent1, "key1");
+            assertThat(target.getHint(mockComponent1, "key1"), is(nullValue()));
+        }
+
+        @Test
+        public void setToNull() throws Exception {
+            target.setHint(mockComponent1, "key1", "value1");
+            assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
+            target.setHint(mockComponent1, "key1", null);
+            assertThat(target.getHint(mockComponent1, "key1"), is(nullValue()));
+        }
+
+        @Test
+        public void multipleKeys() throws Exception {
+            target.setHint(mockComponent1, "key1", "value1");
+            target.setHint(mockComponent1, "key2", "value2");
+            assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
+            assertThat(target.getHint(mockComponent1, "key2"), is("value2"));
+        }
+
+        @Test
+        public void multipleComponents() throws Exception {
+            target.setHint(mockComponent1, "key", "valueA");
+            target.setHint(mockComponent2, "key", "valueB");
+            assertThat(target.getHint(mockComponent1, "key"), is("valueA"));
+            assertThat(target.getHint(mockComponent2, "key"), is("valueB"));
+        }
+
+        @Test
+        public void smoke() throws Exception {
+            target.setHint(mockComponent1, "X", "1.X");
+            target.setHint(mockComponent1, "A", "1.A");
+            target.setHint(mockComponent1, "B", "1.B");
+            target.setHint(mockComponent1, "C", "1.C");
+            target.setHint(mockComponent2, "X", "2.X");
+            target.setHint(mockComponent2, "P", "2.P");
+            target.setHint(mockComponent2, "Q", "2.Q");
+            target.setHint(mockComponent2, "R", "2.R");
+
+            final Map<String, String> hints = target.getHints();
+            assertThat(hints.size(), is(8));
+            assertThat(hints.get("id1-X"), is("1.X"));
+            assertThat(hints.get("id2-X"), is("2.X"));
+            assertThat(hints.get("id1-B"), is("1.B"));
+            assertThat(hints.get("id2-R"), is("2.R"));
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/be5b3384/core/viewer-wicket-model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java b/core/viewer-wicket-model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java
deleted file mode 100644
index d7dc520..0000000
--- a/core/viewer-wicket-model/src/test/java/org/apache/isis/viewer/wicket/model/models/ModelAbstractTest.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
- *  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.viewer.wicket.model.models;
-
-import java.util.Map;
-
-import org.apache.wicket.Component;
-import org.apache.wicket.MarkupContainer;
-import org.jmock.Expectations;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertThat;
-
-public class ModelAbstractTest {
-
-    @Rule
-    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(JUnitRuleMockery2.Mode.INTERFACES_AND_CLASSES);
-
-    ModelAbstract<String> target;
-
-    MarkupContainer mockParent;
-    Component mockComponent1;
-    Component mockComponent2;
-
-    @Before
-    public void setUp() throws Exception {
-        target = new ModelAbstract<String>("foo"){
-            @Override
-            protected String load() {
-                return null;
-            }
-        };
-
-        mockParent = context.mock(MarkupContainer.class, "parent");
-        mockComponent1 = context.mock(Component.class, "component1");
-        mockComponent2 = context.mock(Component.class, "component2");
-
-        context.checking(new Expectations() {{
-            allowing(mockParent).getId();
-            will(returnValue("parent"));
-
-            allowing(mockComponent1).getId();
-            will(returnValue("id1"));
-
-            allowing(mockComponent2).getId();
-            will(returnValue("id2"));
-
-            ignoring(mockComponent1);
-            ignoring(mockComponent2);
-
-        }});
-
-        mockComponent1.setParent(mockParent);
-        mockComponent2.setParent(mockParent);
-    }
-
-    public static class Hints extends ModelAbstractTest {
-
-        @Test
-        public void empty() throws Exception {
-            assertThat(target.getHint(mockComponent1, "key1"), is(nullValue()));
-        }
-
-        @Test
-        public void single() throws Exception {
-            target.setHint(mockComponent1, "key1", "value1");
-            assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
-        }
-
-        @Test
-        public void clear() throws Exception {
-            target.setHint(mockComponent1, "key1", "value1");
-            assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
-            target.clearHint(mockComponent1, "key1");
-            assertThat(target.getHint(mockComponent1, "key1"), is(nullValue()));
-        }
-
-        @Test
-        public void setToNull() throws Exception {
-            target.setHint(mockComponent1, "key1", "value1");
-            assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
-            target.setHint(mockComponent1, "key1", null);
-            assertThat(target.getHint(mockComponent1, "key1"), is(nullValue()));
-        }
-
-        @Test
-        public void multipleKeys() throws Exception {
-            target.setHint(mockComponent1, "key1", "value1");
-            target.setHint(mockComponent1, "key2", "value2");
-            assertThat(target.getHint(mockComponent1, "key1"), is("value1"));
-            assertThat(target.getHint(mockComponent1, "key2"), is("value2"));
-        }
-
-        @Test
-        public void multipleComponents() throws Exception {
-            target.setHint(mockComponent1, "key", "valueA");
-            target.setHint(mockComponent2, "key", "valueB");
-            assertThat(target.getHint(mockComponent1, "key"), is("valueA"));
-            assertThat(target.getHint(mockComponent2, "key"), is("valueB"));
-        }
-
-        @Test
-        public void smoke() throws Exception {
-            target.setHint(mockComponent1, "X", "1.X");
-            target.setHint(mockComponent1, "A", "1.A");
-            target.setHint(mockComponent1, "B", "1.B");
-            target.setHint(mockComponent1, "C", "1.C");
-            target.setHint(mockComponent2, "X", "2.X");
-            target.setHint(mockComponent2, "P", "2.P");
-            target.setHint(mockComponent2, "Q", "2.Q");
-            target.setHint(mockComponent2, "R", "2.R");
-
-            final Map<String, String> hints = target.getHints();
-            assertThat(hints.size(), is(8));
-            assertThat(hints.get("id1-X"), is("1.X"));
-            assertThat(hints.get("id2-X"), is("2.X"));
-            assertThat(hints.get("id1-B"), is("1.B"));
-            assertThat(hints.get("id2-R"), is("2.R"));
-        }
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/be5b3384/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
index 5a1b305..d03928e 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
@@ -49,7 +49,6 @@ import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel
  */
 public class CollectionPanel extends PanelAbstract<EntityCollectionModel> implements CollectionSelectorProvider {
 
-
     private static final long serialVersionUID = 1L;
 
     private static final String ID_FEEDBACK = "feedback";
@@ -61,21 +60,18 @@ public class CollectionPanel extends PanelAbstract<EntityCollectionModel> implem
     public CollectionPanel(
             final String id,
             final EntityCollectionModel collectionModel) {
-        this(id, collectionModel, new EntityModel(collectionModel.getParentObjectAdapterMemento()), collectionModel.getCollectionMemento().getCollection());
-    }
-
-    CollectionPanel(
-            final String id,
-            final EntityCollectionModel collectionModel,
-            final EntityModel entityModel,
-            final OneToManyAssociation otma) {
         super(id, collectionModel);
 
         final List<LinkAndLabel> entityActionLinks = Lists.newArrayList();
 
-        final List<ObjectAction> associatedActions = EntityActionUtil.getObjectActionsForAssociation(entityModel, otma, getDeploymentType());
+        final OneToManyAssociation otma = collectionModel.getCollectionMemento().getCollection();
+        final EntityModel entityModel = collectionModel.getEntityModel();
+
+        final List<ObjectAction> associatedActions =
+                EntityActionUtil.getObjectActionsForAssociation(entityModel, otma, getDeploymentType());
 
-        entityActionLinks.addAll(EntityActionUtil.asLinkAndLabelsForAdditionalLinksPanel(entityModel, associatedActions));
+        entityActionLinks.addAll(
+                EntityActionUtil.asLinkAndLabelsForAdditionalLinksPanel(entityModel, associatedActions));
 
         collectionModel.addEntityActions(entityActionLinks);
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/be5b3384/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/selector/CollectionSelectorHelper.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/selector/CollectionSelectorHelper.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/selector/CollectionSelectorHelper.java
index 69510d3..7bf15b2 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/selector/CollectionSelectorHelper.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/selector/CollectionSelectorHelper.java
@@ -72,7 +72,7 @@ public class CollectionSelectorHelper implements Serializable {
                 selectedItemSessionAttribute != null
                         ? selectedItemSessionAttribute
                         : ScopedSessionAttribute.<String>noop();
-        model.putSessionAttribute(selectedItemSessionAttribute);
+        model.getEntityModel().putSessionAttribute(selectedItemSessionAttribute);
     }
 
     private List<ComponentFactory> locateComponentFactories(ComponentFactoryRegistry componentFactoryRegistry) {

http://git-wip-us.apache.org/repos/asf/isis/blob/be5b3384/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/multiple/CollectionContentsMultipleViewsPanel.java
----------------------------------------------------------------------
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/multiple/CollectionContentsMultipleViewsPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/multiple/CollectionContentsMultipleViewsPanel.java
index 333c852..56e88d4 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/multiple/CollectionContentsMultipleViewsPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/multiple/CollectionContentsMultipleViewsPanel.java
@@ -30,6 +30,8 @@ import org.apache.isis.viewer.wicket.model.hints.IsisEnvelopeEvent;
 import org.apache.isis.viewer.wicket.model.hints.IsisUiHintEvent;
 import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
 import org.apache.isis.viewer.wicket.model.models.EntityCollectionModel;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.model.util.ScopedSessionAttribute;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.components.collection.count.CollectionCountProvider;
@@ -65,8 +67,18 @@ public class CollectionContentsMultipleViewsPanel
             final String id,
             final EntityCollectionModel model) {
         super(id, model);
+
         this.underlyingIdPrefix = ComponentType.COLLECTION_CONTENTS.toString();
-        selectorHelper = new CollectionSelectorHelper(model, getComponentFactoryRegistry(), model.<String>getSessionAttribute(EntityCollectionModel.SESSION_ATTRIBUTE_SELECTED_ITEM));
+        final EntityModel entityModel = model.getEntityModel();
+
+        final ScopedSessionAttribute<String> selectedItemSessionAttribute =
+                entityModel != null
+                        ? entityModel.<String>getSessionAttribute(
+                                EntityCollectionModel.SESSION_ATTRIBUTE_SELECTED_ITEM)
+                        : null;
+
+        selectorHelper = new CollectionSelectorHelper(
+                model, getComponentFactoryRegistry(), selectedItemSessionAttribute);
     }
 
     /**