You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2018/07/18 06:00:55 UTC

[isis] 06/09: ISIS-898: fixes classcast exception with TreePanel.

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

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

commit daca965c2d18b721cc2a87d96918ad8fd14b44a8
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Jul 18 07:55:16 2018 +0200

    ISIS-898: fixes classcast exception with TreePanel.
    
    The FixtureResult class (view model returned from running fixture scripts through the UI) has a property of type java.lang.Object - this being the object wrapped by the FixtureResult, created by the fixture script.  The logic in TreePanelFactories to determine if this property's type implements TreeNode seems to be wrong - returns yes for Object being a subtype of TreeNode.  This then causes a TreePanel to attempt to be rendered which looks to downcast the object to TreeNode, and then [...]
---
 .../isis/commons/internal/base/_NullSafe.java      |  8 +++-
 .../viewer/wicket/model/models/ScalarModel.java    |  8 ++--
 .../ScalarModel_isScalarSubtypingAnyOf_Test.java   | 53 ++++++++++++++++++++++
 .../ui/components/tree/TreePanelFactories.java     |  7 +--
 4 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_NullSafe.java b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_NullSafe.java
index d495c0a..1aa317a 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_NullSafe.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_NullSafe.java
@@ -57,10 +57,14 @@ public final class _NullSafe {
         return array!=null ? Stream.of(array) : Stream.empty();
     }
 
+    public static <T> Stream<T> stream(final T nullable) {
+        return nullable != null ? Stream.of(nullable) : Stream.empty();
+    }
+
     /**
      * If {@code collection} is {@code null} returns the empty stream,
      * otherwise returns a stream of the collection's elements.
-     * @param collection
+     * @param coll
      * @return non-null stream object
      */
     public static <T> Stream<T> stream(final Collection<T> coll){
@@ -80,7 +84,7 @@ public final class _NullSafe {
     /**
      * If {@code iterator} is {@code null} returns the empty stream,
      * otherwise returns a stream of the iterator's elements.
-     * @param collection
+     * @param iterator
      * @return non-null stream object
      */
     public static <T> Stream<T> stream(final Iterator<T> iterator){
diff --git a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
index be2ce23..94ec782 100644
--- a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
+++ b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/ScalarModel.java
@@ -26,6 +26,8 @@ import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
+import com.google.common.collect.Lists;
+
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.commons.internal.base._NullSafe;
@@ -60,8 +62,6 @@ import org.apache.isis.viewer.wicket.model.mementos.ObjectAdapterMemento;
 import org.apache.isis.viewer.wicket.model.mementos.PropertyMemento;
 import org.apache.isis.viewer.wicket.model.mementos.SpecUtils;
 
-import com.google.common.collect.Lists;
-
 /**
  * Represents a scalar of an entity, either a {@link Kind#PROPERTY property} or
  * a {@link Kind#PARAMETER parameter}.
@@ -789,10 +789,10 @@ public class ScalarModel extends EntityModel implements LinksProvider, FormExecu
                 .anyMatch(fullName::equals);
     }
 
-    public boolean isScalarTypeSubtypingAnyOf(final Class<?>... requiredClass) {
+    public boolean isScalarTypeSubtypeOf(final Class<?> requiredClass) {
         final Class<?> scalarType = getTypeOfSpecification().getCorrespondingClass();
         return _NullSafe.stream(requiredClass)
-                .anyMatch(scalarType::isAssignableFrom);
+                .anyMatch(x -> x.isAssignableFrom(scalarType));
     }
 
     public String getObjectAsString() {
diff --git a/core/viewer-wicket-model/src/test/java/org/apache/isis/viewer/wicket/model/models/ScalarModel_isScalarSubtypingAnyOf_Test.java b/core/viewer-wicket-model/src/test/java/org/apache/isis/viewer/wicket/model/models/ScalarModel_isScalarSubtypingAnyOf_Test.java
new file mode 100644
index 0000000..6c0c866
--- /dev/null
+++ b/core/viewer-wicket-model/src/test/java/org/apache/isis/viewer/wicket/model/models/ScalarModel_isScalarSubtypingAnyOf_Test.java
@@ -0,0 +1,53 @@
+package org.apache.isis.viewer.wicket.model.models;
+
+import org.jmock.Expectations;
+import org.jmock.auto.Mock;
+import org.junit.Rule;
+
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class ScalarModel_isScalarSubtypingAnyOf_Test {
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(JUnitRuleMockery2.Mode.INTERFACES_AND_CLASSES);
+
+    @Mock
+    ObjectSpecification mockObjectSpecification;
+
+    public static class A {}
+    public static class B extends A {}
+    public static class C extends B {}
+
+    @org.junit.Test
+    public void when_super() {
+        assertThat(newScalarModelFor(A.class).isScalarTypeSubtypeOf(B.class), is(equalTo(false)));
+    }
+
+    @org.junit.Test
+    public void when_same() {
+        assertThat(newScalarModelFor(B.class).isScalarTypeSubtypeOf(B.class), is(equalTo(true)));
+    }
+
+    @org.junit.Test
+    public void when_sub() {
+        assertThat(newScalarModelFor(C.class).isScalarTypeSubtypeOf(B.class), is(equalTo(true)));
+    }
+
+    private ScalarModel newScalarModelFor(final Class<?> result) {
+        final ScalarModel scalarModel = new ScalarModel(null, null) {
+            @Override public ObjectSpecification getTypeOfSpecification() {
+                return mockObjectSpecification;
+            }
+        };
+        context.checking(new Expectations() {{
+            allowing(mockObjectSpecification).getCorrespondingClass();
+            will(returnValue(result));
+        }});
+        return scalarModel;
+    }
+}
\ No newline at end of file
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanelFactories.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanelFactories.java
index 9ea944e..d9936b4 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanelFactories.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/tree/TreePanelFactories.java
@@ -19,6 +19,9 @@
 
 package org.apache.isis.viewer.wicket.ui.components.tree;
 
+import org.apache.wicket.Component;
+import org.apache.wicket.model.IModel;
+
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.model.models.ValueModel;
@@ -26,8 +29,6 @@ import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupPanel;
-import org.apache.wicket.Component;
-import org.apache.wicket.model.IModel;
 
 /**
  * {@link ComponentFactory} for {@link MarkupPanel}.
@@ -51,7 +52,7 @@ public class TreePanelFactories {
 
             final ScalarModel scalarModel = (ScalarModel) model;
 
-            if(!scalarModel.isScalarTypeSubtypingAnyOf(org.apache.isis.applib.tree.TreeNode.class)) {
+            if(!scalarModel.isScalarTypeSubtypeOf(org.apache.isis.applib.tree.TreeNode.class)) {
                 return ApplicationAdvice.DOES_NOT_APPLY;
             }