Repository: isis
Updated Branches:
  refs/heads/master fac70844b -> b66fb6e66


ISIS-1603: renames the refactored ScalarPanelAbstract and 
ScalarModelSubscriber, and brings back in older versions for backward 
compatibility


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

Branch: refs/heads/master
Commit: b66fb6e662a4273a00f94fea07725f813121d8e8
Parents: fac7084
Author: Dan Haywood <[email protected]>
Authored: Fri Apr 28 12:16:32 2017 +0100
Committer: Dan Haywood <[email protected]>
Committed: Fri Apr 28 12:18:03 2017 +0100

----------------------------------------------------------------------
 .../actions/ActionParametersFormPanel.java      |  13 +-
 .../components/collection/CollectionPanel.java  |   4 +-
 .../property/PropertyEditFormPanel.java         |  10 +-
 .../scalars/ScalarModelSubscriber2.java         |  27 +
 .../components/scalars/ScalarPanelAbstract.java | 603 +++++------------
 .../scalars/ScalarPanelAbstract2.java           | 677 +++++++++++++++++++
 .../scalars/ScalarPanelSelect2Abstract.java     |   2 +-
 .../scalars/ScalarPanelTextFieldAbstract.java   |   2 +-
 .../isisapplib/IsisBlobOrClobPanelAbstract.java |   4 +-
 .../scalars/primitive/BooleanPanel.java         |   4 +-
 .../scalars/reference/ReferencePanel.java       |   4 +-
 .../ui/components/scalars/value/ValuePanel.java |   5 +-
 .../components/value/StandaloneValuePanel.java  |   4 +-
 .../linkandlabel/ActionLinkFactoryAbstract.java |   4 +-
 .../ui/panels/PromptFormPanelAbstract.java      |  10 +-
 15 files changed, 920 insertions(+), 453 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
index 7db99e0..72e67bf 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersFormPanel.java
@@ -40,8 +40,8 @@ import org.apache.isis.viewer.wicket.model.models.ActionModel;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import 
org.apache.isis.viewer.wicket.ui.components.property.PropertyEditFormPanel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.PanelWithChoices;
-import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarModelSubscriber;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarModelSubscriber2;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.panels.PromptFormPanelAbstract;
@@ -69,7 +69,8 @@ public class ActionParametersFormPanel extends 
PromptFormPanelAbstract<ActionMod
         add(new ActionParameterForm("inputForm", this, this.getSettings(), 
model));
     }
 
