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 2018/04/12 22:41:54 UTC

[isis] branch master updated: ISIS-1599 adds meta-data validation for non-scalar action parameters

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


The following commit(s) were added to refs/heads/master by this push:
     new 9285542  ISIS-1599 adds meta-data validation for non-scalar action parameters
9285542 is described below

commit 9285542c9b5641a1dc9c12a1613e5e253235face
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Apr 13 00:41:49 2018 +0200

    ISIS-1599 adds meta-data validation for non-scalar action parameters
    
    Refines the CollectionSemantics in order to determine whether a
    collection type is supported as action parameter type.
---
 ...nChoicesForCollectionParameterFacetFactory.java | 21 ++++-
 .../collparam/semantics/CollectionSemantics.java   | 97 +++++++++++++---------
 .../core/metamodel/spec/ObjectSpecification.java   |  2 -
 .../spec/feature/ObjectActionParameter.java        |  7 +-
 .../domainobjects/CollectionSemantics.java         |  2 +-
 .../resources/DomainObjectResourceServerside.java  |  2 +-
 6 files changed, 84 insertions(+), 47 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionChoicesForCollectionParameterFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionChoicesForCollectionParameterFacetFactory.java
index 62727b2..6b95d00 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionChoicesForCollectionParameterFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionChoicesForCollectionParameterFacetFactory.java
@@ -25,6 +25,7 @@ import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.facetapi.FeatureType;
 import org.apache.isis.core.metamodel.facetapi.MetaModelValidatorRefiner;
 import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.collparam.semantics.CollectionSemanticsFacet;
 import org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
 import org.apache.isis.core.metamodel.facets.param.autocomplete.ActionParameterAutoCompleteFacet;
 import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacet;
@@ -106,6 +107,25 @@ public class ActionChoicesForCollectionParameterFacetFactory extends FacetFactor
                             final ObjectActionParameter parameter,
                             final int paramNum,
                             final ValidationFailures validationFailures) {
+                    	
+                    	
+                    	final CollectionSemanticsFacet collectionSemantics = 
+                    			parameter.getFacet(CollectionSemanticsFacet.class);
+                    	if (collectionSemantics != null) {
+                            // Violation if there are action parameter types that are assignable 
+                        	// from java.util.Collection but are not of  
+                            // exact type List, Set, SortedSet or Collection.
+                    		if(!collectionSemantics.value().isSupportedInterfaceForActionParameters()) {
+                    			validationFailures.add(
+                                        "Collection action parameter found that is not exaclty one "
+                                        + "of the following supported types: "
+                                        + "List, Set, SortedSet or Collection.  "
+                                        + "Class: %s action: %s parameter %d",
+                                        objectSpec.getFullIdentifier(), objectAction.getName(), paramNum);
+                        		return;	
+                    		}
+                        }
+                    	
                         final ActionParameterChoicesFacet choicesFacet =
                                 parameter.getFacet(ActionParameterChoicesFacet.class);
                         final ActionParameterAutoCompleteFacet autoCompleteFacet =
@@ -129,5 +149,4 @@ public class ActionChoicesForCollectionParameterFacetFactory extends FacetFactor
         metaModelValidator.add(validator);
     }
 
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collparam/semantics/CollectionSemantics.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collparam/semantics/CollectionSemantics.java
index 9cb5887..bd015b1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collparam/semantics/CollectionSemantics.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collparam/semantics/CollectionSemantics.java
@@ -18,56 +18,55 @@
  */
 package org.apache.isis.core.metamodel.facets.collparam.semantics;
 
-import java.lang.reflect.Array;
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Queue;
 import java.util.Set;
 import java.util.SortedSet;
