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/08/23 19:01:34 UTC

[1/2] git commit: ISIS-478: better handling of primitives as choices

Updated Branches:
  refs/heads/master 58aff6aa3 -> 52bc369a0


ISIS-478: better handling of primitives as choices

* ObjactActionParameterAbstract's check for compatibility of returned choices vs parameter types now treats wrapper and primitive types (eg int.class and java.lang.Integer.class) as compatible
* AdapterInvokeUtils#invokeAutoFit will substitute default values for primitives (eg 0 for an int), rather than null (which fails, obviously)

In addition:
* removed some duplication between ValueChoicesSelect2Panel and EntityLinkSelect2Panel (use of ObjectAdapterMementoProvider for choices provider impl)
* working towards EntityLinkSelect2Panel supporting onChange [fixed] and correct handling of pending values for onUpdate [not yet fixed]


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

Branch: refs/heads/master
Commit: a5fca2526baf9cbfed02e1cc88b58795fd24d04a
Parents: 58aff6a
Author: Dan Haywood <da...@apache.org>
Authored: Thu Aug 22 07:32:15 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Fri Aug 23 12:26:06 2013 +0100

----------------------------------------------------------------------
 .../EmbeddedWebViewerRestfulObjects.java        |   2 +-
 .../model/mementos/ObjectAdapterMemento.java    |  22 +++-
 .../components/scalars/ScalarPanelAbstract.java |   6 +-
 .../scalars/reference/ReferencePanel.java       |   2 +-
 .../ObjectAdapterMementoProviderAbstract.java   |  67 ++++++++++++
 .../entitylink/EntityLinkSelect2Panel.java      | 104 +++++++------------
 .../valuechoices/ValueChoicesSelect2Panel.java  |  57 +++-------
 .../isis/core/commons/lang/ListUtils.java       |   4 +-
 .../apache/isis/core/commons/lang/MapUtils.java |  29 +++---
 .../isis/core/commons/lang/WrapperUtils.java    |  54 ++++++----
 .../adapter/util/AdapterInvokeUtils.java        |  24 ++++-
 .../specimpl/ObjectActionParameterAbstract.java |  20 +++-
 .../ActionParameterChoicesFacetViaMethod.java   |   2 +-
 .../ActionParameterDefaultsFacetFactory.java    |  24 ++++-
 .../ActionParameterDefaultsFacetViaMethod.java  |  15 ++-
 15 files changed, 270 insertions(+), 162 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/embedded/EmbeddedWebViewerRestfulObjects.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/embedded/EmbeddedWebViewerRestfulObjects.java b/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/embedded/EmbeddedWebViewerRestfulObjects.java
