You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2020/04/18 17:13:53 UTC

[isis] branch master updated (e7d29ba -> 7ac9bbc)

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git.


    from e7d29ba  ISIS-2340: fixes prism js script to run on every page update
     new f368395  ISIS-2340: simplify usage of the component factory request class
     new 7ac9bbc  ISIS-2340: add 'characteristics' attributes to the temporal facet

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../TemporalValueSemanticsProviderAbstract.java    | 10 ++-
 .../vaadin/ui/IsisModuleIncViewerVaadinUi.java     |  2 +
 .../ui/components/UiComponentHandlerVaa.java       |  3 +-
 .../ui/components/blob/BlobFieldFactory.java       |  7 +-
 .../vaadin/ui/components/clob/ClobField.java       |  2 +
 .../ui/components/clob/ClobFieldFactory.java       |  7 +-
 .../ui/components/markup/MarkupFieldFactory.java   |  8 +--
 .../date/DateField.java}                           | 24 ++++---
 .../temporal/date/TemporalFieldFactory.java        | 84 ++++++++++++++++++++++
 .../ui/components/text/TextFieldFactory.java       |  7 +-
 .../ui/vaa/components/AsciiDocFieldFactoryVaa.java |  7 +-
 .../common/model/binding/UiComponentFactory.java   | 82 +++++++++++++++++++++
 12 files changed, 208 insertions(+), 35 deletions(-)
 copy incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/{clob/ClobField.java => temporal/date/DateField.java} (71%)
 create mode 100644 incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/temporal/date/TemporalFieldFactory.java


[isis] 02/02: ISIS-2340: add 'characteristics' attributes to the temporal facet

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 7ac9bbcd4303127847cab3e97d818d80a1a4ae58
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat Apr 18 19:13:41 2020 +0200

    ISIS-2340: add 'characteristics' attributes to the temporal facet
---
 .../value/temporal/TemporalValueSemanticsProviderAbstract.java | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/temporal/TemporalValueSemanticsProviderAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/temporal/TemporalValueSemanticsProviderAbstract.java
index e63ceef..4778e18 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/temporal/TemporalValueSemanticsProviderAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/temporal/TemporalValueSemanticsProviderAbstract.java
@@ -44,7 +44,6 @@ import lombok.Getter;
 import lombok.NonNull;
 import lombok.Setter;
 import lombok.val;
-import lombok.extern.log4j.Log4j2;
 
 /**
  * Common base for {@link java.time.temporal.Temporal} types.
@@ -53,7 +52,7 @@ import lombok.extern.log4j.Log4j2;
  *
  * @param <T> implementing {@link java.time.temporal.Temporal} type
  */
-@Log4j2
+//@Log4j2
 public abstract class TemporalValueSemanticsProviderAbstract<T extends Temporal> 
 extends ValueSemanticsProviderAndFacetAbstract<T>
 implements TemporalValueFacet<T> {
@@ -99,6 +98,13 @@ implements TemporalValueFacet<T> {
         updateParsers();
     }
     
+    @Override
+    public void appendAttributesTo(Map<String, Object> attributeMap) {
+        super.appendAttributesTo(attributeMap);
+        attributeMap.put("temporalCharacteristic", getTemporalCharacteristic());
+        attributeMap.put("offsetCharacteristic", getOffsetCharacteristic());
+    }
+    
     protected void setEncodingFormatter(DateTimeFormatter encodingFormatter) {
         this.encodingFormatter = encodingFormatter;
     }


[isis] 01/02: ISIS-2340: simplify usage of the component factory request class

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit f36839551c10ce5271728e010c437159b7f7b918
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat Apr 18 19:09:52 2020 +0200

    ISIS-2340: simplify usage of the component factory request class
    
    also add factory stub for temporal types
---
 .../vaadin/ui/IsisModuleIncViewerVaadinUi.java     |  2 +
 .../ui/components/UiComponentHandlerVaa.java       |  3 +-
 .../ui/components/blob/BlobFieldFactory.java       |  7 +-
 .../vaadin/ui/components/clob/ClobField.java       |  2 +
 .../ui/components/clob/ClobFieldFactory.java       |  7 +-
 .../ui/components/markup/MarkupFieldFactory.java   |  8 +--
 .../date/DateField.java}                           | 24 ++++---
 .../temporal/date/TemporalFieldFactory.java        | 84 ++++++++++++++++++++++
 .../ui/components/text/TextFieldFactory.java       |  7 +-
 .../ui/vaa/components/AsciiDocFieldFactoryVaa.java |  7 +-
 .../common/model/binding/UiComponentFactory.java   | 82 +++++++++++++++++++++
 11 files changed, 200 insertions(+), 33 deletions(-)

diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/IsisModuleIncViewerVaadinUi.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/IsisModuleIncViewerVaadinUi.java
index 9facc50..e1f018e 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/IsisModuleIncViewerVaadinUi.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/IsisModuleIncViewerVaadinUi.java
@@ -31,6 +31,7 @@ import org.apache.isis.incubator.viewer.vaadin.ui.components.blob.BlobFieldFacto
 import org.apache.isis.incubator.viewer.vaadin.ui.components.clob.ClobFieldFactory;
 import org.apache.isis.incubator.viewer.vaadin.ui.components.markup.MarkupFieldFactory;
 import org.apache.isis.incubator.viewer.vaadin.ui.components.other.FallbackFieldFactory;
+import org.apache.isis.incubator.viewer.vaadin.ui.components.temporal.date.TemporalFieldFactory;
 import org.apache.isis.incubator.viewer.vaadin.ui.components.text.TextFieldFactory;
 import org.apache.isis.viewer.common.model.IsisModuleViewerCommon;
 
@@ -50,6 +51,7 @@ import org.apache.isis.viewer.common.model.IsisModuleViewerCommon;
         BlobFieldFactory.class,
         ClobFieldFactory.class,
         MarkupFieldFactory.class,
+        TemporalFieldFactory.class,
         TextFieldFactory.class,
         FallbackFieldFactory.class,
         
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/UiComponentHandlerVaa.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/UiComponentHandlerVaa.java
index cf6b237..44c36e1 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/UiComponentHandlerVaa.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/UiComponentHandlerVaa.java
@@ -22,6 +22,7 @@ import com.vaadin.flow.component.Component;
 
 import org.apache.isis.viewer.common.model.binding.UiComponentFactory;
 
