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 <d...@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; }