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/03/26 05:17:11 UTC
[isis] branch master updated: ISIS-1932 consolidating
collection-util classes
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 7b22d90 ISIS-1932 consolidating collection-util classes
7b22d90 is described below
commit 7b22d9041c0228cddd7cb71b781edccfb04a3832
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sun Mar 25 21:31:30 2018 +0200
ISIS-1932 consolidating collection-util classes
---
.../facets/actcoll/typeof/TypeOfFacet.java | 9 +-
.../core/metamodel/services/ServicesInjector.java | 11 +-
.../core/metamodel/specloader/CollectionUtils.java | 154 +++++++++++++++++----
3 files changed, 138 insertions(+), 36 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actcoll/typeof/TypeOfFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actcoll/typeof/TypeOfFacet.java
index d3219c1..8e79f74 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actcoll/typeof/TypeOfFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actcoll/typeof/TypeOfFacet.java
@@ -106,7 +106,7 @@ public interface TypeOfFacet extends SingleClassValueFacet {
final FacetHolder holder,
final Class<?> type,
final SpecificationLoader specificationLoader) {
- final Class<?> componentType = CollectionUtils.inferFromArrayType(type);
+ final Class<?> componentType = CollectionUtils.inferElementTypeFromArrayType(type);
return componentType != null
? new TypeOfFacetInferredFromArray(componentType, holder, specificationLoader)
: null;
@@ -118,7 +118,12 @@ public interface TypeOfFacet extends SingleClassValueFacet {
final Class<?> parameterType,
final Type genericParameterType,
final SpecificationLoader specificationLoader) {
- final Class<?> actualType = CollectionUtils.inferFromGenericParamType(parameterType, genericParameterType);
+
+ if(!CollectionUtils.isCollectionType(parameterType)) {
+ return null;
+ }
+
+ final Class<?> actualType = CollectionUtils.inferElementTypeFromGenericType(genericParameterType);
return actualType != null
? new TypeOfFacetInferredFromGenerics(actualType, holder, specificationLoader)
: null;
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
index 06582bb..b9d9773 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
@@ -43,6 +43,7 @@ import org.apache.isis.core.metamodel.exceptions.MetaModelException;
import org.apache.isis.core.metamodel.services.configinternal.ConfigurationServiceInternal;
import org.apache.isis.core.metamodel.services.persistsession.PersistenceSessionServiceInternal;
import org.apache.isis.core.metamodel.spec.InjectorMethodEvaluator;
+import org.apache.isis.core.metamodel.specloader.CollectionUtils;
import org.apache.isis.core.metamodel.specloader.InjectorMethodEvaluatorDefault;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.core.runtime.authentication.AuthenticationManager;
@@ -196,7 +197,7 @@ public class ServicesInjector implements ApplicationScopedComponent {
static boolean contains(final List<Object> services, final Class<?> serviceClass) {
return _NullSafe.stream(services)
- .anyMatch(service->serviceClass.isAssignableFrom(service.getClass()));
+ .anyMatch(isOfType(serviceClass));
}
/**
@@ -283,14 +284,14 @@ public class ServicesInjector implements ApplicationScopedComponent {
}
// inject matching services into a field of type Collection<T> if a generic type T is present
- CollectionHelper.ifIsCollectionWithGenericTypeThen(field, (elementType)->{
+ CollectionUtils.ifIsCollectionWithGenericTypeThen(field, (elementType)->{
@SuppressWarnings("unchecked")
final Class<? extends Collection<Object>> collectionTypeToBeInjected =
(Class<? extends Collection<Object>>) typeToBeInjected;
final Collection<Object> collectionOfServices =
- CollectionHelper.collectIntoUnmodifiableCompatibleWithCollectionType(
+ CollectionUtils.collectIntoUnmodifiableCompatibleWithCollectionType(
collectionTypeToBeInjected,
@@ -385,7 +386,7 @@ public class ServicesInjector implements ApplicationScopedComponent {
injectServicesInto(this.services);
}
- // -- lookupService, lookupServices
+ // -- LOOKUP SERVICE(S)
/**
* Returns the first registered domain service implementing the requested type.
@@ -450,7 +451,7 @@ public class ServicesInjector implements ApplicationScopedComponent {
// -- REFLECTIVE PREDICATES
private static final Predicate<Object> isOfType(final Class<?> cls) {
- return input->cls.isAssignableFrom(input.getClass());
+ return obj->cls.isAssignableFrom(obj.getClass());
}
private static final Predicate<Method> nameStartsWith(final String prefix) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/CollectionUtils.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/CollectionUtils.java
index 1f6133a..7d8fe7b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/CollectionUtils.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/CollectionUtils.java
@@ -19,12 +19,22 @@
package org.apache.isis.core.metamodel.specloader;
+import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
+import javax.annotation.Nullable;
/**
* Defines the types which are considered to be collections.
@@ -39,36 +49,64 @@ public final class CollectionUtils {
private CollectionUtils() {}
- public static boolean isCollectionType(final Class<?> cls) {
- return java.util.Collection.class.isAssignableFrom(cls);
+ // -- PREDICATES
+
+ public static boolean isCollectionType(@Nullable final Class<?> cls) {
+ return cls!=null ? java.util.Collection.class.isAssignableFrom(cls) : false;
}
- public static boolean isArrayType(final Class<?> cls) {
- return cls.isArray();
+ public static boolean isArrayType(@Nullable final Class<?> cls) {
+ return cls!=null ? cls.isArray() : false;
+ }
+
+ /**
+ *
+ * @param parameterType
+ * @param genericParameterType
+ * @return whether the parameter is a (collection or array) and has an infer-able element type
+ */
+ public static boolean isParamCollection(
+ @Nullable final Class<?> parameterType,
+ @Nullable final Type genericParameterType) {
+ if(inferElementTypeFromArrayType(parameterType) != null) {
+ return true;
+ }
+ if(isCollectionType(parameterType) && inferElementTypeFromGenericType(genericParameterType)!=null) {
+ return true;
+ }
+ return false;
}
- public static Class<?> inferFromArrayType(final Class<?> type) {
+ // -- ELEMENT TYPE INFERENCE (ARRAY)
+
+ /**
+ * Returns the inferred element type of the specified array type
+ * @param type of the array for which to infer the element type
+ * @return inferred type or null if inference fails
+ */
+ public static @Nullable Class<?> inferElementTypeFromArrayType(@Nullable final Class<?> type) {
if(!isArrayType(type)) {
return null;
}
- if (type.isArray()) {
- final Class<?> componentType = type.getComponentType();
- return componentType;
- }
- return null;
+ return type.getComponentType();
}
- @Programmatic
- public static Class<?> inferFromGenericParamType(
- final Class<?> parameterType,
- final Type genericParameterType) {
+ // -- ELEMENT TYPE INFERENCE (FROM GENERIC TYPE)
+
+ /**
+ * Returns the inferred element type of the specified array type
+ * @param collectionType
+ * @param genericParameterType
+ * @return inferred type or null if inference fails
+ */
+ public static @Nullable Class<?> inferElementTypeFromGenericType(@Nullable final Type genericType) {
- if(!isCollectionType(parameterType)) {
- return null;
- }
+ if(genericType==null) {
+ return null;
+ }
- if(genericParameterType instanceof ParameterizedType) {
- final ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
+ if(genericType instanceof ParameterizedType) {
+ final ParameterizedType parameterizedType = (ParameterizedType) genericType;
final Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
if(actualTypeArguments.length == 1) {
final Type actualTypeArgument = actualTypeArguments[0];
@@ -78,15 +116,73 @@ public final class CollectionUtils {
}
}
}
+
return null;
}
+ // -- ELEMENT TYPE INFERENCE (FROM FIELD)
+
/**
- * @return true means that either {@link CollectionUtils#inferFromGenericParamType(Class, Type)} or {@link TypeOfFacet.Util#inferFromArrayType(FacetHolder, Class, SpecificationLoader)} will return a non-null value.
- */
- public static boolean isParamCollection(
- final Class<?> parameterType,
- final Type genericParameterType) {
- return inferFromGenericParamType(parameterType, genericParameterType) != null || inferFromArrayType(parameterType) != null;
- }
+ * If field is of type (or a sub-type of) Collection<T> with generic type T present,
+ * then call action with the element type.
+ * @param field
+ * @param action
+ */
+ public static void ifIsCollectionWithGenericTypeThen(Field field, Consumer<Class<?>> action) {
+
+ final Class<?> fieldType = field.getType();
+
+ if(isCollectionType(fieldType)) {
+
+ final Class<?> elementType = inferElementTypeFromGenericType(field.getGenericType());
+
+ if(elementType!=null) {
+ action.accept(elementType);
+ }
+ }
+
+ }
+
+ // -- COLLECT ELEMENTS FROM STREAM
+
+ /**
+ * Collects elements from stream into a collection that is compatible with the given typeOfCollection.
+ * @param typeOfCollection
+ * @param elementStream
+ * @return
+ *
+ * @throws IllegalArgumentException if the given typeOfCollection is not supported
+ */
+ public static <T> Collection<T> collectIntoUnmodifiableCompatibleWithCollectionType (
+ Class<?> typeOfCollection, Stream<? extends T> elementStream) {
+
+ if(SortedSet.class.equals(typeOfCollection)) {
+ return Collections.unmodifiableSortedSet(
+ elementStream.collect(Collectors.<T, SortedSet<T>>toCollection(TreeSet::new))
+ );
+ }
+
+ if(Set.class.equals(typeOfCollection)) {
+ return Collections.unmodifiableSet(
+ elementStream.collect(Collectors.<T, Set<T>>toCollection(HashSet::new))
+ );
+ }
+
+ if(List.class.equals(typeOfCollection)) {
+ return Collections.unmodifiableList(
+ elementStream.collect(Collectors.<T, List<T>>toCollection(ArrayList::new))
+ );
+ }
+
+ if(Collection.class.equals(typeOfCollection)) {
+ return Collections.unmodifiableCollection(
+ elementStream.collect(Collectors.toCollection(ArrayList::new))
+ );
+ }
+
+ throw new IllegalArgumentException(
+ String.format("Can not collect into %s. Only List, Set, SortedSet and Collection are supported.",
+ typeOfCollection.getClass().getName()));
+ }
+
}
--
To stop receiving notification emails like this one, please contact
ahuber@apache.org.