-import java.util.TreeSet;
 
 public enum CollectionSemantics {
-    LIST {
-        @Override
-        public Object emptyCollectionOf(final Class<?> elementClass) {
-            return new ArrayList<>();
-        }
-    }, ARRAY {
-        @Override
-        public Object emptyCollectionOf(final Class<?> elementClass) {
-            return Array.newInstance(elementClass, 0);
-        }
-    }, SORTED_SET {
-        @Override
-        public Object emptyCollectionOf(final Class<?> elementClass) {
-            return new TreeSet<>();
-        }
-    }, SET {
-        @Override
-        public Object emptyCollectionOf(final Class<?> elementClass) {
-            return new HashSet<>();
-        }
-    }, OTHER {
-        @Override
-        public Object emptyCollectionOf(final Class<?> elementClass) {
-            return new ArrayList<>();
-        }
-    };
+	
+	ARRAY,
+	
+	COLLECTION_INTERFACE(true),
+	
+	LIST_IMPLEMENTATION, 
+	LIST_INTERFACE(true),
+	
+    SORTED_SET_IMPLEMENTATION, 
+    SORTED_SET_INTERFACE(true),
+    
+    SET_IMPLEMENTATION,
+    SET_INTERFACE(true),
+    
+    OTHER
+    ;
+	
+	final boolean isSupportedInterfaceForActionParameters;
+	
+	private CollectionSemantics() {
+		this(false);
+	}
+	
+    private CollectionSemantics(boolean isSupportedInterfaceForActionParameters) {
+		this.isSupportedInterfaceForActionParameters = isSupportedInterfaceForActionParameters;
+	}
 
-    public static CollectionSemantics of(final Class<?> accessorReturnType) {
+	public static CollectionSemantics of(final Class<?> accessorReturnType) {
         if (!Collection.class.isAssignableFrom(accessorReturnType)) {
             return ARRAY;
         }
+        if (Collection.class.equals(accessorReturnType)) {
+        	return COLLECTION_INTERFACE;
+        }
         if (List.class.isAssignableFrom(accessorReturnType)) {
-            return LIST;
+            return List.class.equals(accessorReturnType) ? LIST_INTERFACE : LIST_IMPLEMENTATION;
         }
         if (SortedSet.class.isAssignableFrom(accessorReturnType)) {
-            return SORTED_SET;
+        	return SortedSet.class.equals(accessorReturnType) ? SORTED_SET_INTERFACE : SORTED_SET_IMPLEMENTATION;
         }
         if (Set.class.isAssignableFrom(accessorReturnType)) {
-            return SET;
+        	return Set.class.equals(accessorReturnType) ? SET_INTERFACE : SET_IMPLEMENTATION;
         }
         return OTHER;
     }
@@ -79,15 +78,35 @@ public enum CollectionSemantics {
         return this == ARRAY;
     }
 
+    /**
+     * The corresponding class is assignable from {@link List}.
+     */
     public boolean isList() {
-        return this == LIST;
+        return this == LIST_IMPLEMENTATION || this == LIST_INTERFACE;
     }
 
-    public boolean isSet() {
-        return this == SET || this == SORTED_SET;
+    /**
+     * The corresponding class is assignable from {@link SortedSet}.
+     */
+    public boolean isSortedSet() {
+        return this == SORTED_SET_IMPLEMENTATION || this == SORTED_SET_INTERFACE;
+    }
+    
+    /**
+     * The corresponding class is assignable from {@link Set} but not from {@link SortedSet}.
+     */
+    public boolean isUnorderedSet() {
+        return this == SET_IMPLEMENTATION || this == SET_INTERFACE;
     }
 
     /**
+     * The corresponding class is assignable from {@link Set}.
+     */
+    public boolean isAnySet() {
+        return isSortedSet() || isUnorderedSet();
+    }
+    
+    /**
      * For example, {@link Queue}, or some other 3rd party implementation of
      * {@link Collection}.
      */
@@ -99,6 +118,8 @@ public enum CollectionSemantics {
         return isList() || isArray();
     }
 
-    public abstract Object emptyCollectionOf(final Class<?> elementClass);
+    public boolean isSupportedInterfaceForActionParameters() {
+    	return isSupportedInterfaceForActionParameters;
+    }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
index 12833a5..ef3a508 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
@@ -23,8 +23,6 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
-import com.google.common.base.Function;
-
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
index c0e7043..794b51c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
@@ -21,16 +21,15 @@ package org.apache.isis.core.metamodel.spec.feature;
 
 import javax.annotation.Nullable;
 
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-
-import com.google.common.base.Predicate;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.isis.core.metamodel.facets.all.named.NamedFacet;
 import org.apache.isis.core.metamodel.interactions.ActionArgValidityContext;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+
 /**
  * Analogous to {@link ObjectAssociation}.
  */
diff --git a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/CollectionSemantics.java b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/CollectionSemantics.java
index 4075016..c11a25c 100644
--- a/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/CollectionSemantics.java
+++ b/core/viewer-restfulobjects-rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/CollectionSemantics.java
@@ -40,7 +40,7 @@ public enum CollectionSemantics {
     }
 
     public static CollectionSemantics determine(final OneToManyAssociation collection) {
-        return collection.getCollectionSemantics().isSet() ? CollectionSemantics.SET : CollectionSemantics.LIST;
+        return collection.getCollectionSemantics().isAnySet() ? CollectionSemantics.SET : CollectionSemantics.LIST;
     }
 
 }
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java
index a8a6a68..86ba9b2 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainObjectResourceServerside.java
@@ -506,7 +506,7 @@ public class DomainObjectResourceServerside extends ResourceAbstract implements
         final OneToManyAssociation collection = accessHelper.getCollectionThatIsVisibleForIntent(
                 collectionId, ObjectAdapterAccessHelper.Intent.MUTATE);
 
-        if (!collection.getCollectionSemantics().isSet()) {
+        if (!collection.getCollectionSemantics().isAnySet()) {
             throw RestfulObjectsApplicationException.createWithMessage(HttpStatusCode.BAD_REQUEST, "Collection '%s' does not have set semantics", collectionId);
         }
 

-- 
To stop receiving notification emails like this one, please contact
ahuber@apache.org.