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 2014/11/10 11:23:23 UTC

[16/23] isis git commit: ISIS-537: completed factoring out of CollectionContentsSelectorHelper.

ISIS-537: completed factoring out of CollectionContentsSelectorHelper.


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

Branch: refs/heads/ISIS-939
Commit: 7087fc25ece5113839975db3b83ae4d1c78d041a
Parents: 457b365
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Sun Nov 9 15:52:49 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Mon Nov 10 10:21:43 2014 +0000

----------------------------------------------------------------------
 ...CollectionContentsSelectorDropdownPanel.java | 247 +--------------
 .../CollectionContentsSelectorHelper.java       |  97 +++++-
 .../CollectionContentsLinksSelectorPanel.java   | 315 +------------------
 ...ectionContentsSelectorDropdownPanelTest.java |   2 +-
 4 files changed, 122 insertions(+), 539 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/7087fc25/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorDropdownPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorDropdownPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorDropdownPanel.java
index 0903d2a..37797c5 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorDropdownPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorDropdownPanel.java
@@ -21,13 +21,8 @@ package org.apache.isis.viewer.wicket.ui.components.collectioncontents.selector.
 
 import de.agilecoders.wicket.core.markup.html.bootstrap.button.Buttons;
 
-import java.util.ArrayList;
 import java.util.List;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
 import org.apache.wicket.AttributeModifier;
-import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.event.Broadcast;
@@ -40,10 +35,7 @@ import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
-import org.apache.isis.applib.annotation.Render.Type;
 import org.apache.isis.core.commons.lang.StringExtensions;
-import org.apache.isis.core.metamodel.facets.members.render.RenderFacet;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 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.hints.UiHintPathSignificant;
@@ -51,13 +43,9 @@ import org.apache.isis.viewer.wicket.model.models.EntityCollectionModel;
 import org.apache.isis.viewer.wicket.ui.CollectionContentsAsFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
-import org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.CollectionContentsAsAjaxTablePanelFactory;
-import org.apache.isis.viewer.wicket.ui.components.collectioncontents.selector.links.CollectionContentsLinksSelectorPanelFactory;
-import org.apache.isis.viewer.wicket.ui.components.collectioncontents.unresolved.CollectionContentsAsUnresolvedPanelFactory;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.panels.PanelUtil;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
-import org.apache.isis.viewer.wicket.ui.util.CssClassRemover;
 
 /**
  * Provides a list of links for selecting other views that support
@@ -69,9 +57,6 @@ public class CollectionContentsSelectorDropdownPanel
 
     private static final long serialVersionUID = 1L;
 
-    private static final String INVISIBLE_CLASS = "link-selector-panel-invisible";
-//    private static final int MAX_NUM_UNDERLYING_VIEWS = 10;
-
     private static final String ID_VIEWS = "views";
     private static final String ID_VIEW_LIST = "viewList";
     private static final String ID_VIEW_LINK = "viewLink";
@@ -79,23 +64,18 @@ public class CollectionContentsSelectorDropdownPanel
     private static final String ID_VIEW_ITEM_TITLE = "viewItemTitle";
     private static final String ID_VIEW_ITEM_ICON = "viewItemIcon";
 
-    private static final String UIHINT_VIEW = "view";
     private static final String ID_VIEW_BUTTON_TITLE = "viewButtonTitle";
     private static final String ID_VIEW_BUTTON_ICON = "viewButtonIcon";
 
     private final ComponentType componentType;
+    private final CollectionContentsSelectorHelper selectorHelper;
 
     private ComponentFactory selectedComponentFactory;
-//    private Component selectedComponent;
-
-//    /**
-//     * May be <tt>null</tt>, depending upon the model implementation.
-//     */
-//    protected WebMarkupContainer additionalLinks;
 