index 5331201..c395233 100644
--- a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/embedded/EmbeddedWebViewerRestfulObjects.java
+++ b/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/embedded/EmbeddedWebViewerRestfulObjects.java
@@ -43,7 +43,7 @@ final class EmbeddedWebViewerRestfulObjects extends EmbeddedWebViewer {
         webAppSpec.addContextParams(RestfulObjectsViewerInstaller.JAVAX_WS_RS_APPLICATION, RestfulObjectsApplication.class.getName());
 
         webAppSpec.addFilterSpecification(IsisSessionFilter.class, 
-                MapUtils.asMap(
+                MapUtils.<String,String>asMap(
                         IsisSessionFilter.AUTHENTICATION_SESSION_STRATEGY_KEY, AuthenticationSessionStrategyTrusted.class.getName(),
                         IsisSessionFilter.WHEN_NO_SESSION_KEY, IsisSessionFilter.WhenNoSession.CONTINUE.name().toLowerCase()), 
                 RestfulObjectsViewerInstaller.EVERYTHING);

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
index 0eec181..a39025b 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/mementos/ObjectAdapterMemento.java
@@ -20,6 +20,7 @@
 package org.apache.isis.viewer.wicket.model.mementos;
 
 import java.io.Serializable;
+import java.util.List;
 
 import org.apache.isis.core.commons.ensure.Ensure;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
@@ -304,7 +305,24 @@ public class ObjectAdapterMemento implements Serializable {
         return objectSpecId;
     }
 
-    
+
+    /**
+     * Analogous to {@link List#contains(Object)}, but does not perform
+     * {@link ConcurrencyChecking concurrency checking} of the OID.
+     */
+    public boolean containedIn(List<ObjectAdapterMemento> list) {
+        // REVIEW: heavy handed, ought to be possible to just compare the OIDs
+        // ignoring the concurrency checking
+        final ObjectAdapter currAdapter = getObjectAdapter(ConcurrencyChecking.NO_CHECK);
+        for (ObjectAdapterMemento each : list) {
+            final ObjectAdapter otherAdapter = each.getObjectAdapter(ConcurrencyChecking.NO_CHECK);
+            if(currAdapter == otherAdapter) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     @Override
     public int hashCode() {
         return type.hashCode(this);
@@ -315,6 +333,7 @@ public class ObjectAdapterMemento implements Serializable {
         return (obj instanceof ObjectAdapterMemento) && type.equals(this, (ObjectAdapterMemento)obj);
     }
 
+
     @Override
     public String toString() {
         return type.toString(this);
@@ -339,4 +358,5 @@ public class ObjectAdapterMemento implements Serializable {
 
 
 
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
index e005ccd..e519d47 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
@@ -171,8 +171,12 @@ public abstract class ScalarPanelAbstract extends PanelAbstract<ScalarModel> imp
      * @see #setFormat(Rendering)
      */
     private void buildGui() {
-        componentIfRegular = addComponentForRegular();
+        
+        // REVIEW: this is nasty, both write to the same entityLink field
+        // even though only one is used
         componentIfCompact = addComponentForCompact();
+        componentIfRegular = addComponentForRegular();
+        
         getRendering().buildGui(this);
         addCssForMetaModel();
         

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
index 6a4685b..09faa65 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
@@ -47,7 +47,6 @@ public class ReferencePanel extends ScalarPanelAbstract {
 
     private static final String ID_SCALAR_IF_REGULAR = "scalarIfRegular";
     private static final String ID_SCALAR_NAME = "scalarName";
-    private static final String ID_FEEDBACK = "feedback";
 
     private static final String ID_SCALAR_IF_COMPACT = "scalarIfCompact";
 
@@ -87,6 +86,7 @@ public class ReferencePanel extends ScalarPanelAbstract {
         
         entityLink = (EntityLinkSelect2Panel) getComponentFactoryRegistry().createComponent(ComponentType.ENTITY_LINK, getModel());
         
+        setOutputMarkupId(true);
         entityLink.setOutputMarkupId(true);
         entityLink.setLabel(Model.of(name));
         

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/ObjectAdapterMementoProviderAbstract.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/ObjectAdapterMementoProviderAbstract.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/ObjectAdapterMementoProviderAbstract.java
new file mode 100644
index 0000000..ebf4db0
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/ObjectAdapterMementoProviderAbstract.java
@@ -0,0 +1,67 @@
+/**
+ *  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.ui.components.widgets;
+
+import java.util.Collection;
+import java.util.List;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.vaynberg.wicket.select2.TextChoiceProvider;
+
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOidDefault;
+import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
+
+public abstract class ObjectAdapterMementoProviderAbstract extends TextChoiceProvider<ObjectAdapterMemento> {
+    private static final long serialVersionUID = 1L;
+
+    public ObjectAdapterMementoProviderAbstract(){}
+    
+    @Override
+    protected String getDisplayText(ObjectAdapterMemento choice) {
+        return choice.getObjectAdapter(ConcurrencyChecking.NO_CHECK).titleString(null);
+    }
+
+    @Override
+    protected Object getId(ObjectAdapterMemento choice) {
+        return choice.toString();
+    }
+
+    @Override
+    public void query(String term, int page, com.vaynberg.wicket.select2.Response<ObjectAdapterMemento> response) {
+        
+        List<ObjectAdapterMemento> mementos = obtainMementos(term);
+        response.addAll(mementos);
+    }
+
+    protected abstract List<ObjectAdapterMemento> obtainMementos(String term);
+
+    @Override
+    public Collection<ObjectAdapterMemento> toChoices(Collection<String> ids) {
+        Function<String, ObjectAdapterMemento> function = new Function<String, ObjectAdapterMemento>() {
+
+            @Override
+            public ObjectAdapterMemento apply(String input) {
+                final RootOid oid = RootOidDefault.deString(input, ObjectAdapterMemento.getOidMarshaller());
+                return ObjectAdapterMemento.createPersistent(oid);
+            }
+        };
+        return Collections2.transform(ids, function);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
index 7b91e01..74f4ffa 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
@@ -20,17 +20,13 @@
 package org.apache.isis.viewer.wicket.ui.components.widgets.entitylink;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
 import com.google.common.collect.Lists;
 import com.vaynberg.wicket.select2.ChoiceProvider;
 import com.vaynberg.wicket.select2.Select2Choice;
 import com.vaynberg.wicket.select2.Settings;
-import com.vaynberg.wicket.select2.TextChoiceProvider;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.behavior.Behavior;
@@ -40,8 +36,6 @@ import org.apache.wicket.markup.html.link.Link;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
-import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import org.apache.isis.core.metamodel.adapter.oid.RootOidDefault;
 import org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
 import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -58,6 +52,7 @@ import org.apache.isis.viewer.wicket.model.util.Mementos;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.components.actions.ActionInvokeHandler;
+import org.apache.isis.viewer.wicket.ui.components.widgets.ObjectAdapterMementoProviderAbstract;
 import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.CancelHintRequired;
 import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.FormComponentPanelAbstract;
 
@@ -204,14 +199,19 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
             
         };
 
-        select2Field = new Select2Choice<ObjectAdapterMemento>(ID_AUTO_COMPLETE, model);
-        setChoices(null);
+        if(select2Field == null) {
+            select2Field = new Select2Choice<ObjectAdapterMemento>(ID_AUTO_COMPLETE, model);
+            setChoices(null);
+            if(!hasChoices()) {
+                final Settings settings = select2Field.getSettings();
+                ScalarModel scalarModel = (ScalarModel) getEntityModel();
+                final int minLength = scalarModel.getAutoCompleteMinLength();
+                settings.setMinimumInputLength(minLength);
+            }
+            addOrReplace(select2Field);
+        }
         
-        final Settings settings = select2Field.getSettings();
         
-        ScalarModel scalarModel = (ScalarModel) getEntityModel();
-        settings.setMinimumInputLength(scalarModel.getAutoCompleteMinLength());
-        addOrReplace(select2Field);
         
         // no need for link, since can see in drop-down
         permanentlyHide(ID_ENTITY_ICON_AND_TITLE);
@@ -222,42 +222,6 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
     }
 
 
-    abstract static class ObjectAdapterMementoProviderAbstract extends TextChoiceProvider<ObjectAdapterMemento> {
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        protected String getDisplayText(ObjectAdapterMemento choice) {
-            return choice.getObjectAdapter(ConcurrencyChecking.NO_CHECK).titleString(null);
-        }
-
-        @Override
-        protected Object getId(ObjectAdapterMemento choice) {
-            return choice.toString();
-        }
-
-        @Override
-        public void query(String term, int page, com.vaynberg.wicket.select2.Response<ObjectAdapterMemento> response) {
-            
-            List<ObjectAdapterMemento> mementos = obtainMementos(term);
-            response.addAll(mementos);
-        }
-
-        protected abstract List<ObjectAdapterMemento> obtainMementos(String term);
-
-        @Override
-        public Collection<ObjectAdapterMemento> toChoices(Collection<String> ids) {
-            Function<String, ObjectAdapterMemento> function = new Function<String, ObjectAdapterMemento>() {
-
-                @Override
-                public ObjectAdapterMemento apply(String input) {
-                    final RootOid oid = RootOidDefault.deString(input, ObjectAdapterMemento.getOidMarshaller());
-                    return ObjectAdapterMemento.createPersistent(oid);
-                }
-            };
-            return Collections2.transform(ids, function);
-        }
-    }
-
     private ChoiceProvider<ObjectAdapterMemento> providerForObjectAutoComplete() {
         final EntityModel entityModel = getEntityModel();
         return new ObjectAdapterMementoProviderAbstract() {
@@ -299,21 +263,6 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
         };
     }
     
-    private ChoiceProvider<ObjectAdapterMemento> providerForChoices(final ObjectAdapter[] argsIfAvailable) {
-        
-        final List<ObjectAdapterMemento> choices = getChoiceMementos(argsIfAvailable);
-        
-        return new ObjectAdapterMementoProviderAbstract() {
-
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            protected List<ObjectAdapterMemento> obtainMementos(String unused) {
-                return choices;
-            }
-        };
-    }
-
     private List<ObjectAdapterMemento> getChoiceMementos(final ObjectAdapter[] argsIfAvailable) {
         
         final ScalarModel scalarModel = (ScalarModel) getEntityModel();;
@@ -479,13 +428,38 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
         
         final ChoiceProvider<ObjectAdapterMemento> provider;
         if (hasChoices()) {
-            provider = providerForChoices(argsIfAvailable);
+            final List<ObjectAdapterMemento> choiceMementos = getChoiceMementos(argsIfAvailable);
+            provider = new ObjectAdapterMementoProviderAbstract() {
+                private static final long serialVersionUID = 1L;
+                @Override
+                protected List<ObjectAdapterMemento> obtainMementos(String unused) {
+                    return choiceMementos;
+                }
+            };
+            select2Field.setProvider(provider);
+            getEntityModel().clearPending();
+            final ObjectAdapterMemento curr = select2Field.getModelObject();
+            final ObjectAdapterMemento curr2 = getEntityModel().getObjectAdapterMemento();
+            if(curr == null || !curr.containedIn(choiceMementos)) {
+                final ObjectAdapterMemento newAdapterMemento = 
+                        !choiceMementos.isEmpty() 
+                        ? choiceMementos.get(0) 
+                                : null;
+                        select2Field.getModel().setObject(newAdapterMemento);
+                        getModel().setObject(
+                                newAdapterMemento != null? newAdapterMemento.getObjectAdapter(ConcurrencyChecking.NO_CHECK): null);
+            } else {
+                //select2Field.getModel().setObject(curr);
+            }
         } else if(hasParamOrPropertyAutoComplete()) {
             provider = providerForParamOrPropertyAutoComplete();
+            select2Field.setProvider(provider);
+            getEntityModel().setPending(null);
         } else {
             provider = providerForObjectAutoComplete();
+            select2Field.setProvider(provider);
+            getEntityModel().setPending(null);
         }
-        select2Field.setProvider(provider);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ValueChoicesSelect2Panel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ValueChoicesSelect2Panel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ValueChoicesSelect2Panel.java
index a0070e3..12d10c8 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ValueChoicesSelect2Panel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ValueChoicesSelect2Panel.java
@@ -19,6 +19,7 @@ package org.apache.isis.viewer.wicket.ui.components.widgets.valuechoices;
 import java.util.Collection;
 import java.util.List;
 
+import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.Lists;
@@ -38,11 +39,14 @@ import org.slf4j.LoggerFactory;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOidDefault;
 import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
 import org.apache.isis.viewer.wicket.model.models.ModelAbstract;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.model.util.Mementos;
 import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
+import org.apache.isis.viewer.wicket.ui.components.widgets.ObjectAdapterMementoProviderAbstract;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
 
 /**
@@ -90,22 +94,6 @@ public class ValueChoicesSelect2Panel extends ScalarPanelAbstract {
         return labelIfRegular;
     }
 
-
-    protected ChoiceProvider<ObjectAdapterMemento> newChoiceProvider(final List<ObjectAdapterMemento> choicesMementos) {
-        final IModel<List<ObjectAdapterMemento>> choicesModel = newModel(choicesMementos);
-        return newChoiceProvider(choicesModel);
-    }
-
-    private IModel<List<ObjectAdapterMemento>> newModel(final List<ObjectAdapterMemento> choicesMementos) {
-        return new ModelAbstract<List<ObjectAdapterMemento>>(choicesMementos){
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            protected List<ObjectAdapterMemento> load() {
-                return getObject();
-            }};
-    }
-
     private List<ObjectAdapterMemento> getChoiceMementos(final ObjectAdapter[] argumentsIfAvailable) {
         final List<ObjectAdapter> choices = scalarModel.getChoices(argumentsIfAvailable);
         
@@ -191,33 +179,16 @@ public class ValueChoicesSelect2Panel extends ScalarPanelAbstract {
         return scalarModel.getObject();
     }
 
-    protected ChoiceProvider<ObjectAdapterMemento> newChoiceProvider(final IModel<List<ObjectAdapterMemento>> choicesMementos) {
-        ChoiceProvider<ObjectAdapterMemento> provider = new TextChoiceProvider<ObjectAdapterMemento>() {
+    
+    protected ChoiceProvider<ObjectAdapterMemento> newChoiceProvider(final List<ObjectAdapterMemento> choicesMementos) {
+        ChoiceProvider<ObjectAdapterMemento> provider = new ObjectAdapterMementoProviderAbstract() {
 
             private static final long serialVersionUID = 1L;
 
             @Override
-            protected String getDisplayText(ObjectAdapterMemento choice) {
-                
-                final ObjectAdapter objectAdapter = choice.getObjectAdapter(ConcurrencyChecking.NO_CHECK);
-                return objectAdapter.titleString(null);
-            }
-
-            @Override
-            protected Object getId(ObjectAdapterMemento choice) {
-                final ObjectAdapter objectAdapter = choice.getObjectAdapter(ConcurrencyChecking.NO_CHECK);
-                return objectAdapter.getObject().toString(); // toString of each value acts as its the key
-            }
-
-            @Override
-            public void query(String term, int page, com.vaynberg.wicket.select2.Response<ObjectAdapterMemento> response) {
-                response.addAll(choicesMementos.getObject());
-            }
-
-            @Override
             public Collection<ObjectAdapterMemento> toChoices(final Collection<String> ids) {
-                final List<ObjectAdapterMemento> mementos = choicesMementos.getObject();
-                Predicate<ObjectAdapterMemento> predicate = new Predicate<ObjectAdapterMemento>() {
+                final List<ObjectAdapterMemento> mementos = obtainMementos(null);
+                final Predicate<ObjectAdapterMemento> predicate = new Predicate<ObjectAdapterMemento>() {
 
                     @Override
                     public boolean apply(ObjectAdapterMemento input) {
@@ -228,6 +199,11 @@ public class ValueChoicesSelect2Panel extends ScalarPanelAbstract {
                 return Collections2.filter(mementos, predicate); 
             }
 
+            @Override
+            protected List<ObjectAdapterMemento> obtainMementos(String term) {
+                return choicesMementos;
+            }
+
         };
         return provider;
     }
@@ -263,8 +239,9 @@ public class ValueChoicesSelect2Panel extends ScalarPanelAbstract {
     private void setChoices(ObjectAdapter[] argsIfAvailable) {
         final List<ObjectAdapterMemento> choicesMementos = getChoiceMementos(argsIfAvailable);
         
-        select2Field.setProvider(newChoiceProvider(choicesMementos));
-        getModel().setPending(null);
+        final ChoiceProvider<ObjectAdapterMemento> provider = newChoiceProvider(choicesMementos);
+        select2Field.setProvider(provider);
+        getModel().clearPending();
         final ObjectAdapterMemento objectAdapterMemento = getModel().getObjectAdapterMemento();
         if(!choicesMementos.contains(objectAdapterMemento)) {
             final ObjectAdapterMemento newAdapterMemento = 

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ListUtils.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ListUtils.java b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ListUtils.java
index 3da6bdf..9e87d14 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ListUtils.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ListUtils.java
@@ -27,8 +27,6 @@ import java.util.List;
 
 import com.google.common.collect.Lists;
 
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-
 public final class ListUtils {
     private static final String DEFAULT_DELIMITER = ",";
 
@@ -158,7 +156,7 @@ public final class ListUtils {
         extend(list, insertionPoint);
         list.add(insertionPoint, elementToInsert);
     }
-
+    
     public static <T> void adjust(final List<T> list, final int requiredLength) {
         extend(list, requiredLength);
         if(list.size() > requiredLength) {

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MapUtils.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MapUtils.java b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MapUtils.java
index 9700832..779243a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MapUtils.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MapUtils.java
@@ -19,6 +19,7 @@
 
 package org.apache.isis.core.commons.lang;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -30,24 +31,18 @@ public final class MapUtils {
     /**
      * Converts a list of objects [a, 1, b, 2] into a map {a -> 1; b -> 2}
      */
-    public static Map<String, String> asMap(final String... paramArgs) {
-        final HashMap<String, String> map = new HashMap<String, String>();
-        boolean param = true;
-        String paramStr = null;
-        for (final String paramArg : paramArgs) {
-            if (param) {
-                paramStr = paramArg;
-            } else {
-                final String arg = paramArg;
-                map.put(paramStr, arg);
-                paramStr = null;
-            }
-            param = !param;
+    @SuppressWarnings("unchecked")
+    public static <K,V> Map<K,V> asMap(Object... keyValPair){
+        Map<K,V> map = new HashMap<K,V>();
+
+        if(keyValPair.length % 2 != 0){
+            throw new IllegalArgumentException("Keys and values must be pairs.");
         }
-        if (paramStr != null) {
-            throw new IllegalArgumentException("Must have equal number of parameters and arguments");
+
+        for(int i = 0; i < keyValPair.length; i += 2){
+            map.put((K) keyValPair[i], (V) keyValPair[i+1]);
         }
-        return map;
-    }
 
+        return Collections.unmodifiableMap(map);
+    }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/WrapperUtils.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/WrapperUtils.java b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/WrapperUtils.java
index f6a3732..ee302e4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/WrapperUtils.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/WrapperUtils.java
@@ -20,7 +20,6 @@
 package org.apache.isis.core.commons.lang;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -28,19 +27,31 @@ public final class WrapperUtils {
 
     private WrapperUtils() {
     }
+    
+    private static final Map<Class<?>, Object> defaultByPrimitiveClass = 
+        MapUtils.asMap(
+            boolean.class, false,
+            byte.class, (byte)0,
+            short.class, (short)0,
+            int.class, 0,
+            long.class, 0L,
+            float.class, 0.0f,
+            double.class, 0.0,
+            char.class, (char)0
+        );
 
-    private static Map<Class<?>, Class<?>> wrapperClasses = new HashMap<Class<?>, Class<?>>();
-
-    static {
-        wrapperClasses.put(boolean.class, Boolean.class);
-        wrapperClasses.put(byte.class, Byte.class);
-        wrapperClasses.put(char.class, Character.class);
-        wrapperClasses.put(short.class, Short.class);
-        wrapperClasses.put(int.class, Integer.class);
-        wrapperClasses.put(long.class, Long.class);
-        wrapperClasses.put(float.class, Float.class);
-        wrapperClasses.put(double.class, Double.class);
-    }
+
+    private static Map<Class<?>, Class<?>> wrapperClasses = 
+        MapUtils.asMap(
+            boolean.class, Boolean.class,
+            byte.class, Byte.class,
+            char.class, Character.class,
+            short.class, Short.class,
+            int.class, Integer.class,
+            long.class, Long.class,
+            float.class, Float.class,
+            double.class, Double.class
+        );
 
     public static Class<?> wrap(final Class<?> primitiveClass) {
         return wrapperClasses.get(primitiveClass);
@@ -49,13 +60,20 @@ public final class WrapperUtils {
     public static Class<?>[] wrapAsNecessary(final Class<?>[] classes) {
         final List<Class<?>> wrappedClasses = new ArrayList<Class<?>>();
         for (final Class<?> cls : classes) {
-            if (cls.isPrimitive()) {
-                wrappedClasses.add(wrap(cls));
-            } else {
-                wrappedClasses.add(cls);
-            }
+            wrappedClasses.add(wrapAsNecessary(cls));
         }
         return wrappedClasses.toArray(new Class[] {});
     }
 
+    public static Class<? extends Object> wrapAsNecessary(final Class<?> cls) {
+        return cls.isPrimitive() ? wrap(cls) : cls;
+    }
+
+    public static Object defaultFor(final Class<?> cls) {
+        if(!cls.isPrimitive()) {
+            return null;
+        }
+        return WrapperUtils.defaultByPrimitiveClass.get(cls);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/util/AdapterInvokeUtils.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/util/AdapterInvokeUtils.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/util/AdapterInvokeUtils.java
index 951e29e..fa45a4d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/util/AdapterInvokeUtils.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/util/AdapterInvokeUtils.java
@@ -25,7 +25,9 @@ import java.util.List;
 import com.google.common.collect.Lists;
 
 import org.apache.isis.core.commons.lang.ListUtils;
+import org.apache.isis.core.commons.lang.WrapperUtils;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
 
 public final class AdapterInvokeUtils {
 
@@ -62,20 +64,32 @@ public final class AdapterInvokeUtils {
      * <li>if the method does not declare all parameters for arguments, then truncates arguments.
      * </ul>
      */
-    public static Object invokeAutofit(final Method method, final ObjectAdapter target, List<ObjectAdapter> argumentsIfAvailable) {
+    public static Object invokeAutofit(final Method method, final ObjectAdapter target, List<ObjectAdapter> argumentsIfAvailable, final AdapterManager adapterManager) {
         final List<ObjectAdapter> args = Lists.newArrayList();
         if(argumentsIfAvailable != null) {
             args.addAll(argumentsIfAvailable);
         }
         
-        final int requiredLength = method.getParameterTypes().length;
-        ListUtils.adjust(args, requiredLength);
+        adjust(method, args, adapterManager);
 
         final ObjectAdapter[] argArray = args.toArray(new ObjectAdapter[]{});
-        
         return AdapterInvokeUtils.invoke(method, target, argArray);
     }
-    
+
+    private static void adjust(final Method method, final List<ObjectAdapter> args, final AdapterManager adapterManager) {
+        final Class<?>[] parameterTypes = method.getParameterTypes();
+        ListUtils.adjust(args, parameterTypes.length);
+        
+        for(int i=0; i<parameterTypes.length; i++) {
+            final Class<?> cls = parameterTypes[i];
+            if(args.get(i) == null && cls.isPrimitive()) {
+                final Object object = WrapperUtils.defaultFor(cls);
+                final ObjectAdapter adapter = adapterManager.adapterFor(object);
+                args.set(i, adapter);
+            }
+        }
+    }
+
     /**
      * Invokes the method, adjusting arguments as required.
      * 

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
index 1cc406e..1b1a0f0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
@@ -32,6 +32,7 @@ import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
 import org.apache.isis.core.commons.lang.ListUtils;
 import org.apache.isis.core.commons.lang.StringUtils;
+import org.apache.isis.core.commons.lang.WrapperUtils;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.QuerySubmitter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
@@ -358,7 +359,7 @@ public abstract class ObjectActionParameterAbstract implements ObjectActionParam
      * Hook method; {@link ObjectActionParameterContributee contributed action parameter}s override.
      */
     protected List<ObjectAdapter> argsForDefaultOrChoices(final ObjectAdapter adapter, final List<ObjectAdapter> argumentsIfAvailable) {
-        return null;
+        return argumentsIfAvailable;
     }
 
     
@@ -366,9 +367,20 @@ public abstract class ObjectActionParameterAbstract implements ObjectActionParam
 
     static void checkChoicesOrAutoCompleteType(final SpecificationLoader specificationLookup, final Object[] objects, final ObjectSpecification paramSpec) {
         for (final Object object : objects) {
-            final ObjectSpecification componentSpec = specificationLookup.loadSpecification(object.getClass());
-            if (!componentSpec.isOfType(paramSpec)) {
-                throw new DomainModelException("Type incompatible with parameter type; expected " + paramSpec.getFullIdentifier() + ", but was " + componentSpec.getFullIdentifier());
+
+            // check type, but wrap first 
+            // (eg we treat int.class and java.lang.Integer.class as compatible with each other)
+            final Class<? extends Object> choiceClass = object.getClass();
+            final Class<?> paramClass = paramSpec.getCorrespondingClass();
+            
+            final Class<? extends Object> choiceWrappedClass = WrapperUtils.wrapAsNecessary(choiceClass);
+            final Class<? extends Object> paramWrappedClass = WrapperUtils.wrapAsNecessary(paramClass);
+            
+            final ObjectSpecification choiceWrappedSpec = specificationLookup.loadSpecification(choiceWrappedClass);
+            final ObjectSpecification paramWrappedSpec = specificationLookup.loadSpecification(paramWrappedClass);
+            
+            if (!choiceWrappedSpec.isOfType(paramWrappedSpec)) {
+                throw new DomainModelException("Type incompatible with parameter type; expected " + paramSpec.getFullIdentifier() + ", but was " + choiceClass.getName());
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java
index 7f78b52..548f549 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/choices/methodnum/ActionParameterChoicesFacetViaMethod.java
@@ -66,7 +66,7 @@ public class ActionParameterChoicesFacetViaMethod extends ActionParameterChoices
 
     @Override
     public Object[] getChoices(final ObjectAdapter adapter, final List<ObjectAdapter> argumentsIfAvailable) {
-        final Object choices = AdapterInvokeUtils.invokeAutofit(method, adapter, argumentsIfAvailable);
+        final Object choices = AdapterInvokeUtils.invokeAutofit(method, adapter, argumentsIfAvailable, getAdapterManager());
         if (choices == null) {
             return new Object[0];
         }

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetFactory.java
index c4fd3b5..66f10ca 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetFactory.java
@@ -24,6 +24,8 @@ import java.util.List;
 
 import org.apache.isis.core.commons.lang.ListUtils;
 import org.apache.isis.core.commons.lang.NameUtils;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
 import org.apache.isis.core.metamodel.exceptions.MetaModelException;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
@@ -39,10 +41,12 @@ import org.apache.isis.core.progmodel.facets.MethodPrefixConstants;
 /**
  * Sets up all the {@link Facet}s for an action in a single shot.
  */
-public class ActionParameterDefaultsFacetFactory extends MethodPrefixBasedFacetFactoryAbstract {
+public class ActionParameterDefaultsFacetFactory extends MethodPrefixBasedFacetFactoryAbstract implements AdapterManagerAware {
 
     private static final String[] PREFIXES = {};
 
+    private AdapterManager adapterManager;
+
     /**
      * Note that the {@link Facet}s registered are the generic ones from
      * noa-architecture (where they exist)
@@ -64,7 +68,7 @@ public class ActionParameterDefaultsFacetFactory extends MethodPrefixBasedFacetF
         attachDefaultFacetForParametersIfDefaultsNumMethodIsFound(processMethodContext, holderList);
     }
 
-    private static void attachDefaultFacetForParametersIfDefaultsNumMethodIsFound(final ProcessMethodContext processMethodContext, final List<FacetedMethodParameter> parameters) {
+    private void attachDefaultFacetForParametersIfDefaultsNumMethodIsFound(final ProcessMethodContext processMethodContext, final List<FacetedMethodParameter> parameters) {
 
         if (parameters.isEmpty()) {
             return;
@@ -91,7 +95,7 @@ public class ActionParameterDefaultsFacetFactory extends MethodPrefixBasedFacetF
 
             // add facets directly to parameters, not to actions
             final FacetedMethodParameter paramAsHolder = parameters.get(i);
-            FacetUtil.addFacet(new ActionParameterDefaultsFacetViaMethod(defaultMethod, paramAsHolder));
+            FacetUtil.addFacet(new ActionParameterDefaultsFacetViaMethod(defaultMethod, paramAsHolder, getAdapterManager()));
         }
     }
 
@@ -127,4 +131,18 @@ public class ActionParameterDefaultsFacetFactory extends MethodPrefixBasedFacetF
         return MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, MethodPrefixConstants.DEFAULT_PREFIX + n + capitalizedName, returnType, paramTypes);
     }
 
+    // ///////////////////////////////////////////////////////////////
+    // Dependencies
+    // ///////////////////////////////////////////////////////////////
+
+    @Override
+    public void setAdapterManager(final AdapterManager adapterManager) {
+        this.adapterManager = adapterManager;
+    }
+
+    private AdapterManager getAdapterManager() {
+        return adapterManager;
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/a5fca252/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetViaMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetViaMethod.java
index fd8952d..6832806 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/param/defaults/methodnum/ActionParameterDefaultsFacetViaMethod.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
 import org.apache.isis.core.metamodel.adapter.util.AdapterInvokeUtils;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
@@ -32,10 +33,12 @@ import org.apache.isis.core.progmodel.facets.param.defaults.ActionParameterDefau
 public class ActionParameterDefaultsFacetViaMethod extends ActionParameterDefaultsFacetAbstract implements ImperativeFacet {
 
     private final Method method;
+    private final AdapterManager adapterManager;
 
-    public ActionParameterDefaultsFacetViaMethod(final Method method, final FacetHolder holder) {
+    public ActionParameterDefaultsFacetViaMethod(final Method method, final FacetHolder holder, final AdapterManager adapterManager) {
         super(holder);
         this.method = method;
+        this.adapterManager = adapterManager;
     }
 
     /**
@@ -59,7 +62,7 @@ public class ActionParameterDefaultsFacetViaMethod extends ActionParameterDefaul
 
     @Override
     public Object getDefault(final ObjectAdapter target, List<ObjectAdapter> argumentsIfAvailable) {
-        return AdapterInvokeUtils.invokeAutofit(method, target, argumentsIfAvailable);
+        return AdapterInvokeUtils.invokeAutofit(method, target, argumentsIfAvailable, getAdapterManager());
     }
 
 
@@ -69,4 +72,12 @@ public class ActionParameterDefaultsFacetViaMethod extends ActionParameterDefaul
         return "method=" + method;
     }
 
+    // /////////////////////////////////////////////////////////
+    // Dependencies
+    // /////////////////////////////////////////////////////////
+
+    protected AdapterManager getAdapterManager() {
+        return adapterManager;
+    }
+
 }


[2/2] git commit: ISIS-478: done (EntityLinkSelect2Panel working)

Posted by da...@apache.org.
ISIS-478: done (EntityLinkSelect2Panel working)

* EntityLinkSelect2Panel now also supports dynamic choices (as well as ValueChoicesSelect2Panel, previously)

in addition:
* factored out common code with ValueChoicesSelect2Panel(the ScalarModelWithPending interface)
* split EntityLinkSelect2Panel into another, simpler, panel - EntityLinkSimplePanel, just for showing icon/links


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

Branch: refs/heads/master
Commit: 52bc369a0906a900fbbddf3cd7ae610d75b987a3
Parents: a5fca25
Author: Dan Haywood <da...@apache.org>
Authored: Fri Aug 23 18:00:16 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Fri Aug 23 18:00:16 2013 +0100

----------------------------------------------------------------------
 .../ComponentFactoryRegistrarDefault.java       |   5 +-
 .../viewer/wicket/model/models/EntityModel.java |   8 ++
 .../viewer/wicket/model/models/ScalarModel.java |  45 ++++++-
 .../model/models/ScalarModelWithPending.java    |  88 +++++++++++++
 .../actions/ActionParametersFormPanel.java      |   1 +
 .../entitylink/EntityLinkSelect2Panel.java      | 108 ++++++----------
 .../EntityLinkSelect2PanelFactory.java          |   9 +-
 .../entitysimplelink/EntityLinkSimplePanel.css  |  32 +++++
 .../entitysimplelink/EntityLinkSimplePanel.html |  41 ++++++
 .../entitysimplelink/EntityLinkSimplePanel.java | 127 +++++++++++++++++++
 .../EntityLinkSimplePanelFactory.java           |  55 ++++++++
 .../valuechoices/ValueChoicesSelect2Panel.java  |  65 +++-------
 12 files changed, 462 insertions(+), 122 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
index f6bec25..dd44a9d 100644
--- a/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
+++ b/component/viewer/wicket/impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
@@ -78,6 +78,7 @@ import org.apache.isis.viewer.wicket.ui.components.value.StandaloneValuePanelFac
 import org.apache.isis.viewer.wicket.ui.components.voidreturn.VoidReturnPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.welcome.WelcomePanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.widgets.entitylink.EntityLinkSelect2PanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.widgets.entitysimplelink.EntityLinkSimplePanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.widgets.valuechoices.ValueChoicesSelect2PanelComponentFactory;
 
 /**
@@ -227,7 +228,9 @@ public class ComponentFactoryRegistrarDefault implements ComponentFactoryRegistr
     }
 
     protected void addComponentFactoriesForEntityLink(final ComponentFactoryList componentFactories) {
-        componentFactories.add(new EntityLinkSelect2PanelFactory());
+        // must come before EntityLinkSimplePanelFactory (as is more specific) 
+        componentFactories.add(new EntityLinkSelect2PanelFactory()); 
+        componentFactories.add(new EntityLinkSimplePanelFactory());
     }
 
     protected void addComponentFactoriesForVoidReturn(final ComponentFactoryList componentFactories) {

http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
index fb13569..fa85991 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityModel.java
@@ -482,6 +482,10 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
             return hasPending ? getPendingAdapter() : entityModel.getObject();
         }
 
+        public ObjectAdapterMemento getPending() {
+            return pending;
+        }
+        
         public void setPending(ObjectAdapterMemento selectedAdapterMemento) {
             this.pending = selectedAdapterMemento;
             hasPending=true;
@@ -498,6 +502,10 @@ public class EntityModel extends BookmarkableModel<ObjectAdapter> {
     public ObjectAdapter getPendingAdapter() {
         return pendingModel.getPendingAdapter();
     }
+    
+    public ObjectAdapterMemento getPending() {
+        return pendingModel.getPending();
+    }
 
     public void setPending(ObjectAdapterMemento selectedAdapterMemento) {
         pendingModel.setPending(selectedAdapterMemento);

http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
index 30667de..4e5ec93 100644
--- a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
@@ -43,7 +43,6 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionParameterAbstract;
 import org.apache.isis.core.progmodel.facets.value.bigdecimal.BigDecimalValueFacet;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
@@ -611,6 +610,7 @@ public class ScalarModel extends EntityModel implements LinksProvider {
      */
     private List<LinkAndLabel> entityActions = Lists.newArrayList();
 
+    
     public void addEntityActions(List<LinkAndLabel> entityActions) {
         this.entityActions.addAll(entityActions);
     }
@@ -627,6 +627,49 @@ public class ScalarModel extends EntityModel implements LinksProvider {
         return kind.getAutoCompleteOrChoicesMinLength(this);
     }
 
+    /**
+     * @return
+     */
+    public ScalarModelWithPending asScalarModelWithPending() {
+        return new ScalarModelWithPending(){
+
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public ObjectAdapterMemento getPending() {
+                return ScalarModel.this.getPending();
+            }
+
+            @Override
+            public void setPending(ObjectAdapterMemento pending) {
+                ScalarModel.this.setPending(pending);
+            }
+
+            @Override
+            public ScalarModel getScalarModel() {
+                return ScalarModel.this;
+            }
+        };
+    }
+
 
+    // //////////////////////////////////////
+
+    /**
+     * transient because only temporary hint.
+     */
+    private transient ObjectAdapter[] actionArgsHint;
+
+    public void setActionArgsHint(ObjectAdapter[] actionArgsHint) {
+        this.actionArgsHint = actionArgsHint;
+    }
+
+    /**
+     * The initial call of choicesXxx() for any given scalar argument needs the current values
+     * of all args (possibly as initialized through a defaultNXxx().
+     */
+    public ObjectAdapter[] getActionArgsHint() {
+        return actionArgsHint;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModelWithPending.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModelWithPending.java b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModelWithPending.java
new file mode 100644
index 0000000..3e0109a
--- /dev/null
+++ b/component/viewer/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModelWithPending.java
@@ -0,0 +1,88 @@
+/**
+ *  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.io.Serializable;
+
+import org.apache.wicket.model.Model;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
+import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
+
+/**
+ * For widgets that use a <tt>com.vaynberg.wicket.select2.Select2Choice</tt>; 
+ * synchronizes the {@link Model} of the <tt>Select2Choice</tt>  
+ * with the parent {@link ScalarModel}, allowing also for pending values.
+ */
+public interface ScalarModelWithPending extends Serializable {
+    
+    public ObjectAdapterMemento getPending();
+    public void setPending(ObjectAdapterMemento pending);
+    
+    public ScalarModel getScalarModel();
+    
+    static class Util {
+        
+        private static final Logger LOG = LoggerFactory.getLogger(ScalarModelWithPending.Util.class);
+        
+        public static Model<ObjectAdapterMemento> createModel(final ScalarModelWithPending owner) {
+            return new Model<ObjectAdapterMemento>() {
+
+                private static final long serialVersionUID = 1L;
+
+                @Override
+                public ObjectAdapterMemento getObject() {
+                    if (owner.getPending() != null) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("pending not null: " + owner.getPending().toString());
+                        }
+                        return owner.getPending();
+                    }
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("pending is null");
+                    }
+                    
+                    final ObjectAdapterMemento objectAdapterMemento = owner.getScalarModel().getObjectAdapterMemento();
+                    owner.setPending(objectAdapterMemento);
+
+//                    final ObjectAdapter adapter = scalarModel.getObject(); 
+//                    return ObjectAdapterMemento.createOrNull(adapter);
+                    return objectAdapterMemento;
+                }
+
+                @Override
+                public void setObject(final ObjectAdapterMemento adapterMemento) {
+                    if (adapterMemento != null) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("setting to: " + adapterMemento.toString());
+                        }
+                        owner.setPending(adapterMemento);
+                    }
+                    if (owner.getScalarModel() != null && owner.getPending() != null) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("setting to pending: " + owner.getPending().toString());
+                        }
+                        owner.getScalarModel().setObject(owner.getPending().getObjectAdapter(ConcurrencyChecking.NO_CHECK));
+                    }
+                }
+            };
+        }
+
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
index c168ec5..b2aa843 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
@@ -127,6 +127,7 @@ public class ActionParametersFormPanel extends PanelAbstract<ActionModel> {
                 rv.add(container);
 
                 final ScalarModel argumentModel = actionModel.getArgumentModel(apm);
+                argumentModel.setActionArgsHint(actionModel.getArgumentsAsArray());
                 final Component component = getComponentFactoryRegistry().addOrReplaceComponent(container, ComponentType.SCALAR_NAME_AND_VALUE, argumentModel);
                 final ScalarPanelAbstract paramPanel = component instanceof ScalarPanelAbstract ? (ScalarPanelAbstract) component : null;
                 paramPanels.add(paramPanel);

http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
index 74f4ffa..7969a43 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2Panel.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.viewer.wicket.ui.components.widgets.entitylink;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -33,6 +32,7 @@ import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.FormComponentPanel;
 import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.model.IModel;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
@@ -46,8 +46,8 @@ import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
 import org.apache.isis.viewer.wicket.model.models.ActionModel;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
 import org.apache.isis.viewer.wicket.model.models.EntityModel.RenderingHint;
-import org.apache.isis.viewer.wicket.model.models.ModelAbstract;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.model.models.ScalarModelWithPending.Util;
 import org.apache.isis.viewer.wicket.model.util.Mementos;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
@@ -74,21 +74,20 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
     private Link<String> entityDetailsLink;
     private Link<String> entityClearLink;
 
-    public EntityLinkSelect2Panel(final String id, final EntityModel entityModel) {
-        super(id, entityModel);
+    public EntityLinkSelect2Panel(final String id, final ScalarModel scalarModel) {
+        super(id, scalarModel);
         setType(ObjectAdapter.class);
         buildGui();
     }
 
-    public EntityModel getEntityModel() {
-        return (EntityModel) getModel();
+    public ScalarModel getScalarModel() {
+        return (ScalarModel) getModel();
     }
 
     /**
      * Builds the parts of the GUI that are not dynamic.
      */
     private void buildGui() {
-        //addOrReplace(new ComponentFeedbackPanel(ID_FEEDBACK, this));
         syncWithInput();
     }
 
@@ -106,14 +105,14 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
      */
     public void syncVisibilityAndUsability() {
         
-        final boolean mutability = isEnableAllowed() && !getEntityModel().isViewMode();
+        final boolean mutability = isEnableAllowed() && !getScalarModel().isViewMode();
 
         if(entityClearLink != null) {
             entityClearLink.setVisible(mutability);
         }
 
         if(entityDetailsLink != null) {
-            entityDetailsLink.setVisible(getEntityModel().getRenderingHint() == RenderingHint.REGULAR);
+            entityDetailsLink.setVisible(getScalarModel().getRenderingHint() == RenderingHint.REGULAR);
         }
         
         if(select2Field != null) {
@@ -143,19 +142,19 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
      */
     @Override
     public String getInput() {
-        final ObjectAdapter pendingElseCurrentAdapter = getEntityModel().getPendingElseCurrentAdapter();
+        final ObjectAdapter pendingElseCurrentAdapter = getScalarModel().getPendingElseCurrentAdapter();
         return pendingElseCurrentAdapter != null? pendingElseCurrentAdapter.titleString(null): "(no object)";
     }
 
     @Override
     protected void convertInput() {
 
-        if(getEntityModel().isEditMode() && isEditableWithEitherAutoCompleteOrChoices()) {
+        if(getScalarModel().isEditMode() && isEditableWithEitherAutoCompleteOrChoices()) {
             // flush changes to pending
             onSelected(select2Field.getConvertedInput());
         }
 
-        final ObjectAdapter pendingAdapter = getEntityModel().getPendingAdapter();
+        final ObjectAdapter pendingAdapter = getScalarModel().getPendingAdapter();
         setConvertedInput(pendingAdapter);
     }
 
@@ -187,24 +186,16 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
             permanentlyHide(ID_AUTO_COMPLETE);
             return;
         }
-        
 
-        final ModelAbstract<ObjectAdapterMemento> model = new ModelAbstract<ObjectAdapterMemento>(){
-            private static final long serialVersionUID = 1L;
-            
-            @Override
-            protected ObjectAdapterMemento load() {
-                return ObjectAdapterMemento.createOrNull(getPendingElseCurrentAdapter());
-            }
-            
-        };
+        
+        final IModel<ObjectAdapterMemento> model = Util.createModel(getScalarModel().asScalarModelWithPending());       
 
         if(select2Field == null) {
             select2Field = new Select2Choice<ObjectAdapterMemento>(ID_AUTO_COMPLETE, model);
-            setChoices(null);
-            if(!hasChoices()) {
+            setChoices(getScalarModel().getActionArgsHint());
+            if(!getScalarModel().hasChoices()) {
                 final Settings settings = select2Field.getSettings();
-                ScalarModel scalarModel = (ScalarModel) getEntityModel();
+                ScalarModel scalarModel = (ScalarModel) getScalarModel();
                 final int minLength = scalarModel.getAutoCompleteMinLength();
                 settings.setMinimumInputLength(minLength);
             }
@@ -223,7 +214,7 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
 
 
     private ChoiceProvider<ObjectAdapterMemento> providerForObjectAutoComplete() {
-        final EntityModel entityModel = getEntityModel();
+        final EntityModel entityModel = getScalarModel();
         return new ObjectAdapterMementoProviderAbstract() {
 
             private static final long serialVersionUID = 1L;
@@ -240,7 +231,7 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
     }
 
     private ChoiceProvider<ObjectAdapterMemento> providerForParamOrPropertyAutoComplete() {
-        final EntityModel entityModel = getEntityModel();
+        final EntityModel entityModel = getScalarModel();
         return new ObjectAdapterMementoProviderAbstract() {
             
             private static final long serialVersionUID = 1L;
@@ -265,7 +256,7 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
     
     private List<ObjectAdapterMemento> getChoiceMementos(final ObjectAdapter[] argsIfAvailable) {
         
-        final ScalarModel scalarModel = (ScalarModel) getEntityModel();;
+        final ScalarModel scalarModel = (ScalarModel) getScalarModel();;
         final boolean hasChoices = scalarModel.hasChoices();
         if(!hasChoices) {
             return Collections.emptyList();
@@ -300,6 +291,12 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
             permanentlyHide(ID_ENTITY_CLEAR_LINK);
             return;
         } 
+        
+        if(getScalarModel().isRequired()) {
+            permanentlyHide(ID_ENTITY_CLEAR_LINK);
+            return;
+        }
+        
         entityClearLink = new Link<String>(ID_ENTITY_CLEAR_LINK) {
             private static final long serialVersionUID = 1L;
 
@@ -314,8 +311,8 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
 
     private void addOrReplaceIconAndTitle(ObjectAdapter pendingOrCurrentAdapter) {
         final EntityModel entityModelForLink = new EntityModel(pendingOrCurrentAdapter);
-        entityModelForLink.setContextAdapterIfAny(getEntityModel().getContextAdapterIfAny());
-        entityModelForLink.setRenderingHint(getEntityModel().getRenderingHint());
+        entityModelForLink.setContextAdapterIfAny(getScalarModel().getContextAdapterIfAny());
+        entityModelForLink.setRenderingHint(getScalarModel().getRenderingHint());
         final ComponentFactory componentFactory = getComponentFactoryRegistry().findComponentFactory(ComponentType.ENTITY_ICON_AND_TITLE, entityModelForLink);
         final Component component = componentFactory.createComponent(entityModelForLink);
         addOrReplace(component);
@@ -342,7 +339,7 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
     }
 
     public void onSelected(final ObjectAdapterMemento selectedAdapterMemento) {
-        getEntityModel().setPending(selectedAdapterMemento);
+        getScalarModel().setPending(selectedAdapterMemento);
         renderSamePage();
     }
 
@@ -352,11 +349,11 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
 
     @Override
     public void onCancel() {
-        getEntityModel().clearPending();
+        getScalarModel().clearPending();
     }
 
     private ObjectAdapter getPendingElseCurrentAdapter() {
-        return getEntityModel().getPendingElseCurrentAdapter();
+        return getScalarModel().getPendingElseCurrentAdapter();
     }
 
     private void renderSamePage() {
@@ -365,50 +362,30 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
     
     private boolean isEditableWithEitherAutoCompleteOrChoices() {
         // never doesn't apply in compact rendering contexts (ie tables)
-        if(getEntityModel().getRenderingHint().isInTable()) {
+        if(getScalarModel().getRenderingHint().isInTable()) {
             return false;
         }
         // doesn't apply if not editable, either
-        if(getEntityModel().isViewMode()) {
+        if(getScalarModel().isViewMode()) {
             return false;
         }
-        return hasChoices() || hasParamOrPropertyAutoComplete() || hasObjectAutoComplete();
-    }
-
-    private boolean hasChoices() {
-        final EntityModel entityModel = getEntityModel();
-        if (!(entityModel instanceof ScalarModel)) {
-            return false;
-        } 
-        final ScalarModel scalarModel = (ScalarModel) entityModel;
-        return scalarModel.hasChoices();
+        return getScalarModel().hasChoices() || hasParamOrPropertyAutoComplete() || hasObjectAutoComplete();
     }
 
     private boolean hasParamOrPropertyAutoComplete() {
-        final EntityModel entityModel = getEntityModel();
-        if (!(entityModel instanceof ScalarModel)) {
-            return false;
-        } 
-        final ScalarModel scalarModel = (ScalarModel) entityModel;
-        return scalarModel.hasAutoComplete();
+        return getScalarModel().hasAutoComplete();
     }
 
     private boolean hasObjectAutoComplete() {
 
         // on property/param
-        final EntityModel entityModel = getEntityModel();
-        if (!(entityModel instanceof ScalarModel)) {
-            return false;
-        } 
-        final ScalarModel scalarModel = (ScalarModel) entityModel;
-        boolean hasAutoComplete = scalarModel.hasAutoComplete();
+        boolean hasAutoComplete = getScalarModel().hasAutoComplete();
         if(hasAutoComplete) {
             return true;
         }
-
         
         // else on underlying type
-        final ObjectSpecification typeOfSpecification = getEntityModel().getTypeOfSpecification();
+        final ObjectSpecification typeOfSpecification = getScalarModel().getTypeOfSpecification();
         final AutoCompleteFacet autoCompleteFacet = 
                 (typeOfSpecification != null)? typeOfSpecification.getFacet(AutoCompleteFacet.class):null;
         return autoCompleteFacet != null;
@@ -427,7 +404,7 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
     private void setChoices(final ObjectAdapter[] argsIfAvailable) {
         
         final ChoiceProvider<ObjectAdapterMemento> provider;
-        if (hasChoices()) {
+        if (getScalarModel().hasChoices()) {
             final List<ObjectAdapterMemento> choiceMementos = getChoiceMementos(argsIfAvailable);
             provider = new ObjectAdapterMementoProviderAbstract() {
                 private static final long serialVersionUID = 1L;
@@ -436,10 +413,9 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
                     return choiceMementos;
                 }
             };
-            select2Field.setProvider(provider);
-            getEntityModel().clearPending();
             final ObjectAdapterMemento curr = select2Field.getModelObject();
-            final ObjectAdapterMemento curr2 = getEntityModel().getObjectAdapterMemento();
+            select2Field.setProvider(provider);
+            getScalarModel().clearPending();
             if(curr == null || !curr.containedIn(choiceMementos)) {
                 final ObjectAdapterMemento newAdapterMemento = 
                         !choiceMementos.isEmpty() 
@@ -448,17 +424,15 @@ public class EntityLinkSelect2Panel extends FormComponentPanelAbstract<ObjectAda
                         select2Field.getModel().setObject(newAdapterMemento);
                         getModel().setObject(
                                 newAdapterMemento != null? newAdapterMemento.getObjectAdapter(ConcurrencyChecking.NO_CHECK): null);
-            } else {
-                //select2Field.getModel().setObject(curr);
             }
         } else if(hasParamOrPropertyAutoComplete()) {
             provider = providerForParamOrPropertyAutoComplete();
             select2Field.setProvider(provider);
-            getEntityModel().setPending(null);
+            getScalarModel().setPending(null);
         } else {
             provider = providerForObjectAutoComplete();
             select2Field.setProvider(provider);
-            getEntityModel().setPending(null);
+            getScalarModel().setPending(null);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2PanelFactory.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2PanelFactory.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2PanelFactory.java
index d3da397..cbe4f34 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2PanelFactory.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitylink/EntityLinkSelect2PanelFactory.java
@@ -25,6 +25,7 @@ import org.apache.wicket.model.IModel;
 import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 
@@ -38,17 +39,17 @@ public class EntityLinkSelect2PanelFactory extends ComponentFactoryAbstract {
 
     @Override
     public ApplicationAdvice appliesTo(final IModel<?> model) {
-        if (!(model instanceof EntityModel)) {
+        if (!(model instanceof ScalarModel)) {
             return ApplicationAdvice.DOES_NOT_APPLY;
         }
-        final EntityModel entityModel = (EntityModel) model;
+        final ScalarModel entityModel = (ScalarModel) model;
         final ObjectSpecification specification = entityModel.getTypeOfSpecification();
         return appliesIf(specification != null && !specification.containsFacet(ValueFacet.class));
     }
 
     @Override
     public Component createComponent(final String id, final IModel<?> model) {
-        final EntityModel entityModel = (EntityModel) model;
-        return new EntityLinkSelect2Panel(id, entityModel);
+        final ScalarModel scalarModel = (ScalarModel) model;
+        return new EntityLinkSelect2Panel(id, scalarModel);
     }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.css
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.css b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.css
new file mode 100644
index 0000000..ca08a38
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.css
@@ -0,0 +1,32 @@
+/*
+ *  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.
+ */
+div.entitySimpleLinkPanel  {
+	display: inline
+}
+
+div.entitySimpleLinkPanel > div {
+	margin-left: 2px;
+}
+
+.entitySimpleLinkPanel .entityImage {
+	width: 16px;
+	height: 16px;
+}
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.html
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.html b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.html
new file mode 100644
index 0000000..f0402b8
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"  
+      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"  
+      xml:lang="en"  
+      lang="en">
+	<wicket:head>
+		<wicket:link>
+			<link href="EntityLinkSimplePanel.css" rel="stylesheet" type="text/css"/>
+		</wicket:link>
+	</wicket:head>
+	<body>
+		<wicket:panel>
+			<div class="entityLinkSimplePanel entityLinkComponentType">
+				<div>
+					<span wicket:id="entityIconAndTitle">[icon and title]</span>
+					<span wicket:id="entityTitleNull">(null)</span>
+				    <div class="clear"/>
+	  			</div>
+			</div>
+		</wicket:panel>
+	</body>
+</html>

http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.java
new file mode 100644
index 0000000..c161e23
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanel.java
@@ -0,0 +1,127 @@
+/*
+ *  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.ui.components.widgets.entitysimplelink;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.google.common.collect.Lists;
+import com.vaynberg.wicket.select2.ChoiceProvider;
+import com.vaynberg.wicket.select2.Select2Choice;
+import com.vaynberg.wicket.select2.Settings;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.FormComponentPanel;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
+import org.apache.isis.core.metamodel.spec.ActionType;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.runtime.system.DeploymentType;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
+import org.apache.isis.viewer.wicket.model.models.ActionModel;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.model.models.ScalarModelWithPending;
+import org.apache.isis.viewer.wicket.model.models.EntityModel.RenderingHint;
+import org.apache.isis.viewer.wicket.model.models.ScalarModelWithPending.Util;
+import org.apache.isis.viewer.wicket.model.models.ModelAbstract;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.model.util.Mementos;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+import org.apache.isis.viewer.wicket.ui.components.actions.ActionInvokeHandler;
+import org.apache.isis.viewer.wicket.ui.components.widgets.ObjectAdapterMementoProviderAbstract;
+import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.CancelHintRequired;
+import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.FormComponentPanelAbstract;
+
+/**
+ * {@link FormComponentPanel} representing a reference to an entity: a link and
+ * (optionally) an autocomplete field.
+ */
+public class EntityLinkSimplePanel extends FormComponentPanelAbstract<ObjectAdapter> implements CancelHintRequired, ActionInvokeHandler  {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final String ID_ENTITY_ICON_AND_TITLE = "entityIconAndTitle";
+    private static final String ID_ENTITY_TITLE_NULL = "entityTitleNull";
+    
+    public EntityLinkSimplePanel(final String id, final EntityModel entityModel) {
+        super(id, entityModel);
+        setType(ObjectAdapter.class);
+        buildGui();
+    }
+
+    public EntityModel getEntityModel() {
+        return (EntityModel) getModel();
+    }
+
+    private void buildGui() {
+        syncWithInput();
+    }
+
+
+    @Override
+    protected void onBeforeRender() {
+        syncWithInput();
+        super.onBeforeRender();
+    }
+
+    private void syncWithInput() {
+        final ObjectAdapter adapter = getPendingElseCurrentAdapter();
+
+        if (adapter != null) {
+            final EntityModel entityModelForLink = new EntityModel(adapter);
+            entityModelForLink.setContextAdapterIfAny(getEntityModel().getContextAdapterIfAny());
+            entityModelForLink.setRenderingHint(getEntityModel().getRenderingHint());
+            
+            final ComponentFactory componentFactory = getComponentFactoryRegistry().findComponentFactory(ComponentType.ENTITY_ICON_AND_TITLE, entityModelForLink);
+            final Component component = componentFactory.createComponent(entityModelForLink);
+            addOrReplace(component);
+            
+            permanentlyHide(ID_ENTITY_TITLE_NULL);
+        } else {
+            // represent no object by a simple label displaying '(null)'
+            addOrReplace(new Label(ID_ENTITY_TITLE_NULL, ""));
+            permanentlyHide(ID_ENTITY_ICON_AND_TITLE);
+        }
+    }
+
+    @Override
+    public void onClick(final ActionModel actionModel) {
+    }
+
+    @Override
+    public void onCancel() {
+    }
+
+    private ObjectAdapter getPendingElseCurrentAdapter() {
+        return getEntityModel().getPendingElseCurrentAdapter();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanelFactory.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanelFactory.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanelFactory.java
new file mode 100644
index 0000000..9286148
--- /dev/null
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/entitysimplelink/EntityLinkSimplePanelFactory.java
@@ -0,0 +1,55 @@
+/*
+ *  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.ui.components.widgets.entitysimplelink;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.model.IModel;
+
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+
+public class EntityLinkSimplePanelFactory extends ComponentFactoryAbstract {
+
+    private static final long serialVersionUID = 1L;
+
+    public EntityLinkSimplePanelFactory() {
+        super(ComponentType.ENTITY_LINK);
+    }
+
+    @Override
+    public ApplicationAdvice appliesTo(final IModel<?> model) {
+        if (!(model instanceof EntityModel)) {
+            return ApplicationAdvice.DOES_NOT_APPLY;
+        }
+        final EntityModel entityModel = (EntityModel) model;
+        final ObjectSpecification specification = entityModel.getTypeOfSpecification();
+        return appliesIf(specification != null && !specification.containsFacet(ValueFacet.class));
+    }
+
+    @Override
+    public Component createComponent(final String id, final IModel<?> model) {
+        final EntityModel scalarModel = (EntityModel) model;
+        return new EntityLinkSimplePanel(id, scalarModel);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/52bc369a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ValueChoicesSelect2Panel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ValueChoicesSelect2Panel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ValueChoicesSelect2Panel.java
index 12d10c8..693b607 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ValueChoicesSelect2Panel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/valuechoices/ValueChoicesSelect2Panel.java
@@ -34,8 +34,6 @@ import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.FormComponentLabel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
@@ -44,16 +42,13 @@ import org.apache.isis.core.metamodel.adapter.oid.RootOidDefault;
 import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
 import org.apache.isis.viewer.wicket.model.models.ModelAbstract;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.model.models.ScalarModelWithPending;
 import org.apache.isis.viewer.wicket.model.util.Mementos;
 import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
 import org.apache.isis.viewer.wicket.ui.components.widgets.ObjectAdapterMementoProviderAbstract;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
 
-/**
- * Initial skeleton - trying to add support for value choices.
- */
-public class ValueChoicesSelect2Panel extends ScalarPanelAbstract {
-    private static final Logger LOG = LoggerFactory.getLogger(ValueChoicesSelect2Panel.class);
+public class ValueChoicesSelect2Panel extends ScalarPanelAbstract implements ScalarModelWithPending {
 
     private static final long serialVersionUID = 1L;
 
@@ -75,7 +70,7 @@ public class ValueChoicesSelect2Panel extends ScalarPanelAbstract {
     @Override
     protected FormComponentLabel addComponentForRegular() {
 
-        final IModel<ObjectAdapterMemento> modelObject = createModel();
+        final IModel<ObjectAdapterMemento> modelObject = Util.createModel(this);
         
         select2Field = new Select2Choice<ObjectAdapterMemento>(ID_VALUE_ID, modelObject);
         setChoices(null);
@@ -101,43 +96,7 @@ public class ValueChoicesSelect2Panel extends ScalarPanelAbstract {
         return Lists.newArrayList(Lists.transform(choices, Mementos.fromAdapter()));
     }
 
-    private Model<ObjectAdapterMemento> createModel() {
-        return new Model<ObjectAdapterMemento>() {
-
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public ObjectAdapterMemento getObject() {
-                if (pending != null) {
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("TextField: pending not null: " + pending.toString());
-                    }
-                    return pending;
-                }
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("TextField: pending is null");
-                }
-                final ObjectAdapter adapter = ValueChoicesSelect2Panel.this.getModelValue();
-                return ObjectAdapterMemento.createOrNull(adapter);
-            }
 
-            @Override
-            public void setObject(final ObjectAdapterMemento adapterMemento) {
-                if (adapterMemento != null) {
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("TextField: setting to: " + adapterMemento.toString());
-                    }
-                    pending = adapterMemento;
-                }
-                if (scalarModel != null && pending != null) {
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("TextField: setting to pending: " + pending.toString());
-                    }
-                    scalarModel.setObject(pending.getObjectAdapter(ConcurrencyChecking.NO_CHECK));
-                }
-            }
-        };
-    }
 
     protected void addStandardSemantics() {
         setRequiredIfSpecified();
@@ -174,11 +133,6 @@ public class ValueChoicesSelect2Panel extends ScalarPanelAbstract {
         return labelIfCompact;
     }
 
-    protected ObjectAdapter getModelValue() {
-        pending = scalarModel.getObjectAdapterMemento();
-        return scalarModel.getObject();
-    }
-
     
     protected ChoiceProvider<ObjectAdapterMemento> newChoiceProvider(final List<ObjectAdapterMemento> choicesMementos) {
         ChoiceProvider<ObjectAdapterMemento> provider = new ObjectAdapterMementoProviderAbstract() {
@@ -254,4 +208,17 @@ public class ValueChoicesSelect2Panel extends ScalarPanelAbstract {
         }
     }
 
+    
+    // //////////////////////////////////////
+
+    public ObjectAdapterMemento getPending() {
+        return pending;
+    }
+    public void setPending(ObjectAdapterMemento pending) {
+        this.pending = pending;
+    }
+
+    public ScalarModel getScalarModel() {
+        return scalarModel;
+    }
 }