-    class ActionParameterForm extends 
PropertyEditFormPanel.FormAbstract<ActionModel> implements 
ScalarModelSubscriber  {
+    class ActionParameterForm extends 
PropertyEditFormPanel.FormAbstract<ActionModel> implements
+            ScalarModelSubscriber2 {
 
         private static final long serialVersionUID = 1L;
 
@@ -102,7 +103,7 @@ public class ActionParametersFormPanel extends 
PromptFormPanelAbstract<ActionMod
                 
actionArgumentModel.setActionArgsHint(actionModel.getArgumentsAsArray());
                 final Component component = 
getComponentFactoryRegistry().addOrReplaceComponent(container, 
ComponentType.SCALAR_NAME_AND_VALUE,
                         actionArgumentModel);
-                final ScalarPanelAbstract paramPanel = component instanceof 
ScalarPanelAbstract ? (ScalarPanelAbstract) component : null;
+                final ScalarPanelAbstract2 paramPanel = component instanceof 
ScalarPanelAbstract2 ? (ScalarPanelAbstract2) component : null;
                 paramPanels.add(paramPanel);
                 if(paramPanel != null) {
                     paramPanel.setOutputMarkupId(true);
@@ -138,7 +139,7 @@ public class ActionParametersFormPanel extends 
PromptFormPanelAbstract<ActionMod
         }
 
         @Override
-        public void onUpdate(AjaxRequestTarget target, ScalarPanelAbstract 
scalarPanel) {
+        public void onUpdate(AjaxRequestTarget target, ScalarPanelAbstract2 
scalarPanel) {
 
             final ActionModel actionModel = getActionModel();
             
@@ -148,7 +149,7 @@ public class ActionParametersFormPanel extends 
PromptFormPanelAbstract<ActionMod
                 final ObjectAction action = 
actionModel.getActionMemento().getAction(getSpecificationLoader());
                 final int numParams = action.getParameterCount();
                 for (int i = 0; i < numParams; i++) {
-                    final ScalarPanelAbstract paramPanel = paramPanels.get(i);
+                    final ScalarPanelAbstract2 paramPanel = paramPanels.get(i);
                     if(paramPanel != null && paramPanel instanceof 
PanelWithChoices) {
                         final PanelWithChoices panelWithChoices = 
(PanelWithChoices) paramPanel;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
index c613ac9..71a0ec2 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/collection/CollectionPanel.java
@@ -38,14 +38,14 @@ import org.apache.isis.viewer.wicket.ui.ComponentType;
 import 
org.apache.isis.viewer.wicket.ui.components.actionmenu.entityactions.LinkAndLabelUtil;
 import 
org.apache.isis.viewer.wicket.ui.components.collection.selector.CollectionSelectorPanel;
 import 
org.apache.isis.viewer.wicket.ui.components.collection.selector.CollectionSelectorProvider;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 
 import 
de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
 
 /**
  * Panel for rendering entity collection; analogous to (any concrete subclass
- * of) {@link ScalarPanelAbstract}.
+ * of) {@link ScalarPanelAbstract2}.
  */
 public class CollectionPanel extends PanelAbstract<EntityCollectionModel> 
implements CollectionSelectorProvider {
 

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditFormPanel.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditFormPanel.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditFormPanel.java
index 65f22f3..64c4b16 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditFormPanel.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/property/PropertyEditFormPanel.java
@@ -31,8 +31,8 @@ import 
org.apache.isis.viewer.wicket.model.hints.IsisPropertyEditCompletedEvent;
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
-import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarModelSubscriber;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarModelSubscriber2;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.panels.PromptFormPanelAbstract;
 
@@ -56,7 +56,7 @@ public class PropertyEditFormPanel extends 
PromptFormPanelAbstract<ScalarModel>
         add(new PropertyEditForm("inputForm", this, this.getSettings(), 
model));
     }
 
-    class PropertyEditForm extends FormAbstract<ScalarModel> implements 
ScalarModelSubscriber  {
+    class PropertyEditForm extends FormAbstract<ScalarModel> implements 
ScalarModelSubscriber2 {
 
         private static final long serialVersionUID = 1L;
 
@@ -94,7 +94,7 @@ public class PropertyEditFormPanel extends 
PromptFormPanelAbstract<ScalarModel>
 
             final Component component =
                     
getComponentFactoryRegistry().addOrReplaceComponent(container, 
ComponentType.SCALAR_NAME_AND_VALUE, scalarModel);
-            final ScalarPanelAbstract paramPanel = component instanceof 
ScalarPanelAbstract ? (ScalarPanelAbstract) component : null;
+            final ScalarPanelAbstract2 paramPanel = component instanceof 
ScalarPanelAbstract2 ? (ScalarPanelAbstract2) component : null;
             if(paramPanel != null) {
                 paramPanel.setOutputMarkupId(true);
                 paramPanel.notifyOnChange(this);
@@ -109,7 +109,7 @@ public class PropertyEditFormPanel extends 
PromptFormPanelAbstract<ScalarModel>
 
         @Override
         public void onUpdate(
-                final AjaxRequestTarget target, final ScalarPanelAbstract 
scalarPanel) {
+                final AjaxRequestTarget target, final ScalarPanelAbstract2 
scalarPanel) {
 
         }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarModelSubscriber2.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarModelSubscriber2.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarModelSubscriber2.java
new file mode 100644
index 0000000..f2dc4b2
--- /dev/null
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarModelSubscriber2.java
@@ -0,0 +1,27 @@
+/**
+ *  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.scalars;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+
+public interface ScalarModelSubscriber2 {
+
+    void onUpdate(AjaxRequestTarget target, ScalarPanelAbstract2 scalarPanel);
+
+    void onError(AjaxRequestTarget target, ScalarPanelAbstract2 scalarPanel);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
index 72ebf8f..0428e09 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract.java
@@ -32,158 +32,153 @@ import org.apache.wicket.behavior.AttributeAppender;
 import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.feedback.ComponentFeedbackMessageFilter;
 import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.LabeledWebMarkupContainer;
-import org.apache.wicket.model.IModel;
+import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.model.Model;
 
 import org.apache.isis.applib.annotation.ActionLayout;
-import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import 
org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
 import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.labelat.LabelAtFacet;
 import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
 import org.apache.isis.viewer.wicket.model.models.ActionPrompt;
 import org.apache.isis.viewer.wicket.model.models.ActionPromptProvider;
-import org.apache.isis.viewer.wicket.model.models.EntityModel;
-import org.apache.isis.viewer.wicket.model.models.InlinePromptContext;
+import org.apache.isis.viewer.wicket.model.models.EntityModel.RenderingHint;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import 
org.apache.isis.viewer.wicket.ui.components.actionmenu.entityactions.AdditionalLinksPanel;
-import 
org.apache.isis.viewer.wicket.ui.components.actionmenu.entityactions.LinkAndLabelUtil;
-import 
org.apache.isis.viewer.wicket.ui.components.property.PropertyEditFormExecutor;
-import 
org.apache.isis.viewer.wicket.ui.components.property.PropertyEditFormPanel;
 import org.apache.isis.viewer.wicket.ui.components.property.PropertyEditPanel;
 import 
org.apache.isis.viewer.wicket.ui.components.property.PropertyEditPromptHeaderPanel;
-import 
org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisBlobOrClobPanelAbstract;
-import 
org.apache.isis.viewer.wicket.ui.components.scalars.primitive.BooleanPanel;
-import 
org.apache.isis.viewer.wicket.ui.components.scalars.reference.ReferencePanel;
-import 
org.apache.isis.viewer.wicket.ui.components.scalars.valuechoices.ValueChoicesSelect2Panel;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.TextFieldValueModel.ScalarModelProvider;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 import org.apache.isis.viewer.wicket.ui.util.Components;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
 
 import 
de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
 
-public abstract class ScalarPanelAbstract extends PanelAbstract<ScalarModel> 
implements ScalarModelSubscriber {
+/**
+ * Adapter for {@link PanelAbstract panel}s that use a {@link ScalarModel} as
+ * their backing model.
+ *
+ * <p>
+ * Supports the concept of being {@link Rendering#COMPACT} (eg within a table) 
or
+ * {@link Rendering#REGULAR regular} (eg within a form).
+ *
+ * <p>
+ *     REVIEW: this has been replaced by {@link ScalarPanelAbstract2} and is 
unused by the core framework.
+ *     It is however still used by some wicket addons (specifically, pdfjs).
+ * </p>
+ */
+public abstract class ScalarPanelAbstract extends PanelAbstract<ScalarModel> 
implements ScalarModelProvider {
 
     private static final long serialVersionUID = 1L;
 
-    protected static final String ID_SCALAR_TYPE_CONTAINER = 
"scalarTypeContainer";
-
-    protected static final String ID_SCALAR_IF_COMPACT = "scalarIfCompact";
     protected static final String ID_SCALAR_IF_REGULAR = "scalarIfRegular";
     protected static final String ID_SCALAR_NAME = "scalarName";
     protected static final String ID_SCALAR_VALUE = "scalarValue";
 
+    protected static final String ID_SCALAR_IF_COMPACT = "scalarIfCompact";
 
-    /**
-     * as per {@link #inlinePromptLink}
-     */
-    protected static final String ID_SCALAR_VALUE_INLINE_PROMPT_LINK = 
"scalarValueInlinePromptLink";
-    protected static final String ID_SCALAR_VALUE_INLINE_PROMPT_LABEL = 
"scalarValueInlinePromptLabel";
-
-    /**
-     * as per {@link #scalarIfRegularInlinePromptForm}.
-     */
-    public static final String ID_SCALAR_IF_REGULAR_INLINE_PROMPT_FORM = 
"scalarIfRegularInlinePromptForm";
-
-
-    private static final String ID_EDIT_PROPERTY = "editProperty";
-    private static final String ID_FEEDBACK = "feedback";
     private static final String ID_ASSOCIATED_ACTION_LINKS_BELOW = 
"associatedActionLinksBelow";
     private static final String ID_ASSOCIATED_ACTION_LINKS_RIGHT = 
"associatedActionLinksRight";
 
-    public static class InlinePromptConfig {
-        private final boolean supported;
-        private final Component componentToHideIfAny;
+    private static final String ID_EDIT_PROPERTY = "editProperty";
+    private static final String ID_FEEDBACK = "feedback";
 
-        public static InlinePromptConfig supported() {
-            return new InlinePromptConfig(true, null);
-        }
+    public enum CompactType {
+        INPUT_CHECKBOX,
+        SPAN
+    }
 
-        public static InlinePromptConfig notSupported() {
-            return new InlinePromptConfig(false, null);
-        }
+    public enum Rendering {
+        /**
+         * Does not show labels, eg for use in tables
+         */
+        COMPACT {
+            @Override
+            public String getLabelCaption(final LabeledWebMarkupContainer 
labeledContainer) {
+                return "";
+            }
 
-        public static InlinePromptConfig supportedAndHide(final Component 
componentToHideIfAny) {
-            return new InlinePromptConfig(true, componentToHideIfAny);
-        }
+            @Override
+            public void buildGui(final ScalarPanelAbstract panel) {
+                panel.getComponentForRegular().setVisible(false);
+            }
 
-        private InlinePromptConfig(final boolean supported, final Component 
componentToHideIfAny) {
-            this.supported = supported;
-            this.componentToHideIfAny = componentToHideIfAny;
-        }
+            @Override
+            public Where getWhere() {
+                return Where.PARENTED_TABLES;
+            }
+        },
+        /**
+         * Does show labels, eg for use in forms.
+         */
+        REGULAR {
+            @Override
+            public String getLabelCaption(final LabeledWebMarkupContainer 
labeledContainer) {
+                return labeledContainer.getLabel().getObject();
+            }
 
-        boolean isSupported() {
-            return supported;
-        }
+            @Override
+            public void buildGui(final ScalarPanelAbstract panel) {
+                panel.getLabelForCompact().setVisible(false);
+            }
 
-        Component getComponentToHideIfAny() {
-            return componentToHideIfAny;
-        }
-    }
+            @Override
+            public Where getWhere() {
+                return Where.OBJECT_FORMS;
+            }
+        };
 
-    // ///////////////////////////////////////////////////////////////////
+        public abstract String getLabelCaption(LabeledWebMarkupContainer 
labeledContainer);
 
-    protected final ScalarModel scalarModel;
+        public abstract void buildGui(ScalarPanelAbstract panel);
 
-    private Component scalarIfCompact;
-    private MarkupContainer scalarIfRegular;
+        public abstract Where getWhere();
 
-    private WebMarkupContainer scalarTypeContainer;
+        private static Rendering renderingFor(RenderingHint renderingHint) {
+            return renderingHint.isInTable()? Rendering.COMPACT: 
Rendering.REGULAR;
+        }
+    }
 
-    /**
-     * Populated
-     * Used by most subclasses ({@link ScalarPanelAbstract}, {@link 
ReferencePanel}, {@link ValueChoicesSelect2Panel}) but not all ({@link 
IsisBlobOrClobPanelAbstract}, {@link BooleanPanel})
-     */
-    private WebMarkupContainer scalarIfRegularInlinePromptForm;
+    protected Component componentIfCompact;
+    private Component componentIfRegular;
+    protected final ScalarModel scalarModel;
 
-    WebMarkupContainer inlinePromptLink;
 
     public ScalarPanelAbstract(final String id, final ScalarModel scalarModel) 
{
         super(id, scalarModel);
         this.scalarModel = scalarModel;
     }
 
+    protected Fragment getCompactFragment(CompactType type) {
+        Fragment compactFragment;
+        switch (type) {
+        case INPUT_CHECKBOX:
+            compactFragment = new Fragment("scalarIfCompact", 
"compactAsInputCheckbox", ScalarPanelAbstract.this);
+            break;
+        case SPAN:
+        default:
+            compactFragment = new Fragment("scalarIfCompact", "compactAsSpan", 
ScalarPanelAbstract.this);
+            break;
+        }
+        return compactFragment;
+    }
 
-    // ///////////////////////////////////////////////////////////////////
-
-
-    @Override
-    protected void onInitialize() {
-        super.onInitialize();
-
-        scalarTypeContainer = new WebMarkupContainer(ID_SCALAR_TYPE_CONTAINER);
-        scalarTypeContainer.setOutputMarkupId(true);
-        scalarTypeContainer.add(new 
CssClassAppender(Model.of(getScalarPanelType())));
-        addOrReplace(scalarTypeContainer);
-
+    protected Rendering getRendering() {
+        return Rendering.renderingFor(getModel().getRenderingHint());
     }
 
-    /**
-     * Mandatory hook; simply determines the CSS that is added to the 
outermost 'scalarTypeContainer' div.
-     */
-    protected abstract String getScalarPanelType();
+    protected Component getLabelForCompact() {
+        return componentIfCompact;
+    }
 
-    /**
-     * Mandatory hook for implementations to indicate whether it supports the 
{@link PromptStyle#INLINE} inline prompt,
-     * and if so, how.
-     *
-     * <p>
-     *     For those that do, both {@link #createInlinePromptForm()} and
-     *     {@link #createInlinePromptLink()} must return non-null values (and 
their corresponding markup
-     *     must define the corresponding elements).
-     * </p>
-     *
-     * <p>
-     *     Implementations that support inline prompts are: ({@link 
ScalarPanelAbstract}, {@link ReferencePanel} and
-     *     {@link ValueChoicesSelect2Panel}; those that don't are {@link 
IsisBlobOrClobPanelAbstract} and {@link BooleanPanel}.
-     * </p>
-     */
-    protected abstract InlinePromptConfig getInlinePromptConfig();
+    public Component getComponentForRegular() {
+        return componentIfRegular;
+    }
 
     @Override
     protected void onBeforeRender() {
@@ -207,7 +202,6 @@ public abstract class ScalarPanelAbstract extends 
PanelAbstract<ScalarModel> imp
         super.onBeforeRender();
     }
 
-
     /**
      * hook for highly dynamic components, eg conditional choices.
      *
@@ -229,344 +223,85 @@ public abstract class ScalarPanelAbstract extends 
PanelAbstract<ScalarModel> imp
      */
     private void buildGui() {
 
-        this.scalarIfCompact = createComponentForCompact();
-        this.scalarIfRegular = createComponentForRegular();
-        scalarIfRegular.setOutputMarkupId(true);
-
-        scalarTypeContainer.addOrReplace(scalarIfCompact, scalarIfRegular);
-
-        final InlinePromptConfig inlinePromptConfig = getInlinePromptConfig();
-        if(inlinePromptConfig.isSupported()) {
-            this.scalarIfRegularInlinePromptForm = createInlinePromptForm();
-            scalarTypeContainer.addOrReplace(scalarIfRegularInlinePromptForm);
-            inlinePromptLink = createInlinePromptLink();
-            scalarIfRegular.add(inlinePromptLink);
-
-            // even if this particular scalarModel (property) is not 
configured for inline edits, it's possible that
-            // one of the associated actions is.  Thus we set the prompt 
context
-            scalarModel.setInlinePromptContext(
-                    new InlinePromptContext(
-                            getComponentForRegular(),
-                            scalarIfRegularInlinePromptForm, 
scalarTypeContainer));
-
-            // and we configure the prompt link if _this_ property is 
configured for inline edits...
-            final PromptStyle promptStyle = this.scalarModel.getPromptStyle();
-            if(promptStyle == PromptStyle.INLINE) {
-                configureInlinePromptLinkCallback(inlinePromptLink);
-            }
-
-            Component componentToHideIfAny = 
inlinePromptConfig.getComponentToHideIfAny();
-            if (componentToHideIfAny != null || promptStyle == 
PromptStyle.DIALOG) {
-                if (scalarModel.canEnterEditMode() && 
scalarModel.getPromptStyle() == PromptStyle.INLINE) {
-                    componentToHideIfAny.setVisibilityAllowed(false);
-                } else {
-                    inlinePromptLink.setVisibilityAllowed(false);
-                }
-            }
-        }
-        if(scalarModel.getPromptStyle() != PromptStyle.INLINE) {
-            getScalarValueComponent().add(new AttributeAppender("tabindex", 
"-1"));
-        }
-
-        final List<LinkAndLabel> actionLinks =
-                LinkAndLabelUtil.asActionLinksForAssociation(this.scalarModel, 
getDeploymentCategory());
-        addPositioningCssTo(scalarIfRegular, actionLinks);
-        addActionLinksBelowAndRight(scalarIfRegular, actionLinks);
-
-        addEditPropertyTo(scalarIfRegular);
-        addFeedbackOnlyTo(scalarIfRegular, getScalarValueComponent());
-
+        // REVIEW: this is nasty, both write to the same entityLink field
+        // even though only one is used
+        componentIfCompact = addComponentForCompact();
+        componentIfRegular = addComponentForRegular();
 
         getRendering().buildGui(this);
-        addCssFromMetaModel();
-
-        notifyOnChange(this);
-        addFormComponentBehaviourToUpdateSubscribers();
-
-    }
-
-    /**
-     * Optional hook.
-     */
-    protected void onBeforeRenderWhenViewMode() {
-    }
-
-    /**
-     * Optional hook.
-     */
-    protected void onBeforeRenderWhenDisabled(final String disableReason) {
-    }
-
-    /**
-     * Optional hook.
-     */
-    protected void onBeforeRenderWhenEnabled() {
-    }
-
+        addCssForMetaModel();
 
-    private void addCssFromMetaModel() {
-        final String cssForMetaModel = getModel().getLongName();
-        if (cssForMetaModel != null) {
-            add(new AttributeAppender("class", Model.of(cssForMetaModel), " 
"));
-        }
-
-        ScalarModel model = getModel();
-        final CssClassFacet facet = model.getFacet(CssClassFacet.class);
-        if(facet != null) {
-            final ObjectAdapter parentAdapter = 
model.getParentObjectAdapterMemento().getObjectAdapter(
-                    AdapterManager.ConcurrencyChecking.NO_CHECK,
-                    getPersistenceSession(), getSpecificationLoader());
-            final String cssClass = facet.cssClass(parentAdapter);
-            CssClassAppender.appendCssClassTo(this, cssClass);
+        if(!subscribers.isEmpty()) {
+            addFormComponentBehavior(new ScalarUpdatingBehavior());
         }
     }
 
-
-    // //////////////////////////////////////
-
-
-    static class ScalarUpdatingBehavior extends 
AjaxFormComponentUpdatingBehavior {
+    protected class ScalarUpdatingBehavior extends 
AjaxFormComponentUpdatingBehavior {
         private static final long serialVersionUID = 1L;
 
-        private final ScalarPanelAbstract scalarPanel;
-
-        private ScalarUpdatingBehavior(final ScalarPanelAbstract scalarPanel) {
+        private ScalarUpdatingBehavior() {
             super("change");
-            this.scalarPanel = scalarPanel;
         }
 
         @Override
         protected void onUpdate(AjaxRequestTarget target) {
-            for (ScalarModelSubscriber subscriber : scalarPanel.subscribers) {
-                subscriber.onUpdate(target, scalarPanel);
+            for (ScalarModelSubscriber subscriber : subscribers) {
+                subscriber.onUpdate(target, ScalarPanelAbstract.this);
             }
+
+            // hmmm... this doesn't seem to be picked up...
+            target.appendJavaScript(
+                    
String.format("Wicket.Event.publish(Isis.Topic.FOCUS_FIRST_ACTION_PARAMETER, 
'%s')", getMarkupId()));
         }
 
         @Override
         protected void onError(AjaxRequestTarget target, RuntimeException e) {
             super.onError(target, e);
-            for (ScalarModelSubscriber subscriber : scalarPanel.subscribers) {
-                subscriber.onError(target, scalarPanel);
+            for (ScalarModelSubscriber subscriber : subscribers) {
+                subscriber.onError(target, ScalarPanelAbstract.this);
             }
         }
     }
 
-    private final List<ScalarModelSubscriber> subscribers = 
Lists.newArrayList();
-
-    public void notifyOnChange(final ScalarModelSubscriber subscriber) {
-        subscribers.add(subscriber);
-    }
+    /**
+     * Mandatory hook.
+     */
+    protected abstract void addFormComponentBehavior(Behavior behavior);
 
-    private void addFormComponentBehaviourToUpdateSubscribers() {
-        Component scalarValueComponent = getScalarValueComponent();
-        if(scalarValueComponent == null) {
-            return;
-        }
-        for (Behavior b : 
scalarValueComponent.getBehaviors(ScalarUpdatingBehavior.class)) {
-            scalarValueComponent.remove(b);
+    private void addCssForMetaModel() {
+        final String cssForMetaModel = getModel().getLongName();
+        if (cssForMetaModel != null) {
+            add(new AttributeAppender("class", Model.of(cssForMetaModel), " 
"));
         }
-        scalarValueComponent.add(new ScalarUpdatingBehavior(this));
-    }
-
-    // //////////////////////////////////////
-
-    @Override
-    public void onUpdate(
-            final AjaxRequestTarget target, final ScalarPanelAbstract 
scalarPanel) {
-
-        target.appendJavaScript(
-                
String.format("Wicket.Event.publish(Isis.Topic.FOCUS_FIRST_PARAMETER, '%s')", 
getMarkupId()));
-    }
-
-
-    @Override
-    public void onError(
-            final AjaxRequestTarget target, final ScalarPanelAbstract 
scalarPanel) {
-
-    }
 
-
-    // ///////////////////////////////////////////////////////////////////
-
-
-    public enum Rendering {
-        /**
-         * Does not show labels, eg for use in tables
-         */
-        COMPACT {
-            @Override
-            public String getLabelCaption(final LabeledWebMarkupContainer 
labeledContainer) {
-                return "";
-            }
-
-            @Override
-            public void buildGui(final ScalarPanelAbstract panel) {
-                panel.getComponentForRegular().setVisible(false);
-            }
-
-            @Override
-            public Where getWhere() {
-                return Where.PARENTED_TABLES;
-            }
-        },
-        /**
-         * Does show labels, eg for use in forms.
-         */
-        REGULAR {
-            @Override
-            public String getLabelCaption(final LabeledWebMarkupContainer 
labeledContainer) {
-                return labeledContainer.getLabel().getObject();
-            }
-
-            @Override
-            public void buildGui(final ScalarPanelAbstract panel) {
-                panel.scalarIfCompact.setVisible(false);
-            }
-
-            @Override
-            public Where getWhere() {
-                return Where.OBJECT_FORMS;
-            }
-        };
-
-        public abstract String getLabelCaption(LabeledWebMarkupContainer 
labeledContainer);
-
-        public abstract void buildGui(ScalarPanelAbstract panel);
-
-        public abstract Where getWhere();
-
-        private static Rendering renderingFor(EntityModel.RenderingHint 
renderingHint) {
-            return renderingHint.isInTable()? Rendering.COMPACT: 
Rendering.REGULAR;
+        ScalarModel model = getModel();
+        final CssClassFacet facet = model.getFacet(CssClassFacet.class);
+        if(facet != null) {
+            final ObjectAdapter parentAdapter = 
model.getParentObjectAdapterMemento().getObjectAdapter(ConcurrencyChecking.NO_CHECK,
+                    getPersistenceSession(), getSpecificationLoader());
+            final String cssClass = facet.cssClass(parentAdapter);
+            CssClassAppender.appendCssClassTo(this, cssClass);
         }
     }
 
-    protected Rendering getRendering() {
-        return Rendering.renderingFor(scalarModel.getRenderingHint());
-    }
-
-
-    // ///////////////////////////////////////////////////////////////////
-
-    protected Component getComponentForRegular() {
-        return scalarIfRegular;
-    }
-
     /**
      * Mandatory hook method to build the component to render the model when in
      * {@link Rendering#REGULAR regular} format.
-     *
-     * <p>
-     *     Is added to {@link #scalarTypeContainer}.
-     * </p>
-     */
-    protected abstract MarkupContainer createComponentForRegular();
-
-    /**
-     * Mandatory hook method to build the component to render the model when in
-     * {@link Rendering#COMPACT compact} format.
-     *
-     * <p>
-     *     Is added to {@link #scalarTypeContainer}.
-     * </p>
-     */
-    protected abstract Component createComponentForCompact();
-
-
-    /**
-     * Returns a container holding an empty form.  This can be switched out 
using {@link #switchFormForInlinePrompt(AjaxRequestTarget)}.
-     */
-    private WebMarkupContainer createInlinePromptForm() {
-
-        // (placeholder initially, create dynamically when needed - otherwise 
infinite loop because form references regular)
-
-        WebMarkupContainer scalarIfRegularInlinePromptForm = new 
WebMarkupContainer(
-                ID_SCALAR_IF_REGULAR_INLINE_PROMPT_FORM);
-        scalarIfRegularInlinePromptForm.setOutputMarkupId(true);
-        scalarIfRegularInlinePromptForm.setVisible(false);
-
-        return scalarIfRegularInlinePromptForm;
-    }
-
-    private WebMarkupContainer createInlinePromptLink() {
-        final IModel<?> inlineLinkModel = obtainPromptInlineLinkModel();
-        if(inlineLinkModel == null) {
-            throw new IllegalStateException(this.getClass().getName() + ": 
obtainPromptInlineLinkModel() returning null is not compatible with 
supportsInlinePrompt() returning true ");
-        }
-
-        final WebMarkupContainer inlinePromptLink = new 
WebMarkupContainer(ID_SCALAR_VALUE_INLINE_PROMPT_LINK);
-        inlinePromptLink.setOutputMarkupId(true);
-
-        final Label editInlineLinkLabel = new 
Label(ID_SCALAR_VALUE_INLINE_PROMPT_LABEL, inlineLinkModel);
-        inlinePromptLink.add(editInlineLinkLabel);
-
-        return inlinePromptLink;
-    }
-
-    // ///////////////////////////////////////////////////////////////////
-
-    /**
-     * Components returning true for {@link #getInlinePromptConfig()} are 
required to override and return a non-null value.
      */
-    protected IModel<?> obtainPromptInlineLinkModel() {
-        return null;
-    }
-
-
-    private void configureInlinePromptLinkCallback(final WebMarkupContainer 
inlinePromptLink) {
-
-        inlinePromptLink.add(new AjaxEventBehavior("click") {
-            @Override
-            protected void onEvent(final AjaxRequestTarget target) {
-
-                scalarModel.toEditMode();
-
-                // dynamically update the edit form.
-                final PropertyEditFormExecutor formExecutor =
-                        new PropertyEditFormExecutor(ScalarPanelAbstract.this, 
scalarModel);
-                scalarModel.setFormExecutor(formExecutor);
-
-                switchFormForInlinePrompt(target);
-
-                getComponentForRegular().setVisible(false);
-                scalarIfRegularInlinePromptForm.setVisible(true);
+    protected abstract MarkupContainer addComponentForRegular();
 
-                target.add(scalarTypeContainer);
-            }
-
-            @Override
-            public boolean isEnabled(final Component component) {
-                return true;
-            }
-        });
-    }
-
-    private void switchFormForInlinePrompt(final AjaxRequestTarget target) {
-        scalarIfRegularInlinePromptForm = (PropertyEditFormPanel) 
getComponentFactoryRegistry().addOrReplaceComponent(
-                scalarTypeContainer, ID_SCALAR_IF_REGULAR_INLINE_PROMPT_FORM, 
ComponentType.PROPERTY_EDIT_FORM, scalarModel);
-
-        onSwitchFormForInlinePrompt(scalarIfRegularInlinePromptForm, target);
-    }
-
-    /**
-     * Optional hook.
-     */
-    protected void onSwitchFormForInlinePrompt(
-            final WebMarkupContainer inlinePromptForm,
-            final AjaxRequestTarget target) {
+    protected abstract Component addComponentForCompact();
 
+    protected void addFeedbackOnlyTo(final MarkupContainer markupContainer, 
final Component component) {
+        markupContainer.addOrReplace(new NotificationPanel(ID_FEEDBACK, 
component, new ComponentFeedbackMessageFilter(component)));
     }
 
-
-    // ///////////////////////////////////////////////////////////////////
-
-    protected void addEditPropertyTo(
-            final MarkupContainer scalarIfRegularFormGroup) {
-
-        if(scalarModel.canEnterEditMode() && scalarModel.getPromptStyle() == 
PromptStyle.DIALOG) {
-
+    protected void addEditPropertyTo(final MarkupContainer markupContainer) {
+        final String disableReasonIfAny = 
scalarModel.disable(getRendering().getWhere());
+        if (disableReasonIfAny == null && scalarModel.isViewMode()) {
             final WebMarkupContainer editProperty = new 
WebMarkupContainer(ID_EDIT_PROPERTY);
+
             editProperty.setOutputMarkupId(true);
-            scalarIfRegularFormGroup.addOrReplace(editProperty);
 
             editProperty.add(new AjaxEventBehavior("click") {
                 protected void onEvent(AjaxRequestTarget target) {
@@ -575,12 +310,11 @@ public abstract class ScalarPanelAbstract extends 
PanelAbstract<ScalarModel> imp
                             
.getFrom(ScalarPanelAbstract.this).getActionPrompt();
 
                     PropertyEditPromptHeaderPanel titlePanel = new 
PropertyEditPromptHeaderPanel(prompt.getTitleId(),
-                            ScalarPanelAbstract.this.scalarModel);
+                            scalarModel);
 
                     final PropertyEditPanel propertyEditPanel =
                             (PropertyEditPanel) 
getComponentFactoryRegistry().createComponent(
-                                    ComponentType.PROPERTY_EDIT_PROMPT, 
prompt.getContentId(),
-                                    ScalarPanelAbstract.this.scalarModel);
+                                    ComponentType.PROPERTY_EDIT_PROMPT, 
prompt.getContentId(), scalarModel);
 
                     propertyEditPanel.setShowHeader(false);
 
@@ -590,46 +324,52 @@ public abstract class ScalarPanelAbstract extends 
PanelAbstract<ScalarModel> imp
 
                 }
             });
+
+            markupContainer.addOrReplace(editProperty);
         } else {
-            Components.permanentlyHide(scalarIfRegularFormGroup, 
ID_EDIT_PROPERTY);
+            Components.permanentlyHide(markupContainer, ID_EDIT_PROPERTY);
         }
-
     }
 
     /**
-     * Mandatory hook, used to determine which component to attach feedback to.
-     * @return
+     * Optional hook.
      */
-    protected abstract Component getScalarValueComponent();
-
-
-    private void addFeedbackOnlyTo(final MarkupContainer markupContainer, 
final Component component) {
-        markupContainer.addOrReplace(new NotificationPanel(ID_FEEDBACK, 
component, new ComponentFeedbackMessageFilter(component)));
+    protected void onBeforeRenderWhenViewMode() {
     }
 
-    private void addActionLinksBelowAndRight(
-            final MarkupContainer labelIfRegular,
-            final List<LinkAndLabel> linkAndLabels) {
-        final List<LinkAndLabel> linksBelow = 
LinkAndLabel.positioned(linkAndLabels, ActionLayout.Position.BELOW);
-        AdditionalLinksPanel.addAdditionalLinks(labelIfRegular, 
ID_ASSOCIATED_ACTION_LINKS_BELOW, linksBelow, 
AdditionalLinksPanel.Style.INLINE_LIST);
+    /**
+     * Optional hook.
+     */
+    protected void onBeforeRenderWhenDisabled(final String disableReason) {
+    }
 
-        final List<LinkAndLabel> linksRight = 
LinkAndLabel.positioned(linkAndLabels, ActionLayout.Position.RIGHT);
-        AdditionalLinksPanel.addAdditionalLinks(labelIfRegular, 
ID_ASSOCIATED_ACTION_LINKS_RIGHT, linksRight, 
AdditionalLinksPanel.Style.DROPDOWN);
+    /**
+     * Optional hook.
+     */
+    protected void onBeforeRenderWhenEnabled() {
     }
 
     /**
-     * Applies the {@literal @}{@link LabelAtFacet} and also CSS based on
-     * whether any of the associated actions have {@literal @}{@link 
ActionLayout layout} positioned to
-     * the {@link ActionLayout.Position#RIGHT right}.
+     * Applies the {@literal @}{@link 
org.apache.isis.core.metamodel.facets.objectvalue.labelat.LabelAtFacet} and 
also CSS based on
+     * whether any of the associated actions have {@literal @}{@link 
org.apache.isis.applib.annotation.ActionLayout layout} positioned to
+     * the {@link 
org.apache.isis.applib.annotation.ActionLayout.Position#RIGHT right}.
      *
      * @param markupContainer The form group element
      * @param entityActionLinks
      */
-    private void addPositioningCssTo(final MarkupContainer markupContainer, 
final List<LinkAndLabel> entityActionLinks) {
+    protected void addPositioningCssTo(final MarkupContainer markupContainer, 
final List<LinkAndLabel> entityActionLinks) {
         CssClassAppender.appendCssClassTo(markupContainer, 
determinePropParamLayoutCss(getModel()));
         CssClassAppender.appendCssClassTo(markupContainer, 
determineActionLayoutPositioningCss(entityActionLinks));
     }
 
+    protected void addEntityActionLinksBelowAndRight(final MarkupContainer 
labelIfRegular, final List<LinkAndLabel> entityActions) {
+        final List<LinkAndLabel> entityActionsBelow = 
LinkAndLabel.positioned(entityActions, ActionLayout.Position.BELOW);
+        AdditionalLinksPanel.addAdditionalLinks(labelIfRegular, 
ID_ASSOCIATED_ACTION_LINKS_BELOW, entityActionsBelow, 
AdditionalLinksPanel.Style.INLINE_LIST);
+
+        final List<LinkAndLabel> entityActionsRight = 
LinkAndLabel.positioned(entityActions, ActionLayout.Position.RIGHT);
+        AdditionalLinksPanel.addAdditionalLinks(labelIfRegular, 
ID_ASSOCIATED_ACTION_LINKS_RIGHT, entityActionsRight, 
AdditionalLinksPanel.Style.DROPDOWN);
+    }
+
     private static String determinePropParamLayoutCss(ScalarModel model) {
         final LabelAtFacet facet = model.getFacet(LabelAtFacet.class);
         if (facet != null) {
@@ -661,8 +401,24 @@ public abstract class ScalarPanelAbstract extends 
PanelAbstract<ScalarModel> imp
         return false;
     }
 
+    // //////////////////////////////////////
 
-    // ///////////////////////////////////////////////////////////////////
+    private final List<ScalarModelSubscriber> subscribers = 
Lists.newArrayList();
+
+    public void notifyOnChange(final ScalarModelSubscriber subscriber) {
+        subscribers.add(subscriber);
+    }
+
+    // //////////////////////////////////////
+
+    /**
+     * Optional hook method
+     *
+     * @return true - indicates has been updated, so update dynamically via 
ajax
+     */
+    public boolean updateChoices(ObjectAdapter[] pendingArguments) {
+        return false;
+    }
 
     /**
      * Repaints this panel of just some of its children
@@ -674,4 +430,11 @@ public abstract class ScalarPanelAbstract extends 
PanelAbstract<ScalarModel> imp
     }
 
 
+    // ///////////////////////////////////////////////////////////////////
+
+    @Override
+    public AdapterManager getAdapterManager() {
+        return getPersistenceSession();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
new file mode 100644
index 0000000..abc083d
--- /dev/null
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelAbstract2.java
@@ -0,0 +1,677 @@
+/*
+ *  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.scalars;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.ajax.AjaxEventBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.behavior.AttributeAppender;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.feedback.ComponentFeedbackMessageFilter;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.LabeledWebMarkupContainer;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+
+import org.apache.isis.applib.annotation.ActionLayout;
+import org.apache.isis.applib.annotation.PromptStyle;
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.facets.members.cssclass.CssClassFacet;
+import org.apache.isis.core.metamodel.facets.objectvalue.labelat.LabelAtFacet;
+import org.apache.isis.viewer.wicket.model.links.LinkAndLabel;
+import org.apache.isis.viewer.wicket.model.models.ActionPrompt;
+import org.apache.isis.viewer.wicket.model.models.ActionPromptProvider;
+import org.apache.isis.viewer.wicket.model.models.EntityModel;
+import org.apache.isis.viewer.wicket.model.models.InlinePromptContext;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.ui.ComponentType;
+import 
org.apache.isis.viewer.wicket.ui.components.actionmenu.entityactions.AdditionalLinksPanel;
+import 
org.apache.isis.viewer.wicket.ui.components.actionmenu.entityactions.LinkAndLabelUtil;
+import 
org.apache.isis.viewer.wicket.ui.components.property.PropertyEditFormExecutor;
+import 
org.apache.isis.viewer.wicket.ui.components.property.PropertyEditFormPanel;
+import org.apache.isis.viewer.wicket.ui.components.property.PropertyEditPanel;
+import 
org.apache.isis.viewer.wicket.ui.components.property.PropertyEditPromptHeaderPanel;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisBlobOrClobPanelAbstract;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.primitive.BooleanPanel;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.reference.ReferencePanel;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.valuechoices.ValueChoicesSelect2Panel;
+import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+import org.apache.isis.viewer.wicket.ui.util.Components;
+import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
+
+import 
de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
+
+public abstract class ScalarPanelAbstract2 extends PanelAbstract<ScalarModel> 
implements ScalarModelSubscriber2 {
+
+    private static final long serialVersionUID = 1L;
+
+    protected static final String ID_SCALAR_TYPE_CONTAINER = 
"scalarTypeContainer";
+
+    protected static final String ID_SCALAR_IF_COMPACT = "scalarIfCompact";
+    protected static final String ID_SCALAR_IF_REGULAR = "scalarIfRegular";
+    protected static final String ID_SCALAR_NAME = "scalarName";
+    protected static final String ID_SCALAR_VALUE = "scalarValue";
+
+
+    /**
+     * as per {@link #inlinePromptLink}
+     */
+    protected static final String ID_SCALAR_VALUE_INLINE_PROMPT_LINK = 
"scalarValueInlinePromptLink";
+    protected static final String ID_SCALAR_VALUE_INLINE_PROMPT_LABEL = 
"scalarValueInlinePromptLabel";
+
+    /**
+     * as per {@link #scalarIfRegularInlinePromptForm}.
+     */
+    public static final String ID_SCALAR_IF_REGULAR_INLINE_PROMPT_FORM = 
"scalarIfRegularInlinePromptForm";
+
+
+    private static final String ID_EDIT_PROPERTY = "editProperty";
+    private static final String ID_FEEDBACK = "feedback";
+    private static final String ID_ASSOCIATED_ACTION_LINKS_BELOW = 
"associatedActionLinksBelow";
+    private static final String ID_ASSOCIATED_ACTION_LINKS_RIGHT = 
"associatedActionLinksRight";
+
+    public static class InlinePromptConfig {
+        private final boolean supported;
+        private final Component componentToHideIfAny;
+
+        public static InlinePromptConfig supported() {
+            return new InlinePromptConfig(true, null);
+        }
+
+        public static InlinePromptConfig notSupported() {
+            return new InlinePromptConfig(false, null);
+        }
+
+        public static InlinePromptConfig supportedAndHide(final Component 
componentToHideIfAny) {
+            return new InlinePromptConfig(true, componentToHideIfAny);
+        }
+
+        private InlinePromptConfig(final boolean supported, final Component 
componentToHideIfAny) {
+            this.supported = supported;
+            this.componentToHideIfAny = componentToHideIfAny;
+        }
+
+        boolean isSupported() {
+            return supported;
+        }
+
+        Component getComponentToHideIfAny() {
+            return componentToHideIfAny;
+        }
+    }
+
+    // ///////////////////////////////////////////////////////////////////
+
+    protected final ScalarModel scalarModel;
+
+    private Component scalarIfCompact;
+    private MarkupContainer scalarIfRegular;
+
+    private WebMarkupContainer scalarTypeContainer;
+
+    /**
+     * Populated
+     * Used by most subclasses ({@link ScalarPanelAbstract2}, {@link 
ReferencePanel}, {@link ValueChoicesSelect2Panel}) but not all ({@link 
IsisBlobOrClobPanelAbstract}, {@link BooleanPanel})
+     */
+    private WebMarkupContainer scalarIfRegularInlinePromptForm;
+
+    WebMarkupContainer inlinePromptLink;
+
+    public ScalarPanelAbstract2(final String id, final ScalarModel 
scalarModel) {
+        super(id, scalarModel);
+        this.scalarModel = scalarModel;
+    }
+
+
+    // ///////////////////////////////////////////////////////////////////
+
+
+    @Override
+    protected void onInitialize() {
+        super.onInitialize();
+
+        scalarTypeContainer = new WebMarkupContainer(ID_SCALAR_TYPE_CONTAINER);
+        scalarTypeContainer.setOutputMarkupId(true);
+        scalarTypeContainer.add(new 
CssClassAppender(Model.of(getScalarPanelType())));
+        addOrReplace(scalarTypeContainer);
+
+    }
+
+    /**
+     * Mandatory hook; simply determines the CSS that is added to the 
outermost 'scalarTypeContainer' div.
+     */
+    protected abstract String getScalarPanelType();
+
+    /**
+     * Mandatory hook for implementations to indicate whether it supports the 
{@link PromptStyle#INLINE} inline prompt,
+     * and if so, how.
+     *
+     * <p>
+     *     For those that do, both {@link #createInlinePromptForm()} and
+     *     {@link #createInlinePromptLink()} must return non-null values (and 
their corresponding markup
+     *     must define the corresponding elements).
+     * </p>
+     *
+     * <p>
+     *     Implementations that support inline prompts are: ({@link 
ScalarPanelAbstract2}, {@link ReferencePanel} and
+     *     {@link ValueChoicesSelect2Panel}; those that don't are {@link 
IsisBlobOrClobPanelAbstract} and {@link BooleanPanel}.
+     * </p>
+     */
+    protected abstract InlinePromptConfig getInlinePromptConfig();
+
+    @Override
+    protected void onBeforeRender() {
+
+        if ((!hasBeenRendered() || alwaysRebuildGui())) {
+            buildGui();
+        }
+
+        final ScalarModel scalarModel = getModel();
+        final String disableReasonIfAny = 
scalarModel.disable(getRendering().getWhere());
+
+        if (scalarModel.isViewMode()) {
+            onBeforeRenderWhenViewMode();
+        } else {
+            if (disableReasonIfAny != null) {
+                onBeforeRenderWhenDisabled(disableReasonIfAny);
+            } else {
+                onBeforeRenderWhenEnabled();
+            }
+        }
+        super.onBeforeRender();
+    }
+
+
+    /**
+     * hook for highly dynamic components, eg conditional choices.
+     *
+     * <p>
+     * Returning <tt>true</tt> means that the component is always rebuilt 
prior to
+     * every {@link #onBeforeRender() render}ing.
+     */
+    protected boolean alwaysRebuildGui() {
+        return false;
+    }
+
+    /**
+     * Builds GUI lazily prior to first render.
+     *
+     * <p>
+     * This design allows the panel to be configured first.
+     *
+     * @see #onBeforeRender()
+     */
+    private void buildGui() {
+
+        this.scalarIfCompact = createComponentForCompact();
+        this.scalarIfRegular = createComponentForRegular();
+        scalarIfRegular.setOutputMarkupId(true);
+
+        scalarTypeContainer.addOrReplace(scalarIfCompact, scalarIfRegular);
+
+        final InlinePromptConfig inlinePromptConfig = getInlinePromptConfig();
+        if(inlinePromptConfig.isSupported()) {
+            this.scalarIfRegularInlinePromptForm = createInlinePromptForm();
+            scalarTypeContainer.addOrReplace(scalarIfRegularInlinePromptForm);
+            inlinePromptLink = createInlinePromptLink();
+            scalarIfRegular.add(inlinePromptLink);
+
+            // even if this particular scalarModel (property) is not 
configured for inline edits, it's possible that
+            // one of the associated actions is.  Thus we set the prompt 
context
+            scalarModel.setInlinePromptContext(
+                    new InlinePromptContext(
+                            getComponentForRegular(),
+                            scalarIfRegularInlinePromptForm, 
scalarTypeContainer));
+
+            // and we configure the prompt link if _this_ property is 
configured for inline edits...
+            final PromptStyle promptStyle = this.scalarModel.getPromptStyle();
+            if(promptStyle == PromptStyle.INLINE) {
+                configureInlinePromptLinkCallback(inlinePromptLink);
+            }
+
+            Component componentToHideIfAny = 
inlinePromptConfig.getComponentToHideIfAny();
+            if (componentToHideIfAny != null || promptStyle == 
PromptStyle.DIALOG) {
+                if (scalarModel.canEnterEditMode() && 
scalarModel.getPromptStyle() == PromptStyle.INLINE) {
+                    componentToHideIfAny.setVisibilityAllowed(false);
+                } else {
+                    inlinePromptLink.setVisibilityAllowed(false);
+                }
+            }
+        }
+        if(scalarModel.getPromptStyle() != PromptStyle.INLINE) {
+            getScalarValueComponent().add(new AttributeAppender("tabindex", 
"-1"));
+        }
+
+        final List<LinkAndLabel> actionLinks =
+                LinkAndLabelUtil.asActionLinksForAssociation(this.scalarModel, 
getDeploymentCategory());
+        addPositioningCssTo(scalarIfRegular, actionLinks);
+        addActionLinksBelowAndRight(scalarIfRegular, actionLinks);
+
+        addEditPropertyTo(scalarIfRegular);
+        addFeedbackOnlyTo(scalarIfRegular, getScalarValueComponent());
+
+
+        getRendering().buildGui(this);
+        addCssFromMetaModel();
+
+        notifyOnChange(this);
+        addFormComponentBehaviourToUpdateSubscribers();
+
+    }
+
+    /**
+     * Optional hook.
+     */
+    protected void onBeforeRenderWhenViewMode() {
+    }
+
+    /**
+     * Optional hook.
+     */
+    protected void onBeforeRenderWhenDisabled(final String disableReason) {
+    }
+
+    /**
+     * Optional hook.
+     */
+    protected void onBeforeRenderWhenEnabled() {
+    }
+
+
+    private void addCssFromMetaModel() {
+        final String cssForMetaModel = getModel().getLongName();
+        if (cssForMetaModel != null) {
+            add(new AttributeAppender("class", Model.of(cssForMetaModel), " 
"));
+        }
+
+        ScalarModel model = getModel();
+        final CssClassFacet facet = model.getFacet(CssClassFacet.class);
+        if(facet != null) {
+            final ObjectAdapter parentAdapter = 
model.getParentObjectAdapterMemento().getObjectAdapter(
+                    AdapterManager.ConcurrencyChecking.NO_CHECK,
+                    getPersistenceSession(), getSpecificationLoader());
+            final String cssClass = facet.cssClass(parentAdapter);
+            CssClassAppender.appendCssClassTo(this, cssClass);
+        }
+    }
+
+
+    // //////////////////////////////////////
+
+
+    static class ScalarUpdatingBehavior extends 
AjaxFormComponentUpdatingBehavior {
+        private static final long serialVersionUID = 1L;
+
+        private final ScalarPanelAbstract2 scalarPanel;
+
+        private ScalarUpdatingBehavior(final ScalarPanelAbstract2 scalarPanel) 
{
+            super("change");
+            this.scalarPanel = scalarPanel;
+        }
+
+        @Override
+        protected void onUpdate(AjaxRequestTarget target) {
+            for (ScalarModelSubscriber2 subscriber : scalarPanel.subscribers) {
+                subscriber.onUpdate(target, scalarPanel);
+            }
+        }
+
+        @Override
+        protected void onError(AjaxRequestTarget target, RuntimeException e) {
+            super.onError(target, e);
+            for (ScalarModelSubscriber2 subscriber : scalarPanel.subscribers) {
+                subscriber.onError(target, scalarPanel);
+            }
+        }
+    }
+
+    private final List<ScalarModelSubscriber2> subscribers = 
Lists.newArrayList();
+
+    public void notifyOnChange(final ScalarModelSubscriber2 subscriber) {
+        subscribers.add(subscriber);
+    }
+
+    private void addFormComponentBehaviourToUpdateSubscribers() {
+        Component scalarValueComponent = getScalarValueComponent();
+        if(scalarValueComponent == null) {
+            return;
+        }
+        for (Behavior b : 
scalarValueComponent.getBehaviors(ScalarUpdatingBehavior.class)) {
+            scalarValueComponent.remove(b);
+        }
+        scalarValueComponent.add(new ScalarUpdatingBehavior(this));
+    }
+
+    // //////////////////////////////////////
+
+    @Override
+    public void onUpdate(
+            final AjaxRequestTarget target, final ScalarPanelAbstract2 
scalarPanel) {
+
+        target.appendJavaScript(
+                
String.format("Wicket.Event.publish(Isis.Topic.FOCUS_FIRST_PARAMETER, '%s')", 
getMarkupId()));
+    }
+
+
+    @Override
+    public void onError(
+            final AjaxRequestTarget target, final ScalarPanelAbstract2 
scalarPanel) {
+
+    }
+
+
+    // ///////////////////////////////////////////////////////////////////
+
+
+    public enum Rendering {
+        /**
+         * Does not show labels, eg for use in tables
+         */
+        COMPACT {
+            @Override
+            public String getLabelCaption(final LabeledWebMarkupContainer 
labeledContainer) {
+                return "";
+            }
+
+            @Override
+            public void buildGui(final ScalarPanelAbstract2 panel) {
+                panel.getComponentForRegular().setVisible(false);
+            }
+
+            @Override
+            public Where getWhere() {
+                return Where.PARENTED_TABLES;
+            }
+        },
+        /**
+         * Does show labels, eg for use in forms.
+         */
+        REGULAR {
+            @Override
+            public String getLabelCaption(final LabeledWebMarkupContainer 
labeledContainer) {
+                return labeledContainer.getLabel().getObject();
+            }
+
+            @Override
+            public void buildGui(final ScalarPanelAbstract2 panel) {
+                panel.scalarIfCompact.setVisible(false);
+            }
+
+            @Override
+            public Where getWhere() {
+                return Where.OBJECT_FORMS;
+            }
+        };
+
+        public abstract String getLabelCaption(LabeledWebMarkupContainer 
labeledContainer);
+
+        public abstract void buildGui(ScalarPanelAbstract2 panel);
+
+        public abstract Where getWhere();
+
+        private static Rendering renderingFor(EntityModel.RenderingHint 
renderingHint) {
+            return renderingHint.isInTable()? Rendering.COMPACT: 
Rendering.REGULAR;
+        }
+    }
+
+    protected Rendering getRendering() {
+        return Rendering.renderingFor(scalarModel.getRenderingHint());
+    }
+
+
+    // ///////////////////////////////////////////////////////////////////
+
+    protected Component getComponentForRegular() {
+        return scalarIfRegular;
+    }
+
+    /**
+     * Mandatory hook method to build the component to render the model when in
+     * {@link Rendering#REGULAR regular} format.
+     *
+     * <p>
+     *     Is added to {@link #scalarTypeContainer}.
+     * </p>
+     */
+    protected abstract MarkupContainer createComponentForRegular();
+
+    /**
+     * Mandatory hook method to build the component to render the model when in
+     * {@link Rendering#COMPACT compact} format.
+     *
+     * <p>
+     *     Is added to {@link #scalarTypeContainer}.
+     * </p>
+     */
+    protected abstract Component createComponentForCompact();
+
+
+    /**
+     * Returns a container holding an empty form.  This can be switched out 
using {@link #switchFormForInlinePrompt(AjaxRequestTarget)}.
+     */
+    private WebMarkupContainer createInlinePromptForm() {
+
+        // (placeholder initially, create dynamically when needed - otherwise 
infinite loop because form references regular)
+
+        WebMarkupContainer scalarIfRegularInlinePromptForm = new 
WebMarkupContainer(
+                ID_SCALAR_IF_REGULAR_INLINE_PROMPT_FORM);
+        scalarIfRegularInlinePromptForm.setOutputMarkupId(true);
+        scalarIfRegularInlinePromptForm.setVisible(false);
+
+        return scalarIfRegularInlinePromptForm;
+    }
+
+    private WebMarkupContainer createInlinePromptLink() {
+        final IModel<?> inlineLinkModel = obtainPromptInlineLinkModel();
+        if(inlineLinkModel == null) {
+            throw new IllegalStateException(this.getClass().getName() + ": 
obtainPromptInlineLinkModel() returning null is not compatible with 
supportsInlinePrompt() returning true ");
+        }
+
+        final WebMarkupContainer inlinePromptLink = new 
WebMarkupContainer(ID_SCALAR_VALUE_INLINE_PROMPT_LINK);
+        inlinePromptLink.setOutputMarkupId(true);
+
+        final Label editInlineLinkLabel = new 
Label(ID_SCALAR_VALUE_INLINE_PROMPT_LABEL, inlineLinkModel);
+        inlinePromptLink.add(editInlineLinkLabel);
+
+        return inlinePromptLink;
+    }
+
+    // ///////////////////////////////////////////////////////////////////
+
+    /**
+     * Components returning true for {@link #getInlinePromptConfig()} are 
required to override and return a non-null value.
+     */
+    protected IModel<?> obtainPromptInlineLinkModel() {
+        return null;
+    }
+
+
+    private void configureInlinePromptLinkCallback(final WebMarkupContainer 
inlinePromptLink) {
+
+        inlinePromptLink.add(new AjaxEventBehavior("click") {
+            @Override
+            protected void onEvent(final AjaxRequestTarget target) {
+
+                scalarModel.toEditMode();
+
+                // dynamically update the edit form.
+                final PropertyEditFormExecutor formExecutor =
+                        new 
PropertyEditFormExecutor(ScalarPanelAbstract2.this, scalarModel);
+                scalarModel.setFormExecutor(formExecutor);
+
+                switchFormForInlinePrompt(target);
+
+                getComponentForRegular().setVisible(false);
+                scalarIfRegularInlinePromptForm.setVisible(true);
+
+                target.add(scalarTypeContainer);
+            }
+
+            @Override
+            public boolean isEnabled(final Component component) {
+                return true;
+            }
+        });
+    }
+
+    private void switchFormForInlinePrompt(final AjaxRequestTarget target) {
+        scalarIfRegularInlinePromptForm = (PropertyEditFormPanel) 
getComponentFactoryRegistry().addOrReplaceComponent(
+                scalarTypeContainer, ID_SCALAR_IF_REGULAR_INLINE_PROMPT_FORM, 
ComponentType.PROPERTY_EDIT_FORM, scalarModel);
+
+        onSwitchFormForInlinePrompt(scalarIfRegularInlinePromptForm, target);
+    }
+
+    /**
+     * Optional hook.
+     */
+    protected void onSwitchFormForInlinePrompt(
+            final WebMarkupContainer inlinePromptForm,
+            final AjaxRequestTarget target) {
+
+    }
+
+
+    // ///////////////////////////////////////////////////////////////////
+
+    protected void addEditPropertyTo(
+            final MarkupContainer scalarIfRegularFormGroup) {
+
+        if(scalarModel.canEnterEditMode() && scalarModel.getPromptStyle() == 
PromptStyle.DIALOG) {
+
+            final WebMarkupContainer editProperty = new 
WebMarkupContainer(ID_EDIT_PROPERTY);
+            editProperty.setOutputMarkupId(true);
+            scalarIfRegularFormGroup.addOrReplace(editProperty);
+
+            editProperty.add(new AjaxEventBehavior("click") {
+                protected void onEvent(AjaxRequestTarget target) {
+
+                    final ActionPrompt prompt = ActionPromptProvider.Util
+                            
.getFrom(ScalarPanelAbstract2.this).getActionPrompt();
+
+                    PropertyEditPromptHeaderPanel titlePanel = new 
PropertyEditPromptHeaderPanel(prompt.getTitleId(),
+                            ScalarPanelAbstract2.this.scalarModel);
+
+                    final PropertyEditPanel propertyEditPanel =
+                            (PropertyEditPanel) 
getComponentFactoryRegistry().createComponent(
+                                    ComponentType.PROPERTY_EDIT_PROMPT, 
prompt.getContentId(),
+                                    ScalarPanelAbstract2.this.scalarModel);
+
+                    propertyEditPanel.setShowHeader(false);
+
+                    prompt.setTitle(titlePanel, target);
+                    prompt.setPanel(propertyEditPanel, target);
+                    prompt.showPrompt(target);
+
+                }
+            });
+        } else {
+            Components.permanentlyHide(scalarIfRegularFormGroup, 
ID_EDIT_PROPERTY);
+        }
+
+    }
+
+    /**
+     * Mandatory hook, used to determine which component to attach feedback to.
+     * @return
+     */
+    protected abstract Component getScalarValueComponent();
+
+
+    private void addFeedbackOnlyTo(final MarkupContainer markupContainer, 
final Component component) {
+        markupContainer.addOrReplace(new NotificationPanel(ID_FEEDBACK, 
component, new ComponentFeedbackMessageFilter(component)));
+    }
+
+    private void addActionLinksBelowAndRight(
+            final MarkupContainer labelIfRegular,
+            final List<LinkAndLabel> linkAndLabels) {
+        final List<LinkAndLabel> linksBelow = 
LinkAndLabel.positioned(linkAndLabels, ActionLayout.Position.BELOW);
+        AdditionalLinksPanel.addAdditionalLinks(labelIfRegular, 
ID_ASSOCIATED_ACTION_LINKS_BELOW, linksBelow, 
AdditionalLinksPanel.Style.INLINE_LIST);
+
+        final List<LinkAndLabel> linksRight = 
LinkAndLabel.positioned(linkAndLabels, ActionLayout.Position.RIGHT);
+        AdditionalLinksPanel.addAdditionalLinks(labelIfRegular, 
ID_ASSOCIATED_ACTION_LINKS_RIGHT, linksRight, 
AdditionalLinksPanel.Style.DROPDOWN);
+    }
+
+    /**
+     * Applies the {@literal @}{@link LabelAtFacet} and also CSS based on
+     * whether any of the associated actions have {@literal @}{@link 
ActionLayout layout} positioned to
+     * the {@link ActionLayout.Position#RIGHT right}.
+     *
+     * @param markupContainer The form group element
+     * @param entityActionLinks
+     */
+    private void addPositioningCssTo(final MarkupContainer markupContainer, 
final List<LinkAndLabel> entityActionLinks) {
+        CssClassAppender.appendCssClassTo(markupContainer, 
determinePropParamLayoutCss(getModel()));
+        CssClassAppender.appendCssClassTo(markupContainer, 
determineActionLayoutPositioningCss(entityActionLinks));
+    }
+
+    private static String determinePropParamLayoutCss(ScalarModel model) {
+        final LabelAtFacet facet = model.getFacet(LabelAtFacet.class);
+        if (facet != null) {
+            switch (facet.label()) {
+            case LEFT:
+                return "label-left";
+            case RIGHT:
+                return "label-right";
+            case NONE:
+                return "label-none";
+            case TOP:
+                return "label-top";
+            }
+        }
+        return "label-left";
+    }
+
+    private static String 
determineActionLayoutPositioningCss(List<LinkAndLabel> entityActionLinks) {
+        boolean actionsPositionedOnRight = 
hasActionsPositionedOn(entityActionLinks, ActionLayout.Position.RIGHT);
+        return actionsPositionedOnRight ? "actions-right" : null;
+    }
+
+    private static boolean hasActionsPositionedOn(final List<LinkAndLabel> 
entityActionLinks, final ActionLayout.Position position) {
+        for (LinkAndLabel entityActionLink : entityActionLinks) {
+            if(entityActionLink.getPosition() == position) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    // ///////////////////////////////////////////////////////////////////
+
+    /**
+     * Repaints this panel of just some of its children
+     *
+     * @param target The Ajax request handler
+     */
+    public void repaint(AjaxRequestTarget target) {
+        target.add(this);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java
index d9d41b6..c4022a5 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelSelect2Abstract.java
@@ -40,7 +40,7 @@ import 
org.apache.isis.viewer.wicket.ui.components.widgets.select2.Select2;
 import 
org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers.ObjectAdapterMementoProviderForChoices;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
 
-public abstract class ScalarPanelSelect2Abstract extends ScalarPanelAbstract {
+public abstract class ScalarPanelSelect2Abstract extends ScalarPanelAbstract2 {
 
     private static final long serialVersionUID = 1L;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
index e27a358..4f8b049 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/ScalarPanelTextFieldAbstract.java
@@ -63,7 +63,7 @@ import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
  * This implementation is for panels that use a textfield/text area.
  * </p>
  */
-public abstract class ScalarPanelTextFieldAbstract<T extends Serializable> 
extends ScalarPanelAbstract implements TextFieldValueModel.ScalarModelProvider {
+public abstract class ScalarPanelTextFieldAbstract<T extends Serializable> 
extends ScalarPanelAbstract2 implements TextFieldValueModel.ScalarModelProvider 
{
 
     private static final long serialVersionUID = 1L;
 

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java
index e141980..9c1c57f 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java
@@ -51,13 +51,13 @@ import org.apache.isis.applib.value.NamedWithMimeType;
 import org.apache.isis.core.commons.lang.CloseableExtensions;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import org.apache.isis.viewer.wicket.ui.components.widgets.bootstrap.FormGroup;
 import org.apache.isis.viewer.wicket.ui.util.Components;
 
 import 
de.agilecoders.wicket.extensions.markup.html.bootstrap.form.fileinput.BootstrapFileInputField;
 
-public abstract class IsisBlobOrClobPanelAbstract<T extends NamedWithMimeType> 
extends ScalarPanelAbstract {
+public abstract class IsisBlobOrClobPanelAbstract<T extends NamedWithMimeType> 
extends ScalarPanelAbstract2 {
 
 
     private static final long serialVersionUID = 1L;

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
index b32e0ee..2deb00b 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/primitive/BooleanPanel.java
@@ -31,7 +31,7 @@ import 
org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
 import org.apache.isis.core.metamodel.facets.objectvalue.labelat.LabelAtFacet;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import org.apache.isis.viewer.wicket.ui.components.widgets.bootstrap.FormGroup;
 import org.apache.isis.viewer.wicket.ui.util.CssClassAppender;
 
@@ -41,7 +41,7 @@ import 
de.agilecoders.wicket.extensions.markup.html.bootstrap.form.checkboxx.Che
 /**
  * Panel for rendering scalars of type {@link Boolean} or <tt>boolean</tt>.
  */
-public class BooleanPanel extends ScalarPanelAbstract {
+public class BooleanPanel extends ScalarPanelAbstract2 {
 
     private static final CheckBoxXConfig THREE_STATE_CONFIG = new 
CheckBoxXConfig()
         .withSize(CheckBoxXConfig.Sizes.xs)

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
index 639ddc7..e083670 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
@@ -50,7 +50,7 @@ import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.components.scalars.PanelWithChoices;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelSelect2Abstract;
 import org.apache.isis.viewer.wicket.ui.components.widgets.bootstrap.FormGroup;
 import 
org.apache.isis.viewer.wicket.ui.components.widgets.entitysimplelink.EntityLinkSimplePanel;
@@ -462,7 +462,7 @@ public class ReferencePanel extends 
ScalarPanelSelect2Abstract implements PanelW
 
     @Override
     public void onUpdate(
-            final AjaxRequestTarget target, final ScalarPanelAbstract 
scalarPanel) {
+            final AjaxRequestTarget target, final ScalarPanelAbstract2 
scalarPanel) {
 
         super.onUpdate(target, scalarPanel);
 

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/value/ValuePanel.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/value/ValuePanel.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/value/ValuePanel.java
index 2b3b225..df14483 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/value/ValuePanel.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/value/ValuePanel.java
@@ -19,15 +19,14 @@
 
 package org.apache.isis.viewer.wicket.ui.components.scalars.value;
 
-import org.apache.wicket.model.Model;
 import org.apache.isis.applib.annotation.Value;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelTextFieldParseableAbstract;
 
 /**
  * Panel for rendering any value types that do not have their own custom
- * {@link ScalarPanelAbstract panel} to render them.
+ * {@link ScalarPanelAbstract2 panel} to render them.
  * 
  * <p>
  * This is a fallback panel; values are expected to be {@link Parser parseable}

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/value/StandaloneValuePanel.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/value/StandaloneValuePanel.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/value/StandaloneValuePanel.java
index 80e12f1..3dcefb4 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/value/StandaloneValuePanel.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/value/StandaloneValuePanel.java
@@ -23,12 +23,12 @@ import org.apache.wicket.markup.html.basic.Label;
 
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.viewer.wicket.model.models.ValueModel;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
 
 /**
  * Panel for rendering any value types that do not have their own custom
- * {@link ScalarPanelAbstract panel} to render them.
+ * {@link ScalarPanelAbstract2 panel} to render them.
  */
 public class StandaloneValuePanel extends PanelAbstract<ValueModel> {
 

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java
index c0887f5..f724e94 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java
@@ -47,7 +47,7 @@ import 
org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistryAcc
 import 
org.apache.isis.viewer.wicket.ui.components.actionprompt.ActionPromptHeaderPanel;
 import org.apache.isis.viewer.wicket.ui.components.actions.ActionPanel;
 import 
org.apache.isis.viewer.wicket.ui.components.actions.ActionParametersFormExecutor;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
 import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistryAccessor;
 import org.apache.isis.viewer.wicket.ui.panels.PanelUtil;
@@ -231,7 +231,7 @@ public abstract class ActionLinkFactoryAbstract implements 
ActionLinkFactory {
             actionModel.setFormExecutor(new 
ActionParametersFormExecutor(scalarTypeContainer, actionModel));
             actionModel.setInlinePromptContext(inlinePromptContext);
             
getComponentFactoryRegistry().addOrReplaceComponent(scalarTypeContainer,
-                    
ScalarPanelAbstract.ID_SCALAR_IF_REGULAR_INLINE_PROMPT_FORM, 
ComponentType.PARAMETERS, actionModel);
+                    
ScalarPanelAbstract2.ID_SCALAR_IF_REGULAR_INLINE_PROMPT_FORM, 
ComponentType.PARAMETERS, actionModel);
 
             // TODO: probably needs to be like the switchXxx, and update the 
parent of the placeholder editform
             inlinePromptContext.getScalarIfRegular().setVisible(false);

http://git-wip-us.apache.org/repos/asf/isis/blob/b66fb6e6/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormPanelAbstract.java
----------------------------------------------------------------------
diff --git 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormPanelAbstract.java
 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormPanelAbstract.java
index 29741ab..ff967c1 100644
--- 
a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormPanelAbstract.java
+++ 
b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormPanelAbstract.java
@@ -47,8 +47,8 @@ import 
org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
 import org.apache.isis.viewer.wicket.model.models.ActionPrompt;
 import org.apache.isis.viewer.wicket.model.models.ActionPromptProvider;
 import org.apache.isis.viewer.wicket.model.models.FormExecutorContext;
-import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarModelSubscriber;
-import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarModelSubscriber2;
+import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract2;
 import 
org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.FormFeedbackPanel;
 import org.apache.isis.viewer.wicket.ui.errors.JGrowlBehaviour;
 import org.apache.isis.viewer.wicket.ui.errors.JGrowlUtil;
@@ -69,11 +69,11 @@ public abstract class PromptFormPanelAbstract<T extends 
IModel<?> & FormExecutor
     }
 
     public static abstract class FormAbstract<T extends IModel<ObjectAdapter> 
& FormExecutorContext> extends Form<ObjectAdapter>
-            implements ScalarModelSubscriber {
+            implements ScalarModelSubscriber2 {
 
         protected static final String ID_FEEDBACK = "feedback";
 
-        protected final List<ScalarPanelAbstract> paramPanels = 
Lists.newArrayList();
+        protected final List<ScalarPanelAbstract2> paramPanels = 
Lists.newArrayList();
         protected final Component parentPanel;
         private final WicketViewerSettings settings;
         private final T formExecutorContext;
@@ -256,7 +256,7 @@ public abstract class PromptFormPanelAbstract<T extends 
IModel<?> & FormExecutor
                 final Form<?> form);
 
         @Override
-        public void onError(AjaxRequestTarget target, ScalarPanelAbstract 
scalarPanel) {
+        public void onError(AjaxRequestTarget target, ScalarPanelAbstract2 
scalarPanel) {
             if(scalarPanel != null) {
                 // ensure that any feedback error associated with the 
providing component is shown.
                 target.add(scalarPanel);

Reply via email to