-    public CollectionContentsSelectorDropdownPanel(final String id, final EntityCollectionModel model, final ComponentFactory factory) {
+    public CollectionContentsSelectorDropdownPanel(final String id, final EntityCollectionModel model, final ComponentFactory ignoreFactory) {
         super(id, model);
-        this.componentType = factory.getComponentType();
+        this.componentType = ignoreFactory.getComponentType();
+        selectorHelper = new CollectionContentsSelectorHelper(model, getComponentFactoryRegistry(), ignoreFactory);
     }
 
     /**
@@ -103,36 +83,14 @@ public class CollectionContentsSelectorDropdownPanel
      */
     public void onInitialize() {
         super.onInitialize();
-        ComponentFactory componentFactory = getComponentFactoryRegistry().findComponentFactoryElseFailFast(getComponentType(), getModel());
-        addUnderlyingViews(getModel(), componentFactory);
+        addDropdown();
     }
 
 
-    private void addUnderlyingViews(final EntityCollectionModel model, final ComponentFactory factory) {
-        final List<ComponentFactory> componentFactories = findOtherComponentFactories(model, factory);
-
-        final int selected = honourViewHintElseDefault(componentFactories, model);
 
-        final CollectionContentsSelectorDropdownPanel selectorPanel = this;
-
-        // create all, hide the one not selected
-//        final Component[] underlyingViews = new Component[MAX_NUM_UNDERLYING_VIEWS];
-//        int i = 0;
-//        final EntityCollectionModel emptyModel = model.asDummy();
-//        for (ComponentFactory componentFactory : componentFactories) {
-//            final String underlyingId = underlyingIdPrefix + "-" + i;
-//
-//            Component underlyingView = componentFactory.createComponent(underlyingId,i==selected? model: emptyModel);
-//            underlyingViews[i++] = underlyingView;
-//            selectorPanel.addOrReplace(underlyingView);
-//        }
-
-//        // hide any unused placeholders
-//        while(i<MAX_NUM_UNDERLYING_VIEWS) {
-//            String underlyingId = underlyingIdPrefix + "-" + i;
-//            permanentlyHide(underlyingId);
-//            i++;
-//        }
+    private void addDropdown() {
+        final List<ComponentFactory> componentFactories = selectorHelper.findOtherComponentFactories();
+        final int selected = selectorHelper.honourViewHintElseDefault(this);
 
         // selector
         if (componentFactories.size() <= 1) {
@@ -140,8 +98,8 @@ public class CollectionContentsSelectorDropdownPanel
         } else {
             final Model<ComponentFactory> componentFactoryModel = new Model<>();
 
-            selectorPanel.selectedComponentFactory = componentFactories.get(selected);
-            componentFactoryModel.setObject(selectorPanel.selectedComponentFactory);
+            this.selectedComponentFactory = componentFactories.get(selected);
+            componentFactoryModel.setObject(this.selectedComponentFactory);
 
             final WebMarkupContainer views = new WebMarkupContainer(ID_VIEWS);
 
@@ -175,21 +133,8 @@ public class CollectionContentsSelectorDropdownPanel
                             CollectionContentsSelectorDropdownPanel linksSelectorPanel = CollectionContentsSelectorDropdownPanel.this;
                             linksSelectorPanel.setViewHintAndBroadcast(underlyingViewNum, target);
 
-//                            final EntityCollectionModel dummyModel = model.asDummy();
-//                            for(int i=0; i<MAX_NUM_UNDERLYING_VIEWS; i++) {
-//                                final Component component = underlyingViews[i];
-//                                if(component == null) {
-//                                    continue;
-//                                }
-//                                final boolean isSelected = i == underlyingViewNum;
-//                                applyCssVisibility(component, isSelected);
-//                                component.setDefaultModel(isSelected? model: dummyModel);
-//                            }
-
-                            selectorPanel.selectedComponentFactory = componentFactory;
-//                            selectorPanel.selectedComponent = underlyingViews[underlyingViewNum];
-//                            selectorPanel.onSelect(target);
-                            target.add(selectorPanel, views);
+                            CollectionContentsSelectorDropdownPanel.this.selectedComponentFactory = componentFactory;
+                            target.add(CollectionContentsSelectorDropdownPanel.this, views);
                         }
 
                         @Override
@@ -206,7 +151,7 @@ public class CollectionContentsSelectorDropdownPanel
                     Label viewItemIcon = new Label(ID_VIEW_ITEM_ICON, "");
                     link.add(viewItemIcon);
 
-                    boolean isEnabled = componentFactory != selectorPanel.selectedComponentFactory;
+                    boolean isEnabled = componentFactory != CollectionContentsSelectorDropdownPanel.this.selectedComponentFactory;
                     if (!isEnabled) {
                         viewButtonTitle.setDefaultModel(title);
                         IModel<String> cssClass = cssClassFor(componentFactory, viewButtonIcon);
@@ -255,17 +200,6 @@ public class CollectionContentsSelectorDropdownPanel
             container.add(listView);
             addOrReplace(views);
         }
-
-//        for(i=0; i<MAX_NUM_UNDERLYING_VIEWS; i++) {
-//            Component component = underlyingViews[i];
-//            if(component != null) {
-//                if(i != selected) {
-//                    component.add(new CssClassAppender(INVISIBLE_CLASS));
-//                } else {
-//                    selectedComponent = component;
-//                }
-//            }
-//        }
     }
 
 
@@ -275,167 +209,14 @@ public class CollectionContentsSelectorDropdownPanel
         if(uiHintContainer == null) {
             return;
         }
-        uiHintContainer.setHint(CollectionContentsSelectorDropdownPanel.this, UIHINT_VIEW, ""+viewNum);
+        uiHintContainer.setHint(CollectionContentsSelectorDropdownPanel.this, CollectionContentsSelectorHelper.UIHINT_VIEW, ""+viewNum);
         send(getPage(), Broadcast.EXACT, new IsisUiHintEvent(uiHintContainer, target));
     }
 
-//    /**
-//     * Iterates up the component hierarchy looking for a parent
-//     * {@link org.apache.isis.viewer.wicket.ui.components.collection.CollectionPanel}, and if so adds to ajax target so that it'll
-//     * be repainted.
-//     *
-//     * <p>
-//     * Yeah, agreed, it's a little bit hacky doing it this way, because it bakes
-//     * in knowledge that this component is created, somehow, by a parent {@link org.apache.isis.viewer.wicket.ui.components.collection.CollectionPanel}.
-//     * Perhaps it could be refactored to use a more general purpose observer pattern?
-//     *
-//     * <p>
-//     * In fact, I've since discovered that Wicket has an event bus, which is used by the
-//     * {@link org.apache.isis.viewer.wicket.model.hints.UiHintContainer hinting mechanism}.  So this ought to be relatively easy to do.
-//     */
-//    public void onSelect(AjaxRequestTarget target) {
-//        Component component = this;
-//        while(component != null) {
-//            if(component instanceof CollectionPanel) {
-//                CollectionPanel collectionPanel = (CollectionPanel) component;
-//                boolean hasCount = collectionPanel.hasCount();
-//                if(hasCount) {
-//                    collectionPanel.updateLabel(target);
-//                }
-////                if(additionalLinks != null) {
-////                    applyCssVisibility(additionalLinks, hasCount);
-////                }
-//                return;
-//            }
-//            component = component.getParent();
-//        }
-//    }
-
-
-    protected static void applyCssVisibility(final Component component, final boolean visible) {
-        if(component == null) {
-            return;
-        }
-        AttributeModifier modifier = visible ? new CssClassRemover(INVISIBLE_CLASS) : new CssClassAppender(INVISIBLE_CLASS);
-        component.add(modifier);
-    }
-
-    protected int honourViewHintElseDefault(final List<ComponentFactory> componentFactories, final IModel<?> model) {
-        // honour hints ...
-        final UiHintContainer hintContainer = getUiHintContainer();
-        if(hintContainer != null) {
-            String viewStr = hintContainer.getHint(this, UIHINT_VIEW);
-            if(viewStr != null) {
-                try {
-                    int view = Integer.parseInt(viewStr);
-                    if(view >= 0 && view < componentFactories.size()) {
-                        return view;
-                    }
-                } catch(NumberFormatException ex) {
-                    // ignore
-                }
-            }
-        }
-
-        // ... else default
-        int initialFactory = determineInitialFactory(componentFactories, model);
-        if(hintContainer != null) {
-            hintContainer.setHint(this, UIHINT_VIEW, ""+initialFactory);
-            // don't broadcast (no AjaxRequestTarget, still configuring initial setup)
-        }
-        return initialFactory;
-    }
-
-
-    /**
-     * return the index of {@link org.apache.isis.viewer.wicket.ui.components.collectioncontents.unresolved.CollectionContentsAsUnresolvedPanelFactory unresolved panel} if present and not eager loading;
-     * else the index of {@link org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.CollectionContentsAsAjaxTablePanelFactory ajax table} if present,
-     * otherwise first factory.
-     */
-    protected int determineInitialFactory(final List<ComponentFactory> componentFactories, final IModel<?> model) {
-        if(!hasRenderEagerlyFacet(model)) {
-            for(int i=0; i<componentFactories.size(); i++) {
-                if(componentFactories.get(i) instanceof CollectionContentsAsUnresolvedPanelFactory) {
-                    return i;
-                }
-            }
-        }
-        int ajaxTableIdx = findAjaxTable(componentFactories);
-        if(ajaxTableIdx>=0) {
-            return ajaxTableIdx;
-        }
-        return 0;
-    }
-
-    private List<ComponentFactory> findOtherComponentFactories(final EntityCollectionModel model, final ComponentFactory ignoreFactory) {
-        final List<ComponentFactory> componentFactories = getComponentFactoryRegistry().findComponentFactories(componentType, model);
-        ArrayList<ComponentFactory> otherFactories = Lists.newArrayList(Collections2.filter(componentFactories, new Predicate<ComponentFactory>() {
-            @Override
-            public boolean apply(final ComponentFactory input) {
-                return input != ignoreFactory && input.getClass() != CollectionContentsLinksSelectorPanelFactory.class;
-            }
-        }));
-        return ordered(otherFactories);
-    }
-
-    protected List<ComponentFactory> ordered(List<ComponentFactory> componentFactories) {
-        return orderAjaxTableToEnd(componentFactories);
-    }
-
-
     @Override
     public void renderHead(final IHeaderResponse response) {
         super.renderHead(response);
         PanelUtil.renderHead(response, CollectionContentsSelectorDropdownPanel.class);
     }
 
-
-    static List<ComponentFactory> orderAjaxTableToEnd(List<ComponentFactory> componentFactories) {
-        int ajaxTableIdx = findAjaxTable(componentFactories);
-        if(ajaxTableIdx>=0) {
-            List<ComponentFactory> orderedFactories = Lists.newArrayList(componentFactories);
-            ComponentFactory ajaxTableFactory = orderedFactories.remove(ajaxTableIdx);
-            orderedFactories.add(ajaxTableFactory);
-            return orderedFactories;
-        } else {
-            return componentFactories;
-        }
-    }
-    
-    private static int findAjaxTable(List<ComponentFactory> componentFactories) {
-        for(int i=0; i<componentFactories.size(); i++) {
-            if(componentFactories.get(i) instanceof CollectionContentsAsAjaxTablePanelFactory) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    private static boolean hasRenderEagerlyFacet(IModel<?> model) {
-        if(!(model instanceof EntityCollectionModel)) {
-            return false;
-        }
-        final EntityCollectionModel entityCollectionModel = (EntityCollectionModel) model;
-        if(!entityCollectionModel.isParented()) {
-            return false;
-        }
-
-        final OneToManyAssociation collection = 
-                entityCollectionModel.getCollectionMemento().getCollection();
-        RenderFacet renderFacet = collection.getFacet(RenderFacet.class);
-        return renderFacet != null && renderFacet.value() == Type.EAGERLY;
-    }
-
-
-//    @Override
-//    public Integer getCount() {
-//        if(selectedComponent instanceof CollectionCountProvider) {
-//            final CollectionCountProvider collectionCountProvider = (CollectionCountProvider) selectedComponent;
-//            return collectionCountProvider.getCount();
-//        } else {
-//            return null;
-//        }
-//    }
-
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/7087fc25/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorHelper.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorHelper.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorHelper.java
index 6b796b5..1e3706c 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorHelper.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorHelper.java
@@ -24,34 +24,51 @@ import java.util.List;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.Lists;
+import org.apache.wicket.Component;
+import org.apache.wicket.model.IModel;
+import org.apache.isis.applib.annotation.Render;
+import org.apache.isis.core.metamodel.facets.members.render.RenderFacet;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
 import org.apache.isis.viewer.wicket.model.models.EntityCollectionModel;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistry;
 import org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.CollectionContentsAsAjaxTablePanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.collectioncontents.selector.links.CollectionContentsLinksSelectorPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.collectioncontents.unresolved.CollectionContentsAsUnresolvedPanelFactory;
 
 public class CollectionContentsSelectorHelper {
 
+    static final String UIHINT_VIEW = "view";
     private static final long serialVersionUID = 1L;
 
     private final ComponentType componentType;
     private final ComponentFactoryRegistry componentFactoryRegistry;
     private final EntityCollectionModel model;
     private final ComponentFactory ignoreFactory;
+    private final List<ComponentFactory> componentFactories;
 
 
     public CollectionContentsSelectorHelper(
-            final ComponentType componentType,
-            final ComponentFactoryRegistry componentFactoryRegistry,
             final EntityCollectionModel model,
+            final ComponentFactoryRegistry componentFactoryRegistry,
             final ComponentFactory ignoreFactory) {
-        this.componentType = componentType;
         this.componentFactoryRegistry = componentFactoryRegistry;
         this.model = model;
         this.ignoreFactory = ignoreFactory;
+        this.componentType = ignoreFactory.getComponentType();
+
+        componentFactories = findOtherComponentFactories();
+
     }
 
+    public ComponentFactory getComponentFactory() {
+        return componentFactoryRegistry.findComponentFactoryElseFailFast(componentType, model);
+    }
+
+
+
 
     public List<ComponentFactory> findOtherComponentFactories() {
         final List<ComponentFactory> componentFactories = componentFactoryRegistry.findComponentFactories(componentType, model);
@@ -64,12 +81,10 @@ public class CollectionContentsSelectorHelper {
         return ordered(otherFactories);
     }
 
-    private static List<ComponentFactory> ordered(List<ComponentFactory> componentFactories) {
+    protected List<ComponentFactory> ordered(List<ComponentFactory> componentFactories) {
         return orderAjaxTableToEnd(componentFactories);
     }
 
-
-
     static List<ComponentFactory> orderAjaxTableToEnd(List<ComponentFactory> componentFactories) {
         int ajaxTableIdx = findAjaxTable(componentFactories);
         if(ajaxTableIdx>=0) {
@@ -82,7 +97,7 @@ public class CollectionContentsSelectorHelper {
         }
     }
 
-    public static int findAjaxTable(List<ComponentFactory> componentFactories) {
+    static int findAjaxTable(List<ComponentFactory> componentFactories) {
         for(int i=0; i<componentFactories.size(); i++) {
             if(componentFactories.get(i) instanceof CollectionContentsAsAjaxTablePanelFactory) {
                 return i;
@@ -93,4 +108,72 @@ public class CollectionContentsSelectorHelper {
 
 
 
+
+
+    public int honourViewHintElseDefault(final Component component) {
+        // honour hints ...
+        final UiHintContainer hintContainer = getUiHintContainer(component);
+        if(hintContainer != null) {
+            String viewStr = hintContainer.getHint(component, UIHINT_VIEW);
+            if(viewStr != null) {
+                try {
+                    int view = Integer.parseInt(viewStr);
+                    if(view >= 0 && view < componentFactories.size()) {
+                        return view;
+                    }
+                } catch(NumberFormatException ex) {
+                    // ignore
+                }
+            }
+        }
+
+        // ... else default
+        int initialFactory = determineInitialFactory(componentFactories, model);
+        if(hintContainer != null) {
+            hintContainer.setHint(component, UIHINT_VIEW, ""+initialFactory);
+            // don't broadcast (no AjaxRequestTarget, still configuring initial setup)
+        }
+        return initialFactory;
+    }
+
+    public static UiHintContainer getUiHintContainer(final Component component) {
+        return UiHintContainer.Util.hintContainerOf(component);
+    }
+
+
+    /**
+     * return the index of {@link org.apache.isis.viewer.wicket.ui.components.collectioncontents.unresolved.CollectionContentsAsUnresolvedPanelFactory unresolved panel} if present and not eager loading;
+     * else the index of {@link org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.CollectionContentsAsAjaxTablePanelFactory ajax table} if present,
+     * otherwise first factory.
+     */
+    protected int determineInitialFactory(final List<ComponentFactory> componentFactories, final IModel<?> model) {
+        if(!hasRenderEagerlyFacet(model)) {
+            for(int i=0; i<componentFactories.size(); i++) {
+                if(componentFactories.get(i) instanceof CollectionContentsAsUnresolvedPanelFactory) {
+                    return i;
+                }
+            }
+        }
+        int ajaxTableIdx = CollectionContentsSelectorHelper.findAjaxTable(componentFactories);
+        if(ajaxTableIdx>=0) {
+            return ajaxTableIdx;
+        }
+        return 0;
+    }
+
+    private static boolean hasRenderEagerlyFacet(IModel<?> model) {
+        if(!(model instanceof EntityCollectionModel)) {
+            return false;
+        }
+        final EntityCollectionModel entityCollectionModel = (EntityCollectionModel) model;
+        if(!entityCollectionModel.isParented()) {
+            return false;
+        }
+
+        final OneToManyAssociation collection =
+                entityCollectionModel.getCollectionMemento().getCollection();
+        RenderFacet renderFacet = collection.getFacet(RenderFacet.class);
+        return renderFacet != null && renderFacet.value() == Render.Type.EAGERLY;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/7087fc25/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/links/CollectionContentsLinksSelectorPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/links/CollectionContentsLinksSelectorPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/links/CollectionContentsLinksSelectorPanel.java
index f29244f..fd0a3da 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/links/CollectionContentsLinksSelectorPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/links/CollectionContentsLinksSelectorPanel.java
@@ -19,21 +19,13 @@
 
 package org.apache.isis.viewer.wicket.ui.components.collectioncontents.selector.links;
 
-import java.util.ArrayList;
 import java.util.List;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
 import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.event.IEvent;
 import org.apache.wicket.markup.head.IHeaderResponse;
-import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
-import org.apache.isis.applib.annotation.Render.Type;
-import org.apache.isis.core.metamodel.facets.members.render.RenderFacet;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 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;
@@ -42,9 +34,8 @@ import org.apache.isis.viewer.wicket.model.models.EntityCollectionModel;
 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.CollectionCountProvider;
-import org.apache.isis.viewer.wicket.ui.components.collectioncontents.ajaxtable.CollectionContentsAsAjaxTablePanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.collectioncontents.selector.dropdown.CollectionContentsSelectorDropdownPanel;
-import org.apache.isis.viewer.wicket.ui.components.collectioncontents.unresolved.CollectionContentsAsUnresolvedPanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.collectioncontents.selector.dropdown.CollectionContentsSelectorHelper;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.panels.PanelUtil;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
@@ -65,30 +56,17 @@ public class CollectionContentsLinksSelectorPanel
 
     private static final String ID_SELECTOR_DROPDOWN = "selectorDropdown";
 
-//    private static final String ID_VIEWS = "views";
-//    private static final String ID_VIEW_LIST = "viewList";
-//    private static final String ID_VIEW_LINK = "viewLink";
-//    private static final String ID_VIEW_ITEM = "viewItem";
-//    private static final String ID_VIEW_ITEM_TITLE = "viewItemTitle";
-//    private static final String ID_VIEW_ITEM_ICON = "viewItemIcon";
-
     private static final String UIHINT_VIEW = "view";
-//    private static final String ID_VIEW_BUTTON_TITLE = "viewButtonTitle";
-//    private static final String ID_VIEW_BUTTON_ICON = "viewButtonIcon";
 
-    private final ComponentFactory componentFactory;
+    private final ComponentFactory ignoreFactory;
 
     private final ComponentType componentType;
     private final String underlyingIdPrefix;
+    private final CollectionContentsSelectorHelper selectorHelper;
 
     private ComponentFactory selectedComponentFactory;
     protected Component selectedComponent;
 
-//    /**
-//     * May be <tt>null</tt>, depending upon the model implementation.
-//     */
-//    protected WebMarkupContainer additionalLinks;
-
     private Component[] underlyingViews;
     private List<ComponentFactory> componentFactories;
     private CollectionContentsSelectorDropdownPanel selectorDropdownPanel;
@@ -96,11 +74,14 @@ public class CollectionContentsLinksSelectorPanel
     public CollectionContentsLinksSelectorPanel(
             final String id,
             final EntityCollectionModel model,
-            final ComponentFactory factory) {
+            final ComponentFactory ignoreFactory) {
         super(id, model);
-        componentFactory = factory;
+        this.ignoreFactory = ignoreFactory;
         this.underlyingIdPrefix = ComponentType.COLLECTION_CONTENTS.toString();
-        this.componentType = factory.getComponentType();
+        this.componentType = ignoreFactory.getComponentType();
+        selectorHelper = new CollectionContentsSelectorHelper(model, getComponentFactoryRegistry(), ignoreFactory);
+
+        componentFactories = selectorHelper.findOtherComponentFactories();
     }
 
     /**
@@ -108,18 +89,14 @@ public class CollectionContentsLinksSelectorPanel
      */
     public void onInitialize() {
         super.onInitialize();
-        ComponentFactory componentFactory = getComponentFactoryRegistry().findComponentFactoryElseFailFast(getComponentType(), getModel());
-        addUnderlyingViews(componentFactory);
+        addUnderlyingViews();
     }
 
 
-    private void addUnderlyingViews(final ComponentFactory factory) {
+    private void addUnderlyingViews() {
         final EntityCollectionModel model = getModel();
-        componentFactories = findOtherComponentFactories(model, factory);
 
-        final int selected = honourViewHintElseDefault(componentFactories, model);
-
-        final CollectionContentsLinksSelectorPanel selectorPanel = this;
+        final int selected = selectorHelper.honourViewHintElseDefault(this);
 
         // create all, hide the one not selected
         underlyingViews = new Component[MAX_NUM_UNDERLYING_VIEWS];
@@ -130,7 +107,7 @@ public class CollectionContentsLinksSelectorPanel
 
             Component underlyingView = componentFactory.createComponent(underlyingId,i==selected? model: emptyModel);
             underlyingViews[i++] = underlyingView;
-            selectorPanel.addOrReplace(underlyingView);
+            this.addOrReplace(underlyingView);
         }
 
         // hide any unused placeholders
@@ -142,129 +119,16 @@ public class CollectionContentsLinksSelectorPanel
 
         // selector
         if (componentFactories.size() <= 1) {
-            //permanentlyHide(ID_VIEWS);
-
             permanentlyHide(ID_SELECTOR_DROPDOWN);
         } else {
             final Model<ComponentFactory> componentFactoryModel = new Model<>();
 
-            selectorPanel.selectedComponentFactory = componentFactories.get(selected);
-            componentFactoryModel.setObject(selectorPanel.selectedComponentFactory);
+            this.selectedComponentFactory = componentFactories.get(selected);
+            componentFactoryModel.setObject(this.selectedComponentFactory);
 
-            selectorDropdownPanel = new CollectionContentsSelectorDropdownPanel(ID_SELECTOR_DROPDOWN, getModel(), componentFactory);
+            selectorDropdownPanel = new CollectionContentsSelectorDropdownPanel(ID_SELECTOR_DROPDOWN, getModel(), ignoreFactory);
 
             this.setOutputMarkupId(true);
-
-//            final WebMarkupContainer views = new WebMarkupContainer(ID_VIEWS);
-//
-//            final Label viewButtonTitle = new Label(ID_VIEW_BUTTON_TITLE, "Hidden");
-//            views.addOrReplace(viewButtonTitle);
-//
-//            final Label viewButtonIcon = new Label(ID_VIEW_BUTTON_ICON, "");
-//            views.addOrReplace(viewButtonIcon);
-//
-//            final WebMarkupContainer container = new WebMarkupContainer(ID_VIEW_LIST);
-//
-//            views.addOrReplace(container);
-//            views.setOutputMarkupId(true);
-//
-//            this.setOutputMarkupId(true);
-
-//            final ListView<ComponentFactory> listView = new ListView<ComponentFactory>(ID_VIEW_ITEM, componentFactories) {
-//
-//                private static final long serialVersionUID = 1L;
-//
-//                @Override
-//                protected void populateItem(ListItem<ComponentFactory> item) {
-//
-//                    final int underlyingViewNum = item.getIndex();
-//
-//                    final ComponentFactory componentFactory = item.getModelObject();
-//                    final AbstractLink link = new AjaxLink<Void>(ID_VIEW_LINK) {
-//                        private static final long serialVersionUID = 1L;
-//                        @Override
-//                        public void onClick(AjaxRequestTarget target) {
-//                            CollectionContentsLinksSelectorPanel linksSelectorPanel = CollectionContentsLinksSelectorPanel.this;
-//                            linksSelectorPanel.setViewHintAndBroadcast(underlyingViewNum, target);
-//
-//                            final EntityCollectionModel dummyModel = model.asDummy();
-//                            for(int i=0; i<MAX_NUM_UNDERLYING_VIEWS; i++) {
-//                                final Component component = underlyingViews[i];
-//                                if(component == null) {
-//                                    continue;
-//                                }
-//                                final boolean isSelected = i == underlyingViewNum;
-//                                applyCssVisibility(component, isSelected);
-//                                component.setDefaultModel(isSelected? model: dummyModel);
-//                            }
-//
-//                            selectorPanel.selectedComponentFactory = componentFactory;
-//                            selectorPanel.selectedComponent = underlyingViews[underlyingViewNum];
-//                            selectorPanel.onSelect(target);
-//                            target.add(selectorPanel, views);
-//                        }
-//
-//                        @Override
-//                        protected void onComponentTag(ComponentTag tag) {
-//                            super.onComponentTag(tag);
-//                            Buttons.fixDisabledState(this, tag);
-//                        }
-//                    };
-//
-//                    IModel<String> title = nameFor(componentFactory);
-//                    Label viewItemTitleLabel = new Label(ID_VIEW_ITEM_TITLE, title);
-//                    link.add(viewItemTitleLabel);
-//
-//                    Label viewItemIcon = new Label(ID_VIEW_ITEM_ICON, "");
-//                    link.add(viewItemIcon);
-//
-//                    boolean isEnabled = componentFactory != selectorPanel.selectedComponentFactory;
-//                    if (!isEnabled) {
-//                        viewButtonTitle.setDefaultModel(title);
-//                        IModel<String> cssClass = cssClassFor(componentFactory, viewButtonIcon);
-//                        viewButtonIcon.add(AttributeModifier.replace("class", "ViewLinkItem " + cssClass.getObject()));
-//                        link.setVisible(false);
-//                    } else {
-//                        IModel<String> cssClass = cssClassFor(componentFactory, viewItemIcon);
-//                        viewItemIcon.add(new CssClassAppender(cssClass));
-//                    }
-//
-//                    item.add(link);
-//                }
-//
-//                private IModel<String> cssClassFor(final ComponentFactory componentFactory, Label viewIcon) {
-//                    IModel<String> cssClass = null;
-//                    if (componentFactory instanceof CollectionContentsAsFactory) {
-//                        CollectionContentsAsFactory collectionContentsAsFactory = (CollectionContentsAsFactory) componentFactory;
-//                        cssClass = collectionContentsAsFactory.getCssClass();
-//                        viewIcon.setDefaultModelObject("");
-//                        viewIcon.setEscapeModelStrings(true);
-//                    }
-//                    if (cssClass == null) {
-//                        String name = componentFactory.getName();
-//                        cssClass = Model.of(StringExtensions.asLowerDashed(name));
-//                        // Small hack: if there is no specific CSS class then we assume that background-image is used
-//                        // the span.ViewItemLink should have some content to show it
-//                        // FIX: find a way to do this with CSS (width and height don't seems to help)
-//                        viewIcon.setDefaultModelObject("&#160;&#160;&#160;&#160;&#160;");
-//                        viewIcon.setEscapeModelStrings(false);
-//                    }
-//                    return cssClass;
-//                }
-//
-//                private IModel<String> nameFor(final ComponentFactory componentFactory) {
-//                    IModel<String> name = null;
-//                    if (componentFactory instanceof CollectionContentsAsFactory) {
-//                        CollectionContentsAsFactory collectionContentsAsFactory = (CollectionContentsAsFactory) componentFactory;
-//                        name = collectionContentsAsFactory.getTitleLabel();
-//                    }
-//                    if (name == null) {
-//                        name = Model.of(componentFactory.getName());
-//                    }
-//                    return name;
-//                }
-//            };
-//            container.add(listView);
             addOrReplace(selectorDropdownPanel);
         }
 
@@ -314,63 +178,18 @@ public class CollectionContentsLinksSelectorPanel
             component.setDefaultModel(isSelected? getModel(): dummyModel);
         }
 
-        this.selectedComponentFactory = componentFactory;
+        this.selectedComponentFactory = ignoreFactory;
         this.selectedComponent = underlyingViews[underlyingViewNum];
 
 
         final AjaxRequestTarget target = uiHintEvent.getTarget();
         if(target != null) {
-//            selectorDropdownPanel.onSelect(target);
             target.add(this, selectorDropdownPanel);
         }
 
-
     }
 
 
-
-//    protected void setViewHintAndBroadcast(int viewNum, AjaxRequestTarget target) {
-//        final UiHintContainer uiHintContainer = getUiHintContainer();
-//        if(uiHintContainer == null) {
-//            return;
-//        }
-//        uiHintContainer.setHint(CollectionContentsLinksSelectorPanel.this, UIHINT_VIEW, ""+viewNum);
-//        send(getPage(), Broadcast.EXACT, new IsisUiHintEvent(uiHintContainer, target));
-//    }
-
-//    /**
-//     * Iterates up the component hierarchy looking for a parent
-//     * {@link org.apache.isis.viewer.wicket.ui.components.collection.CollectionPanel}, and if so adds to ajax target so that it'll
-//     * be repainted.
-//     *
-//     * <p>
-//     * Yeah, agreed, it's a little bit hacky doing it this way, because it bakes
-//     * in knowledge that this component is created, somehow, by a parent {@link org.apache.isis.viewer.wicket.ui.components.collection.CollectionPanel}.
-//     * Perhaps it could be refactored to use a more general purpose observer pattern?
-//     *
-//     * <p>
-//     * In fact, I've since discovered that Wicket has an event bus, which is used by the
-//     * {@link UiHintContainer hinting mechanism}.  So this ought to be relatively easy to do.
-//     */
-//    protected void onSelect(AjaxRequestTarget target) {
-//        Component component = this;
-//        while(component != null) {
-//            if(component instanceof CollectionPanel) {
-//                CollectionPanel collectionPanel = (CollectionPanel) component;
-//                boolean hasCount = collectionPanel.hasCount();
-//                if(hasCount) {
-//                    collectionPanel.updateLabel(target);
-//                }
-//                if(additionalLinks != null) {
-//                    applyCssVisibility(additionalLinks, hasCount);
-//                }
-//                return;
-//            }
-//            component = component.getParent();
-//        }
-//    }
-
-
     protected static void applyCssVisibility(final Component component, final boolean visible) {
         if(component == null) {
             return;
@@ -379,69 +198,6 @@ public class CollectionContentsLinksSelectorPanel
         component.add(modifier);
     }
 
-    protected int honourViewHintElseDefault(final List<ComponentFactory> componentFactories, final IModel<?> model) {
-        // honour hints ...
-        final UiHintContainer hintContainer = getUiHintContainer();
-        if(hintContainer != null) {
-            String viewStr = hintContainer.getHint(this, UIHINT_VIEW);
-            if(viewStr != null) {
-                try {
-                    int view = Integer.parseInt(viewStr);
-                    if(view >= 0 && view < componentFactories.size()) {
-                        return view;
-                    }
-                } catch(NumberFormatException ex) {
-                    // ignore
-                }
-            }
-        }
-
-        // ... else default
-        int initialFactory = determineInitialFactory(componentFactories, model);
-        if(hintContainer != null) {
-            hintContainer.setHint(this, UIHINT_VIEW, ""+initialFactory);
-            // don't broadcast (no AjaxRequestTarget, still configuring initial setup)
-        }
-        return initialFactory;
-    }
-
-
-    /**
-     * return the index of {@link CollectionContentsAsUnresolvedPanelFactory unresolved panel} if present and not eager loading;
-     * else the index of {@link CollectionContentsAsAjaxTablePanelFactory ajax table} if present,
-     * otherwise first factory.
-     */
-    protected int determineInitialFactory(final List<ComponentFactory> componentFactories, final IModel<?> model) {
-        if(!hasRenderEagerlyFacet(model)) {
-            for(int i=0; i<componentFactories.size(); i++) {
-                if(componentFactories.get(i) instanceof CollectionContentsAsUnresolvedPanelFactory) {
-                    return i;
-                }
-            }
-        }
-        int ajaxTableIdx = findAjaxTable(componentFactories);
-        if(ajaxTableIdx>=0) {
-            return ajaxTableIdx;
-        }
-        return 0;
-    }
-
-    private List<ComponentFactory> findOtherComponentFactories(final EntityCollectionModel model, final ComponentFactory ignoreFactory) {
-        final List<ComponentFactory> componentFactories = getComponentFactoryRegistry().findComponentFactories(componentType, model);
-        ArrayList<ComponentFactory> otherFactories = Lists.newArrayList(Collections2.filter(componentFactories, new Predicate<ComponentFactory>() {
-            @Override
-            public boolean apply(final ComponentFactory input) {
-                return input != ignoreFactory && input.getClass() != CollectionContentsLinksSelectorPanelFactory.class;
-            }
-        }));
-        return ordered(otherFactories);
-    }
-
-    protected List<ComponentFactory> ordered(List<ComponentFactory> componentFactories) {
-        return orderAjaxTableToEnd(componentFactories);
-    }
-
-
     @Override
     public void renderHead(final IHeaderResponse response) {
         super.renderHead(response);
@@ -449,43 +205,6 @@ public class CollectionContentsLinksSelectorPanel
     }
 
 
-    static List<ComponentFactory> orderAjaxTableToEnd(List<ComponentFactory> componentFactories) {
-        int ajaxTableIdx = findAjaxTable(componentFactories);
-        if(ajaxTableIdx>=0) {
-            List<ComponentFactory> orderedFactories = Lists.newArrayList(componentFactories);
-            ComponentFactory ajaxTableFactory = orderedFactories.remove(ajaxTableIdx);
-            orderedFactories.add(ajaxTableFactory);
-            return orderedFactories;
-        } else {
-            return componentFactories;
-        }
-    }
-    
-    private static int findAjaxTable(List<ComponentFactory> componentFactories) {
-        for(int i=0; i<componentFactories.size(); i++) {
-            if(componentFactories.get(i) instanceof CollectionContentsAsAjaxTablePanelFactory) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-
-    private static boolean hasRenderEagerlyFacet(IModel<?> model) {
-        if(!(model instanceof EntityCollectionModel)) {
-            return false;
-        }
-        final EntityCollectionModel entityCollectionModel = (EntityCollectionModel) model;
-        if(!entityCollectionModel.isParented()) {
-            return false;
-        }
-
-        final OneToManyAssociation collection = 
-                entityCollectionModel.getCollectionMemento().getCollection();
-        RenderFacet renderFacet = collection.getFacet(RenderFacet.class);
-        return renderFacet != null && renderFacet.value() == Type.EAGERLY;
-    }
-
 
     @Override
     public Integer getCount() {

http://git-wip-us.apache.org/repos/asf/isis/blob/7087fc25/component/viewer/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorDropdownPanelTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorDropdownPanelTest.java b/component/viewer/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorDropdownPanelTest.java
index d116be4..6b94417 100644
--- a/component/viewer/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorDropdownPanelTest.java
+++ b/component/viewer/wicket/ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/collectioncontents/selector/dropdown/CollectionContentsSelectorDropdownPanelTest.java
@@ -58,7 +58,7 @@ public class CollectionContentsSelectorDropdownPanelTest {
                         one,
                         ajaxTableComponentFactory, 
                         two);
-        List<ComponentFactory> orderAjaxTableToEnd = CollectionContentsSelectorDropdownPanel.orderAjaxTableToEnd(componentFactories);
+        List<ComponentFactory> orderAjaxTableToEnd = CollectionContentsSelectorHelper.orderAjaxTableToEnd(componentFactories);
         assertThat(orderAjaxTableToEnd.get(0), is(one));
         assertThat(orderAjaxTableToEnd.get(1), is(two));
         assertThat(orderAjaxTableToEnd.get(2), is(ajaxTableComponentFactory));