-public interface UiComponentHandlerVaa extends UiComponentFactory.Handler<Component> {
+public interface UiComponentHandlerVaa 
+extends UiComponentFactory.Handler<Component> {
 
 }
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/blob/BlobFieldFactory.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/blob/BlobFieldFactory.java
index 2dd724d..24533cf 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/blob/BlobFieldFactory.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/blob/BlobFieldFactory.java
@@ -36,14 +36,13 @@ public class BlobFieldFactory implements UiComponentHandlerVaa {
 
     @Override
     public boolean isHandling(Request request) {
-        val spec = request.getObjectFeature().getSpecification();
-        return spec.getFacet(BlobValueFacet.class)!=null;
+        return request.hasFeatureFacet(BlobValueFacet.class);
     }
 
     @Override
     public Component handle(Request request) {
-        val uiField = new BlobField(request.getObjectFeature().getName());
-        uiField.setValue((Blob)request.getManagedObject().getPojo()); // pojo is nullable!
+        val uiField = new BlobField(request.getFeatureLabel());
+        uiField.setValue(request.getPojo(Blob.class).orElse(null));
         return uiField;
     }
     
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/clob/ClobField.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/clob/ClobField.java
index 6940757..d2d702f 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/clob/ClobField.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/clob/ClobField.java
@@ -24,6 +24,8 @@ import com.vaadin.flow.component.customfield.CustomField;
 
 import org.apache.isis.applib.value.Clob;
 
+// TODO just a stub yet
+//
 public class ClobField extends CustomField<Clob> {
 
     private static final long serialVersionUID = 1L;
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/clob/ClobFieldFactory.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/clob/ClobFieldFactory.java
index 8034fd1..5d11a68 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/clob/ClobFieldFactory.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/clob/ClobFieldFactory.java
@@ -36,14 +36,13 @@ public class ClobFieldFactory implements UiComponentHandlerVaa {
 
     @Override
     public boolean isHandling(Request request) {
-        val spec = request.getObjectFeature().getSpecification();
-        return spec.getFacet(ClobValueFacet.class)!=null;
+        return request.hasFeatureFacet(ClobValueFacet.class);
     }
 
     @Override
     public Component handle(Request request) {
-        val uiField = new ClobField(request.getObjectFeature().getName());
-        uiField.setValue((Clob)request.getManagedObject().getPojo()); // pojo is nullable!
+        val uiField = new ClobField(request.getFeatureLabel());
+        uiField.setValue(request.getPojo(Clob.class).orElse(null));
         return uiField;
     }
     
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/markup/MarkupFieldFactory.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/markup/MarkupFieldFactory.java
index a981b6f..378bd68 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/markup/MarkupFieldFactory.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/markup/MarkupFieldFactory.java
@@ -23,7 +23,6 @@ import com.vaadin.flow.component.Component;
 import org.springframework.core.annotation.Order;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.applib.value.Markup;
 import org.apache.isis.incubator.viewer.vaadin.ui.components.UiComponentHandlerVaa;
 import org.apache.isis.viewer.common.model.binding.UiComponentFactory.Request;
 
@@ -35,14 +34,13 @@ public class MarkupFieldFactory implements UiComponentHandlerVaa {
 
     @Override
     public boolean isHandling(Request request) {
-        val spec = request.getObjectFeature().getSpecification();
-        return spec.getFullIdentifier().contentEquals(org.apache.isis.applib.value.Markup.class.getName());
+        return request.isFeatureTypeEqualTo(org.apache.isis.applib.value.Markup.class);
     }
 
     @Override
     public Component handle(Request request) {
-        val uiField = new MarkupField(request.getObjectFeature().getName());
-        uiField.setValue((Markup)request.getManagedObject().getPojo()); // pojo is nullable!
+        val uiField = new MarkupField(request.getFeatureLabel());
+        uiField.setValue(request.getPojo(org.apache.isis.applib.value.Markup.class).orElse(null));
         return uiField;
     }
     
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/clob/ClobField.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/temporal/date/DateField.java
similarity index 71%
copy from incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/clob/ClobField.java
copy to incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/temporal/date/DateField.java
index 6940757..9ae2674 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/clob/ClobField.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/temporal/date/DateField.java
@@ -16,36 +16,38 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.incubator.viewer.vaadin.ui.components.clob;
+package org.apache.isis.incubator.viewer.vaadin.ui.components.temporal.date;
+
+import java.time.LocalDate;
 
 import javax.annotation.Nullable;
 
 import com.vaadin.flow.component.customfield.CustomField;
 
-import org.apache.isis.applib.value.Clob;
-
-public class ClobField extends CustomField<Clob> {
+// TODO just a stub yet
+//
+public class DateField extends CustomField<LocalDate> {
 
     private static final long serialVersionUID = 1L;
     
-    private Clob clob;
+    private LocalDate temporal;
 
-    public ClobField(String label) {
+    public DateField(String label) {
         super();
         setLabel(label);
         // ...
     }
     
     @Override
-    protected Clob generateModelValue() {
-        return clob;
+    protected LocalDate generateModelValue() {
+        return temporal;
     }
 
     @Override
-    protected void setPresentationValue(@Nullable Clob clob) {
-        this.clob = clob;
+    protected void setPresentationValue(@Nullable LocalDate temporal) {
+        this.temporal = temporal;
         
-        if(clob==null) {
+        if(temporal==null) {
             // ...
             return;
         }
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/temporal/date/TemporalFieldFactory.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/temporal/date/TemporalFieldFactory.java
new file mode 100644
index 0000000..9d7fe7e
--- /dev/null
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/temporal/date/TemporalFieldFactory.java
@@ -0,0 +1,84 @@
+/*
+ *  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.incubator.viewer.vaadin.ui.components.temporal.date;
+
+import java.time.LocalDate;
+import java.time.temporal.Temporal;
+import java.util.Optional;
+
+import com.vaadin.flow.component.Component;
+
+import org.springframework.core.annotation.Order;
+
+import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.core.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.metamodel.facets.value.temporal.TemporalValueFacet;
+import org.apache.isis.incubator.viewer.vaadin.ui.components.UiComponentHandlerVaa;
+import org.apache.isis.viewer.common.model.binding.UiComponentFactory.Request;
+
+import lombok.val;
+
+@org.springframework.stereotype.Component
+@Order(OrderPrecedence.MIDPOINT)
+public class TemporalFieldFactory implements UiComponentHandlerVaa {
+
+    @Override
+    public boolean isHandling(Request request) {
+        return request.hasFeatureFacet(TemporalValueFacet.class)
+                // TODO lift this restrictions, as we support more types
+                && request.isFeatureTypeEqualTo(LocalDate.class); 
+    }
+
+    @Override
+    public Component handle(Request request) {
+
+        val temporalFacet = request.getFeatureFacetElseFail(TemporalValueFacet.class);
+        val temporalCharacteristic = temporalFacet.getTemporalCharacteristic();
+        val offsetCharacteristic = temporalFacet.getOffsetCharacteristic();
+        val temporal = request.getPojo(Temporal.class);
+        
+        switch(temporalFacet.getTemporalCharacteristic()) {
+        case DATE_ONLY:{
+            val uiField = new DateField(request.getFeatureLabel());
+            uiField.setValue(toLocalDate(temporal).orElse(null));
+            return uiField;
+            }    
+        case TIME_ONLY:{
+            // TODO ... 
+            }    
+        case DATE_TIME:{
+            // TODO ...
+            }    
+        default:
+            throw _Exceptions.unmatchedCase(temporalFacet.getTemporalCharacteristic());
+        }
+        
+    }
+
+    private Optional<LocalDate> toLocalDate(Optional<Temporal> temporal) {
+        return temporal.map(this::toLocalDate);
+    }
+    
+    private LocalDate toLocalDate(Temporal temporal) {
+        return (temporal instanceof LocalDate)
+                ? (LocalDate) temporal
+                : null;
+    }
+    
+}
diff --git a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/text/TextFieldFactory.java b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/text/TextFieldFactory.java
index 1698a74..bd4cd82 100644
--- a/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/text/TextFieldFactory.java
+++ b/incubator/viewers/vaadin/ui/src/main/java/org/apache/isis/incubator/viewer/vaadin/ui/components/text/TextFieldFactory.java
@@ -32,14 +32,13 @@ public class TextFieldFactory implements UiComponentHandlerVaa {
 
     @Override
     public boolean isHandling(Request request) {
-        val spec = request.getObjectFeature().getSpecification();
-        return spec.getFacet(StringValueFacet.class)!=null;
+        return request.hasFeatureFacet(StringValueFacet.class);
     }
 
     @Override
     public Component handle(Request request) {
-        val uiField = new TextField(request.getObjectFeature().getName());
-        uiField.setValue(request.getManagedObject().titleString(null));
+        val uiField = new TextField(request.getFeatureLabel());
+        uiField.setValue(request.getPojo(String.class).orElse(null));
         return uiField;
     }
     
diff --git a/valuetypes/asciidoc/ui/vaadin/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/vaa/components/AsciiDocFieldFactoryVaa.java b/valuetypes/asciidoc/ui/vaadin/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/vaa/components/AsciiDocFieldFactoryVaa.java
index 51afc5c..ae130b4 100644
--- a/valuetypes/asciidoc/ui/vaadin/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/vaa/components/AsciiDocFieldFactoryVaa.java
+++ b/valuetypes/asciidoc/ui/vaadin/src/main/java/org/apache/isis/valuetypes/asciidoc/ui/vaa/components/AsciiDocFieldFactoryVaa.java
@@ -35,14 +35,13 @@ public class AsciiDocFieldFactoryVaa implements UiComponentHandlerVaa {
 
     @Override
     public boolean isHandling(Request request) {
-        val spec = request.getObjectFeature().getSpecification();
-        return spec.getFullIdentifier().contentEquals(AsciiDoc.class.getName());
+        return request.isFeatureTypeAssignableFrom(AsciiDoc.class);
     }
 
     @Override
     public Component handle(Request request) {
-        val uiField = new AsciiDocFieldVaa(request.getObjectFeature().getName());
-        uiField.setValue((AsciiDoc)request.getManagedObject().getPojo()); // pojo is nullable!
+        val uiField = new AsciiDocFieldVaa(request.getFeatureLabel());
+        uiField.setValue(request.getPojo(AsciiDoc.class).orElse(null));
         return uiField;
     }
     
diff --git a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/UiComponentFactory.java b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/UiComponentFactory.java
index bcbaf3b..344158e 100644
--- a/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/UiComponentFactory.java
+++ b/viewers/common/src/main/java/org/apache/isis/viewer/common/model/binding/UiComponentFactory.java
@@ -18,8 +18,15 @@
  */
 package org.apache.isis.viewer.common.model.binding;
 
+import java.util.Optional;
+
+import javax.annotation.Nullable;
+
 import org.apache.isis.core.commons.handler.ChainOfResponsibility;
+import org.apache.isis.core.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
 
 import lombok.NonNull;
@@ -36,11 +43,86 @@ public interface UiComponentFactory<T> {
         /** not null but the wrapped pojo is allowed to be null*/
         @NonNull private final ManagedObject managedObject; 
         @NonNull private final ObjectFeature objectFeature;
+        
+        // -- SHORTCUTS
+        
+        /**
+         * @return The feature's name. (With the UI to be used as form field title.) 
+         */
+        public String getFeatureLabel() {
+            return getObjectFeature().getName(); //TODO need to check what we actually use with wicket   
+        }
+        
+        /**
+         * @return The specification of the feature's underlying type. 
+         */
+        public ObjectSpecification getFeatureSpec() {
+            return getObjectFeature().getSpecification();    
+        }
+        
+        /**
+         * @return The feature's underlying type. 
+         */
+        public Class<?> getFeatureType() {
+            return getFeatureSpec().getCorrespondingClass();    
+        }
+        
+        public boolean isFeatureTypeEqualTo(@Nullable Class<?> type) {
+            return getFeatureType() == type;
+        }
+        
+        public boolean isFeatureTypeAssignableFrom(@Nullable Class<?> type) {
+            return type!=null
+                    ? getFeatureType().isAssignableFrom(type)
+                    : false;
+        }
+        
+        /**
+         * @param facetType
+         * @return Whether there exists a facet for this feature, that is of the 
+         * specified {@code facetType} (as per the type it reports from {@link Facet#facetType()}).
+         */
+        public <T extends Facet> boolean hasFeatureFacet(@Nullable Class<T> facetType) {
+            return facetType!=null
+                    ? getFeatureSpec().getFacet(facetType)!=null
+                    : false;
+        }
+
+        /**
+         * @param facetType
+         * @return Optionally the feature's facet of the specified {@code facetType} 
+         * (as per the type it reports from {@link Facet#facetType()}), based on existence.
+         */
+        public <T extends Facet> Optional<T> getFeatureFacet(@Nullable Class<T> facetType) {
+            return facetType!=null
+                    ? Optional.ofNullable(getFeatureSpec().getFacet(facetType))
+                    : Optional.empty();
+        }
+        
+        public <T extends Facet> T getFeatureFacetElseFail(@Nullable Class<T> facetType) {
+            return getFeatureFacet(facetType)
+                    .orElseThrow(()->_Exceptions
+                            .noSuchElement("Feature %s has no such facet %s",
+                                    getObjectFeature().getIdentifier(),
+                                    facetType.getName()));    
+        }
+        
+        public <T> Optional<T> getPojo(@Nullable Class<T> type) {
+            //TODO do a type check before the cast, so we can throw a more detailed exception
+            // that is, given type must be assignable from the actual pojo type 
+            return Optional.ofNullable(getManagedObject().getPojo())
+                    .map(type::cast);
+        }
+        
+        
     }
     
     
     // -- HANDLER
     
+    /**
+     * @param <T> - the Handler's Response type
+     */
     static interface Handler<T> 
     extends ChainOfResponsibility.Handler<UiComponentFactory.Request, T> {
     }