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 2014/07/11 12:56:56 UTC
[44/61] [partial] ISIS-831: digression: moving progmodel/facets into
metamodel/facets
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToFacetViaAccessor.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToFacetViaAccessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToFacetViaAccessor.java
new file mode 100644
index 0000000..467cf16
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToFacetViaAccessor.java
@@ -0,0 +1,98 @@
+/*
+ * 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.core.metamodel.facets.collections.modify;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectDirtier;
+import org.apache.isis.core.metamodel.adapter.util.AdapterInvokeUtils;
+import org.apache.isis.core.metamodel.adapter.util.AdapterUtils;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToFacetAbstract;
+
+public class CollectionAddToFacetViaAccessor extends CollectionAddToFacetAbstract implements ImperativeFacet {
+
+ private final Method method;
+ private final ObjectDirtier objectDirtier;
+
+ public CollectionAddToFacetViaAccessor(final Method method, final FacetHolder holder, final ObjectDirtier objectDirtier) {
+ super(holder);
+ this.method = method;
+ this.objectDirtier = objectDirtier;
+ }
+
+ /**
+ * Returns a singleton list of the {@link Method} provided in the
+ * constructor.
+ */
+ @Override
+ public List<Method> getMethods() {
+ return Collections.singletonList(method);
+ }
+
+ @Override
+ public Intent getIntent(final Method method) {
+ return Intent.MODIFY_COLLECTION_ADD;
+ }
+
+ @Override
+ public boolean impliesResolve() {
+ return true;
+ }
+
+ /**
+ * Bytecode cannot automatically call
+ * {@link DomainObjectContainer#objectChanged(Object)} because cannot
+ * distinguish whether interacting with accessor to read it or to modify its
+ * contents.
+ */
+ @Override
+ public boolean impliesObjectChanged() {
+ return false;
+ }
+
+ @Override
+ public void add(final ObjectAdapter owningAdapter, final ObjectAdapter elementAdapter) {
+ @SuppressWarnings("unchecked")
+ final Collection<? super Object> collection = (Collection<? super Object>) AdapterInvokeUtils.invoke(method, owningAdapter);
+ final Object elementPojo = AdapterUtils.unwrap(elementAdapter);
+ collection.add(elementPojo);
+ getObjectDirtier().objectChanged(owningAdapter);
+ }
+
+ @Override
+ protected String toStringValues() {
+ return "method=" + method;
+ }
+
+ // /////////////////////////////////////////////////////
+ // Dependencies
+ // /////////////////////////////////////////////////////
+
+ protected ObjectDirtier getObjectDirtier() {
+ return objectDirtier;
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToFacetViaMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToFacetViaMethod.java
new file mode 100644
index 0000000..98609ed
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToFacetViaMethod.java
@@ -0,0 +1,75 @@
+/*
+ * 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.core.metamodel.facets.collections.modify;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.util.AdapterInvokeUtils;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToFacetAbstract;
+
+public class CollectionAddToFacetViaMethod extends CollectionAddToFacetAbstract implements ImperativeFacet {
+
+ private final Method method;
+
+ public CollectionAddToFacetViaMethod(final Method method, final FacetHolder holder) {
+ super(holder);
+ this.method = method;
+ }
+
+ /**
+ * Returns a singleton list of the {@link Method} provided in the
+ * constructor.
+ */
+ @Override
+ public List<Method> getMethods() {
+ return Collections.singletonList(method);
+ }
+
+ @Override
+ public Intent getIntent(final Method method) {
+ return Intent.MODIFY_COLLECTION_ADD;
+ }
+
+ @Override
+ public boolean impliesResolve() {
+ return true;
+ }
+
+ @Override
+ public boolean impliesObjectChanged() {
+ return true;
+ }
+
+ @Override
+ public void add(final ObjectAdapter owningAdapter, final ObjectAdapter elementAdapter) {
+ AdapterInvokeUtils.invoke(method, owningAdapter, elementAdapter);
+ }
+
+ @Override
+ protected String toStringValues() {
+ return "method=" + method;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToRemoveFromAndValidateFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToRemoveFromAndValidateFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToRemoveFromAndValidateFacetFactory.java
new file mode 100644
index 0000000..5184e9d
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionAddToRemoveFromAndValidateFacetFactory.java
@@ -0,0 +1,183 @@
+/*
+ * 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.core.metamodel.facets.collections.modify;
+
+import java.lang.reflect.Method;
+
+import org.apache.isis.core.commons.lang.StringExtensions;
+import org.apache.isis.core.metamodel.adapter.ObjectDirtier;
+import org.apache.isis.core.metamodel.adapter.ObjectDirtierAware;
+import org.apache.isis.core.metamodel.exceptions.MetaModelException;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.FacetFactory;
+import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.facets.MethodFinderUtils;
+import org.apache.isis.core.metamodel.facets.MethodPrefixBasedFacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.MethodPrefixConstants;
+import org.apache.isis.core.metamodel.facets.collections.validate.CollectionValidateAddToFacetViaMethod;
+import org.apache.isis.core.metamodel.facets.collections.validate.CollectionValidateRemoveFromFacetViaMethod;
+
+/**
+ * TODO: should probably split out into two {@link FacetFactory}s, one for
+ * <tt>addTo()</tt>/<tt>removeFrom()</tt> and one for <tt>validateAddTo()</tt>/
+ * <tt>validateRemoveFrom()</tt>.
+ */
+public class CollectionAddToRemoveFromAndValidateFacetFactory extends MethodPrefixBasedFacetFactoryAbstract implements ObjectDirtierAware {
+
+ private static final String[] PREFIXES = {};
+
+ private ObjectDirtier objectDirtier;
+
+ public CollectionAddToRemoveFromAndValidateFacetFactory() {
+ super(FeatureType.COLLECTIONS_ONLY, OrphanValidation.VALIDATE, PREFIXES);
+ }
+
+ @Override
+ public void process(final ProcessMethodContext processMethodContext) {
+
+ final Class<?> collectionType = attachAddToFacetAndRemoveFromFacet(processMethodContext);
+ attachValidateAddToAndRemoveFromFacetIfMethodsFound(processMethodContext, collectionType);
+ }
+
+ private Class<?> attachAddToFacetAndRemoveFromFacet(final ProcessMethodContext processMethodContext) {
+
+ final Method accessorMethod = processMethodContext.getMethod();
+ final String capitalizedName = StringExtensions.asJavaBaseName(accessorMethod.getName());
+
+ final Class<?> cls = processMethodContext.getCls();
+
+ // add
+ final Method addToMethod = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, MethodPrefixConstants.ADD_TO_PREFIX + capitalizedName, void.class);
+ processMethodContext.removeMethod(addToMethod);
+
+ // remove
+ final Method removeFromMethod = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, MethodPrefixConstants.REMOVE_FROM_PREFIX + capitalizedName, void.class);
+ processMethodContext.removeMethod(removeFromMethod);
+
+ // add facets
+ final FacetHolder collection = processMethodContext.getFacetHolder();
+ FacetUtil.addFacet(createAddToFacet(addToMethod, accessorMethod, collection));
+ FacetUtil.addFacet(createRemoveFromFacet(removeFromMethod, accessorMethod, collection));
+
+ // infer typ
+ final Class<?> addToType = ((addToMethod == null || addToMethod.getParameterTypes().length != 1) ? null : addToMethod.getParameterTypes()[0]);
+ final Class<?> removeFromType = ((removeFromMethod == null || removeFromMethod.getParameterTypes().length != 1) ? null : removeFromMethod.getParameterTypes()[0]);
+
+ return inferTypeOfIfPossible(accessorMethod, addToType, removeFromType, collection);
+ }
+
+ /**
+ * TODO need to distinguish between Java collections, arrays and other
+ * collections!
+ */
+ private CollectionAddToFacet createAddToFacet(final Method addToMethodIfAny, final Method accessorMethod, final FacetHolder holder) {
+ if (addToMethodIfAny != null) {
+ return new CollectionAddToFacetViaMethod(addToMethodIfAny, holder);
+ } else {
+ return new CollectionAddToFacetViaAccessor(accessorMethod, holder, getObjectDirtier());
+ }
+ }
+
+ /**
+ * TODO need to distinguish between Java collections, arrays and other
+ * collections!
+ */
+ private CollectionRemoveFromFacet createRemoveFromFacet(final Method removeFromMethodIfAny, final Method accessorMethod, final FacetHolder holder) {
+ if (removeFromMethodIfAny != null) {
+ return new CollectionRemoveFromFacetViaMethod(removeFromMethodIfAny, holder);
+ } else {
+ return new CollectionRemoveFromFacetViaAccessor(accessorMethod, holder, getObjectDirtier());
+ }
+ }
+
+ private Class<?> inferTypeOfIfPossible(final Method getMethod, final Class<?> addType, final Class<?> removeType, final FacetHolder collection) {
+
+ if (addType != null && removeType != null && addType != removeType) {
+ throw new MetaModelException("The addTo/removeFrom methods for " + getMethod.getDeclaringClass() + " must " + "both deal with same type of object: " + addType + "; " + removeType);
+ }
+
+ final Class<?> type = addType != null ? addType : removeType;
+ if (type != null) {
+ FacetUtil.addFacet(new TypeOfFacetInferredFromSupportingMethods(type, collection, getSpecificationLoader()));
+ }
+ return type;
+ }
+
+ private void attachValidateAddToAndRemoveFromFacetIfMethodsFound(final ProcessMethodContext processMethodContext, final Class<?> collectionType) {
+ attachValidateAddToFacetIfValidateAddToMethodIsFound(processMethodContext, collectionType);
+ attachValidateRemoveFacetIfValidateRemoveFromMethodIsFound(processMethodContext, collectionType);
+ }
+
+ private void attachValidateAddToFacetIfValidateAddToMethodIsFound(final ProcessMethodContext processMethodContext, final Class<?> collectionType) {
+
+ final Method getMethod = processMethodContext.getMethod();
+ final String capitalizedName = StringExtensions.asJavaBaseName(getMethod.getName());
+
+ final Class<?> cls = processMethodContext.getCls();
+ final Class<?>[] paramTypes = MethodFinderUtils.paramTypesOrNull(collectionType);
+ Method validateAddToMethod = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, MethodPrefixConstants.VALIDATE_ADD_TO_PREFIX + capitalizedName, String.class, paramTypes);
+ if (validateAddToMethod == null) {
+ validateAddToMethod = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, MethodPrefixConstants.VALIDATE_ADD_TO_PREFIX_2 + capitalizedName, String.class, MethodFinderUtils.paramTypesOrNull(collectionType));
+ }
+ if (validateAddToMethod == null) {
+ return;
+ }
+ processMethodContext.removeMethod(validateAddToMethod);
+
+ final FacetHolder collection = processMethodContext.getFacetHolder();
+ FacetUtil.addFacet(new CollectionValidateAddToFacetViaMethod(validateAddToMethod, collection));
+ }
+
+ private void attachValidateRemoveFacetIfValidateRemoveFromMethodIsFound(final ProcessMethodContext processMethodContext, final Class<?> collectionType) {
+
+ final Method getMethod = processMethodContext.getMethod();
+ final String capitalizedName = StringExtensions.asJavaBaseName(getMethod.getName());
+
+ final Class<?> cls = processMethodContext.getCls();
+ final Class<?>[] paramTypes = MethodFinderUtils.paramTypesOrNull(collectionType);
+ Method validateRemoveFromMethod = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, MethodPrefixConstants.VALIDATE_REMOVE_FROM_PREFIX + capitalizedName, String.class, paramTypes);
+ if (validateRemoveFromMethod == null) {
+ validateRemoveFromMethod = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, MethodPrefixConstants.VALIDATE_REMOVE_FROM_PREFIX_2 + capitalizedName, String.class, MethodFinderUtils.paramTypesOrNull(collectionType));
+ }
+ if (validateRemoveFromMethod == null) {
+ return;
+ }
+ processMethodContext.removeMethod(validateRemoveFromMethod);
+
+ final FacetHolder collection = processMethodContext.getFacetHolder();
+ FacetUtil.addFacet(new CollectionValidateRemoveFromFacetViaMethod(validateRemoveFromMethod, collection));
+ }
+
+ // ///////////////////////////////////////////////////////
+ // Dependencies (injected)
+ // ///////////////////////////////////////////////////////
+
+ protected ObjectDirtier getObjectDirtier() {
+ return objectDirtier;
+ }
+
+ @Override
+ public void setObjectDirtier(final ObjectDirtier objectDirtier) {
+ this.objectDirtier = objectDirtier;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacet.java
index 519913f..0ca3f72 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacet.java
@@ -19,12 +19,14 @@
package org.apache.isis.core.metamodel.facets.collections.modify;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
+import java.util.List;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facets.typeof.TypeOfFacet;
+import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
/**
@@ -63,4 +65,27 @@ public interface CollectionFacet extends Facet {
*/
TypeOfFacet getTypeOfFacet();
+
+ public static class Utils {
+
+ public static CollectionFacet getCollectionFacetFromSpec(final ObjectAdapter objectRepresentingCollection) {
+ final ObjectSpecification collectionSpec = objectRepresentingCollection.getSpecification();
+ return collectionSpec.getFacet(CollectionFacet.class);
+ }
+
+ public static int size(final ObjectAdapter collection) {
+ final CollectionFacet facet = getCollectionFacetFromSpec(collection);
+ return facet.size(collection);
+ }
+
+ public static List<ObjectAdapter> convertToAdapterList(final ObjectAdapter collection) {
+ final CollectionFacet facet = getCollectionFacetFromSpec(collection);
+ final List<ObjectAdapter> adapters = new ArrayList<ObjectAdapter>();
+ for (final ObjectAdapter adapter : facet.iterable(collection)) {
+ adapters.add(adapter);
+ }
+ return adapters;
+ }
+
+ }
}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacetUtils.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacetUtils.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacetUtils.java
index 7ce17f9..fed2206 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacetUtils.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionFacetUtils.java
@@ -19,55 +19,28 @@
package org.apache.isis.core.metamodel.facets.collections.modify;
-import java.util.ArrayList;
import java.util.List;
-
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+@Deprecated
public final class CollectionFacetUtils {
+
private CollectionFacetUtils() {
}
+ @Deprecated
public static CollectionFacet getCollectionFacetFromSpec(final ObjectAdapter objectRepresentingCollection) {
- final ObjectSpecification collectionSpec = objectRepresentingCollection.getSpecification();
- return collectionSpec.getFacet(CollectionFacet.class);
+ return CollectionFacet.Utils.getCollectionFacetFromSpec(objectRepresentingCollection);
}
+ @Deprecated
public static int size(final ObjectAdapter collection) {
- final CollectionFacet facet = getCollectionFacetFromSpec(collection);
- return facet.size(collection);
- }
-
- public static ObjectAdapter firstElement(final ObjectAdapter collection) {
- final CollectionFacet facet = getCollectionFacetFromSpec(collection);
- return facet.firstElement(collection);
+ return CollectionFacet.Utils.size(collection);
}
- /**
- * @deprecated - use instead {@link #convertToList(ObjectAdapter)}.
- */
@Deprecated
- public static Object[] convertToArray(final ObjectAdapter collection) {
- return convertToList(collection).toArray();
- }
-
- public static List<Object> convertToList(final ObjectAdapter collection) {
- final CollectionFacet facet = getCollectionFacetFromSpec(collection);
- final List<Object> objects = new ArrayList<Object>();
- for (final ObjectAdapter adapter : facet.iterable(collection)) {
- objects.add(adapter.getObject());
- }
- return objects;
- }
-
public static List<ObjectAdapter> convertToAdapterList(final ObjectAdapter collection) {
- final CollectionFacet facet = getCollectionFacetFromSpec(collection);
- final List<ObjectAdapter> adapters = new ArrayList<ObjectAdapter>();
- for (final ObjectAdapter adapter : facet.iterable(collection)) {
- adapters.add(adapter);
- }
- return adapters;
+ return CollectionFacet.Utils.convertToAdapterList(collection);
}
}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionRemoveFromFacetViaAccessor.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionRemoveFromFacetViaAccessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionRemoveFromFacetViaAccessor.java
new file mode 100644
index 0000000..72ba192
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionRemoveFromFacetViaAccessor.java
@@ -0,0 +1,99 @@
+/*
+ * 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.core.metamodel.facets.collections.modify;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectDirtier;
+import org.apache.isis.core.metamodel.adapter.util.AdapterInvokeUtils;
+import org.apache.isis.core.metamodel.adapter.util.AdapterUtils;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet.Intent;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionRemoveFromFacetAbstract;
+
+public class CollectionRemoveFromFacetViaAccessor extends CollectionRemoveFromFacetAbstract implements ImperativeFacet {
+
+ private final Method method;
+ private final ObjectDirtier objectDirtier;
+
+ public CollectionRemoveFromFacetViaAccessor(final Method method, final FacetHolder holder, final ObjectDirtier objectDirtier) {
+ super(holder);
+ this.method = method;
+ this.objectDirtier = objectDirtier;
+ }
+
+ /**
+ * Returns a singleton list of the {@link Method} provided in the
+ * constructor.
+ */
+ @Override
+ public List<Method> getMethods() {
+ return Collections.singletonList(method);
+ }
+
+ @Override
+ public Intent getIntent(final Method method) {
+ return Intent.MODIFY_COLLECTION_REMOVE;
+ }
+
+ @Override
+ public boolean impliesResolve() {
+ return true;
+ }
+
+ /**
+ * Bytecode cannot automatically call
+ * {@link DomainObjectContainer#objectChanged(Object)} because cannot
+ * distinguish whether interacting with accessor to read it or to modify its
+ * contents.
+ */
+ @Override
+ public boolean impliesObjectChanged() {
+ return false;
+ }
+
+ @Override
+ public void remove(final ObjectAdapter owningAdapter, final ObjectAdapter elementAdapter) {
+ @SuppressWarnings("unchecked")
+ final Collection<? super Object> collection = (Collection<? super Object>) AdapterInvokeUtils.invoke(method, owningAdapter);
+ collection.remove(AdapterUtils.unwrap(elementAdapter));
+ getObjectDirtier().objectChanged(owningAdapter);
+ }
+
+ @Override
+ protected String toStringValues() {
+ return "method=" + method;
+ }
+
+ // /////////////////////////////////////////////////////////
+ // Dependencies (from constructor)
+ // /////////////////////////////////////////////////////////
+
+ protected ObjectDirtier getObjectDirtier() {
+ return objectDirtier;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionRemoveFromFacetViaMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionRemoveFromFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionRemoveFromFacetViaMethod.java
new file mode 100644
index 0000000..23dfe30
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/CollectionRemoveFromFacetViaMethod.java
@@ -0,0 +1,76 @@
+/*
+ * 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.core.metamodel.facets.collections.modify;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.util.AdapterInvokeUtils;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet.Intent;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionRemoveFromFacetAbstract;
+
+public class CollectionRemoveFromFacetViaMethod extends CollectionRemoveFromFacetAbstract implements ImperativeFacet {
+
+ private final Method method;
+
+ public CollectionRemoveFromFacetViaMethod(final Method method, final FacetHolder holder) {
+ super(holder);
+ this.method = method;
+ }
+
+ /**
+ * Returns a singleton list of the {@link Method} provided in the
+ * constructor.
+ */
+ @Override
+ public List<Method> getMethods() {
+ return Collections.singletonList(method);
+ }
+
+ @Override
+ public Intent getIntent(final Method method) {
+ return Intent.MODIFY_COLLECTION_REMOVE;
+ }
+
+ @Override
+ public boolean impliesResolve() {
+ return true;
+ }
+
+ @Override
+ public boolean impliesObjectChanged() {
+ return true;
+ }
+
+ @Override
+ public void remove(final ObjectAdapter owningAdapter, final ObjectAdapter elementAdapter) {
+ AdapterInvokeUtils.invoke(method, owningAdapter, elementAdapter);
+ }
+
+ @Override
+ protected String toStringValues() {
+ return "method=" + method;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/TypeOfFacetInferredFromSupportingMethods.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/TypeOfFacetInferredFromSupportingMethods.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/TypeOfFacetInferredFromSupportingMethods.java
new file mode 100644
index 0000000..f91c59e
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/modify/TypeOfFacetInferredFromSupportingMethods.java
@@ -0,0 +1,32 @@
+/*
+ * 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.core.metamodel.facets.collections.modify;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacetAbstract;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+
+public class TypeOfFacetInferredFromSupportingMethods extends TypeOfFacetAbstract {
+
+ public TypeOfFacetInferredFromSupportingMethods(final Class<?> type, final FacetHolder holder, final SpecificationLoader specificationLookup) {
+ super(type, holder, specificationLookup);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/notpersisted/annotation/NotPersistedFacetOnCollectionAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/notpersisted/annotation/NotPersistedFacetOnCollectionAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/notpersisted/annotation/NotPersistedFacetOnCollectionAnnotation.java
new file mode 100644
index 0000000..fa7110c
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/notpersisted/annotation/NotPersistedFacetOnCollectionAnnotation.java
@@ -0,0 +1,31 @@
+/*
+ * 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.core.metamodel.facets.collections.notpersisted.annotation;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacetAbstract;
+
+public class NotPersistedFacetOnCollectionAnnotation extends NotPersistedFacetAbstract {
+
+ public NotPersistedFacetOnCollectionAnnotation(final FacetHolder holder) {
+ super(holder);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/notpersisted/annotation/NotPersistedFacetOnCollectionAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/notpersisted/annotation/NotPersistedFacetOnCollectionAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/notpersisted/annotation/NotPersistedFacetOnCollectionAnnotationFactory.java
new file mode 100644
index 0000000..3f9fd75
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/notpersisted/annotation/NotPersistedFacetOnCollectionAnnotationFactory.java
@@ -0,0 +1,46 @@
+/*
+ * 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.core.metamodel.facets.collections.notpersisted.annotation;
+
+import org.apache.isis.applib.annotation.NotPersisted;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.propcoll.notpersisted.NotPersistedFacet;
+
+public class NotPersistedFacetOnCollectionAnnotationFactory extends FacetFactoryAbstract {
+
+ public NotPersistedFacetOnCollectionAnnotationFactory() {
+ super(FeatureType.COLLECTIONS_ONLY);
+ }
+
+ @Override
+ public void process(final ProcessMethodContext processMethodContext) {
+ final NotPersisted annotation = Annotations.getAnnotation(processMethodContext.getMethod(), NotPersisted.class);
+ FacetUtil.addFacet(create(annotation, processMethodContext.getFacetHolder()));
+ }
+
+ private NotPersistedFacet create(final NotPersisted annotation, final FacetHolder holder) {
+ return annotation == null ? null : new NotPersistedFacetOnCollectionAnnotation(holder);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/paged/annotation/PagedFacetOnCollectionFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/paged/annotation/PagedFacetOnCollectionFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/paged/annotation/PagedFacetOnCollectionFactory.java
new file mode 100644
index 0000000..ec53b89
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/paged/annotation/PagedFacetOnCollectionFactory.java
@@ -0,0 +1,86 @@
+/*
+ * 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.core.metamodel.facets.collections.paged.annotation;
+
+import java.util.Properties;
+
+import org.apache.isis.applib.annotation.Paged;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.config.IsisConfigurationAware;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.ContributeeMemberFacetFactory;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.objcoll.paged.PagedFacetAnnotation;
+import org.apache.isis.core.metamodel.facets.objcoll.paged.PagedFacetProperties;
+import org.apache.isis.core.metamodel.facets.object.paged.PagedFacet;
+
+public class PagedFacetOnCollectionFactory extends FacetFactoryAbstract
+ implements ContributeeMemberFacetFactory, IsisConfigurationAware {
+
+ private IsisConfiguration configuration;
+
+ public PagedFacetOnCollectionFactory() {
+ super(FeatureType.COLLECTIONS_ONLY);
+ }
+
+ @Override
+ public void process(final ProcessMethodContext processMethodContext) {
+
+ PagedFacet pagedFacet = createFromMetadataPropertiesIfPossible(processMethodContext);
+ if(pagedFacet == null) {
+ pagedFacet = createFromPagedAnnotationIfPossible(processMethodContext);
+ }
+ // no-op if null
+ FacetUtil.addFacet(pagedFacet);
+ }
+
+ @Override
+ public void process(ProcessContributeeMemberContext processMemberContext) {
+ final PagedFacet pagedFacet = createFromMetadataPropertiesIfPossible(processMemberContext);
+ // no-op if null
+ FacetUtil.addFacet(pagedFacet);
+ }
+
+ private PagedFacet createFromMetadataPropertiesIfPossible(final ProcessContextWithMetadataProperties<?> processMethodContext) {
+ final Properties properties = processMethodContext.metadataProperties("paged");
+ return properties != null ? new PagedFacetProperties(properties, processMethodContext.getFacetHolder()) : null;
+ }
+
+ private PagedFacet createFromPagedAnnotationIfPossible(final ProcessMethodContext processMethodContext) {
+ final Paged annotation = Annotations.getAnnotation(processMethodContext.getMethod(), Paged.class);
+ return annotation != null ? new PagedFacetAnnotation(processMethodContext.getFacetHolder(), annotation.value()) : null;
+ }
+
+
+ // //////////////////////////////////////
+
+ public IsisConfiguration getConfiguration() {
+ return configuration;
+ }
+
+ @Override
+ public void setConfiguration(IsisConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/parented/ParentedFacetSinceCollection.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/parented/ParentedFacetSinceCollection.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/parented/ParentedFacetSinceCollection.java
new file mode 100644
index 0000000..385db0f
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/parented/ParentedFacetSinceCollection.java
@@ -0,0 +1,31 @@
+/*
+ * 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.core.metamodel.facets.collections.parented;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.parented.ParentedFacetAbstract;
+
+public class ParentedFacetSinceCollection extends ParentedFacetAbstract {
+
+ public ParentedFacetSinceCollection(final FacetHolder holder) {
+ super(holder);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/parented/ParentedFacetSinceCollectionFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/parented/ParentedFacetSinceCollectionFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/parented/ParentedFacetSinceCollectionFactory.java
new file mode 100644
index 0000000..2097222
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/parented/ParentedFacetSinceCollectionFactory.java
@@ -0,0 +1,53 @@
+/*
+ * 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.core.metamodel.facets.collections.parented;
+
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.facets.object.parented.ParentedFacet;
+import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
+import org.apache.isis.core.metamodel.specloader.collectiontyperegistry.CollectionTypeRegistry;
+import org.apache.isis.core.metamodel.facets.collections.collection.CollectionFacetFactory;
+
+/**
+ * All {@link CollectionTypeRegistry collection types} are intrinsically
+ * {@link ParentedFacet parented}.
+ *
+ * <p>
+ * Must be registered in the {@link ProgrammingModel} after
+ * {@link CollectionFacetFactory}.
+ */
+public class ParentedFacetSinceCollectionFactory extends FacetFactoryAbstract {
+
+ public ParentedFacetSinceCollectionFactory() {
+ super(FeatureType.OBJECTS_ONLY);
+ }
+
+ @Override
+ public void process(final ProcessClassContext processClassContaxt) {
+ if (!processClassContaxt.getFacetHolder().containsFacet(CollectionFacet.class)) {
+ return;
+ }
+ FacetUtil.addFacet(new ParentedFacetSinceCollection(processClassContaxt.getFacetHolder()));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotation.java
new file mode 100644
index 0000000..14647ca
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotation.java
@@ -0,0 +1,33 @@
+/*
+ * 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.core.metamodel.facets.collections.sortedby.annotation;
+
+import java.util.Comparator;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.collections.sortedby.SortedByFacetAbstract;
+
+public class SortedByFacetAnnotation extends SortedByFacetAbstract {
+
+ public SortedByFacetAnnotation(final FacetHolder holder, Class<? extends Comparator<?>> value) {
+ super(value, holder);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotationFactory.java
new file mode 100644
index 0000000..c8b1ad5
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/sortedby/annotation/SortedByFacetAnnotationFactory.java
@@ -0,0 +1,94 @@
+/*
+ * 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.core.metamodel.facets.collections.sortedby.annotation;
+
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.isis.applib.annotation.SortedBy;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facetapi.MetaModelValidatorRefiner;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.collections.sortedby.SortedByFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorComposite;
+import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorVisiting;
+import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorVisiting.Visitor;
+import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
+
+/**
+ * There is no check that the value is a {@link Comparator}; instead this is done through
+ * the {@link #refineMetaModelValidator(MetaModelValidatorComposite, IsisConfiguration)}.
+ */
+public class SortedByFacetAnnotationFactory extends FacetFactoryAbstract implements MetaModelValidatorRefiner {
+
+ public SortedByFacetAnnotationFactory() {
+ super(FeatureType.COLLECTIONS_ONLY);
+ }
+
+ @Override
+ public void process(final ProcessMethodContext processMethodContext) {
+ final SortedBy renderAnnotation = Annotations.getAnnotation(processMethodContext.getMethod(), SortedBy.class);
+ FacetUtil.addFacet(create(renderAnnotation, processMethodContext.getFacetHolder()));
+ }
+
+ private SortedByFacet create(final SortedBy annotation, final FacetHolder holder) {
+ if (annotation == null) {
+ return null;
+ }
+ final Class<?> annotationValue = annotation.value();
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ final Class<? extends Comparator<?>> comparatorType = (Class)annotationValue;
+ return new SortedByFacetAnnotation(holder, comparatorType);
+ }
+
+ @Override
+ public void refineMetaModelValidator(MetaModelValidatorComposite metaModelValidator, IsisConfiguration configuration) {
+ metaModelValidator.add(new MetaModelValidatorVisiting(newValidatorVisitor()));
+ }
+
+ protected Visitor newValidatorVisitor() {
+ return new MetaModelValidatorVisiting.Visitor() {
+
+ @Override
+ public boolean visit(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
+ List<OneToManyAssociation> objectCollections = objectSpec.getCollections(Contributed.EXCLUDED);
+ for (OneToManyAssociation objectCollection : objectCollections) {
+ final SortedByFacet facet = objectCollection.getFacet(SortedByFacet.class);
+ if(facet != null) {
+ final Class<? extends Comparator<?>> cls = facet.value();
+ if(!Comparator.class.isAssignableFrom(cls)) {
+ validationFailures.add("%s#%s is annotated with @SortedBy, but the class specified '%s' is not a Comparator", objectSpec.getIdentifier().getClassName(), objectCollection.getId(), facet.value().getName());
+ }
+ }
+ }
+ return true;
+ }
+ };
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/typeof/annotation/TypeOfFacetOnCollectionAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/typeof/annotation/TypeOfFacetOnCollectionAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/typeof/annotation/TypeOfFacetOnCollectionAnnotation.java
new file mode 100644
index 0000000..83e8477
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/typeof/annotation/TypeOfFacetOnCollectionAnnotation.java
@@ -0,0 +1,32 @@
+/*
+ * 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.core.metamodel.facets.collections.typeof.annotation;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacetAbstract;
+import org.apache.isis.core.metamodel.spec.SpecificationLoader;
+
+public class TypeOfFacetOnCollectionAnnotation extends TypeOfFacetAbstract {
+
+ public TypeOfFacetOnCollectionAnnotation(final Class<?> type, final FacetHolder holder, final SpecificationLoader specificationLookup) {
+ super(type, holder, specificationLookup);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/typeof/annotation/TypeOfFacetOnCollectionAnnotationFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/typeof/annotation/TypeOfFacetOnCollectionAnnotationFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/typeof/annotation/TypeOfFacetOnCollectionAnnotationFactory.java
new file mode 100644
index 0000000..6bcfb18
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/typeof/annotation/TypeOfFacetOnCollectionAnnotationFactory.java
@@ -0,0 +1,97 @@
+/*
+ * 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.core.metamodel.facets.collections.typeof.annotation;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+
+import org.apache.isis.applib.annotation.TypeOf;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacetInferredFromArray;
+import org.apache.isis.core.metamodel.facets.actcoll.typeof.TypeOfFacetInferredFromGenerics;
+import org.apache.isis.core.metamodel.specloader.collectiontyperegistry.CollectionTypeRegistry;
+import org.apache.isis.core.metamodel.specloader.collectiontyperegistry.CollectionTypeRegistryAware;
+
+public class TypeOfFacetOnCollectionAnnotationFactory extends FacetFactoryAbstract implements CollectionTypeRegistryAware {
+ private CollectionTypeRegistry collectionTypeRegistry;
+
+ public TypeOfFacetOnCollectionAnnotationFactory() {
+ super(FeatureType.COLLECTIONS_ONLY);
+ }
+
+ @Override
+ public void process(final ProcessMethodContext processMethodContext) {
+
+ final Class<?> methodReturnType = processMethodContext.getMethod().getReturnType();
+ if (!collectionTypeRegistry.isCollectionType(methodReturnType) && !collectionTypeRegistry.isArrayType(methodReturnType)) {
+ return;
+ }
+
+ final Class<?> returnType = processMethodContext.getMethod().getReturnType();
+ if (returnType.isArray()) {
+ final Class<?> componentType = returnType.getComponentType();
+ FacetUtil.addFacet(new TypeOfFacetInferredFromArray(componentType, processMethodContext.getFacetHolder(), getSpecificationLoader()));
+ return;
+ }
+
+ Method method = processMethodContext.getMethod();
+ final TypeOf annotation = Annotations.getAnnotation(method, TypeOf.class);
+ if (annotation != null) {
+ FacetUtil.addFacet(new TypeOfFacetOnCollectionAnnotation(annotation.value(), processMethodContext.getFacetHolder(), getSpecificationLoader()));
+ return;
+ }
+
+ final Type type = processMethodContext.getMethod().getGenericReturnType();
+ if (!(type instanceof ParameterizedType)) {
+ return;
+ }
+
+ final ParameterizedType parameterizedType = (ParameterizedType) type;
+ final Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+ if (actualTypeArguments.length == 0) {
+ return;
+ }
+
+ final Object actualTypeArgument = actualTypeArguments[0];
+ if (actualTypeArgument instanceof Class) {
+ final Class<?> actualType = (Class<?>) actualTypeArgument;
+ FacetUtil.addFacet(new TypeOfFacetInferredFromGenerics(actualType, processMethodContext.getFacetHolder(), getSpecificationLoader()));
+ return;
+ }
+
+ if (actualTypeArgument instanceof TypeVariable) {
+
+ // TODO: what to do here?
+ return;
+ }
+
+ }
+
+ @Override
+ public void setCollectionTypeRegistry(final CollectionTypeRegistry collectionTypeRegistry) {
+ this.collectionTypeRegistry = collectionTypeRegistry;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacet.java
new file mode 100644
index 0000000..6c9f1ed
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacet.java
@@ -0,0 +1,40 @@
+/*
+ * 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.core.metamodel.facets.collections.validate;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.interactions.ValidatingInteractionAdvisor;
+
+/**
+ * Validate that an object can be added to a collection.
+ *
+ * <p>
+ * In the standard Apache Isis Programming Model, corresponds to invoking the
+ * <tt>validateAddToXxx</tt> support method for a collection.
+ *
+ */
+public interface CollectionValidateAddToFacet extends Facet, ValidatingInteractionAdvisor {
+
+ /**
+ * Reason the object cannot be added, or <tt>null</tt> if okay.
+ */
+ public String invalidReason(ObjectAdapter target, ObjectAdapter proposedArgument);
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetAbstract.java
new file mode 100644
index 0000000..439c2ea
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetAbstract.java
@@ -0,0 +1,48 @@
+/*
+ * 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.core.metamodel.facets.collections.validate;
+
+import org.apache.isis.applib.events.ValidityEvent;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.interactions.CollectionAddToContext;
+import org.apache.isis.core.metamodel.interactions.ValidityContext;
+
+public abstract class CollectionValidateAddToFacetAbstract extends FacetAbstract implements CollectionValidateAddToFacet {
+
+ public static Class<? extends Facet> type() {
+ return CollectionValidateAddToFacet.class;
+ }
+
+ public CollectionValidateAddToFacetAbstract(final FacetHolder holder) {
+ super(type(), holder, Derivation.NOT_DERIVED);
+ }
+
+ @Override
+ public String invalidates(final ValidityContext<? extends ValidityEvent> context) {
+ if (!(context instanceof CollectionAddToContext)) {
+ return null;
+ }
+ final CollectionAddToContext collectionAddToContext = (CollectionAddToContext) context;
+ return invalidReason(context.getTarget(), collectionAddToContext.getProposed());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetViaMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetViaMethod.java
new file mode 100644
index 0000000..ea35429
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateAddToFacetViaMethod.java
@@ -0,0 +1,74 @@
+/*
+ * 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.core.metamodel.facets.collections.validate;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.util.AdapterInvokeUtils;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+
+public class CollectionValidateAddToFacetViaMethod extends CollectionValidateAddToFacetAbstract implements ImperativeFacet {
+
+ private final Method method;
+
+ public CollectionValidateAddToFacetViaMethod(final Method method, final FacetHolder holder) {
+ super(holder);
+ this.method = method;
+ }
+
+ /**
+ * Returns a singleton list of the {@link Method} provided in the
+ * constructor.
+ */
+ @Override
+ public List<Method> getMethods() {
+ return Collections.singletonList(method);
+ }
+
+ @Override
+ public Intent getIntent(final Method method) {
+ return Intent.CHECK_IF_VALID;
+ }
+
+ @Override
+ public boolean impliesResolve() {
+ return true;
+ }
+
+ @Override
+ public boolean impliesObjectChanged() {
+ return false;
+ }
+
+ @Override
+ public String invalidReason(final ObjectAdapter owningAdapter, final ObjectAdapter proposedAdapter) {
+ return (String) AdapterInvokeUtils.invoke(method, owningAdapter, proposedAdapter);
+ }
+
+ @Override
+ protected String toStringValues() {
+ return "method=" + method;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacet.java
new file mode 100644
index 0000000..1f87423
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacet.java
@@ -0,0 +1,39 @@
+/*
+ * 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.core.metamodel.facets.collections.validate;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.interactions.ValidatingInteractionAdvisor;
+
+/**
+ * Validate that an object can be removed to a collection.
+ *
+ * <p>
+ * In the standard Apache Isis Programming Model, corresponds to invoking the
+ * <tt>validateRemoveFromXxx</tt> support method for a collection.
+ */
+public interface CollectionValidateRemoveFromFacet extends Facet, ValidatingInteractionAdvisor {
+
+ /**
+ * Reason the object cannot be removed, or <tt>null</tt> if okay.
+ */
+ public String invalidReason(ObjectAdapter inObject, ObjectAdapter value);
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetAbstract.java
new file mode 100644
index 0000000..5666d4f
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetAbstract.java
@@ -0,0 +1,47 @@
+/*
+ * 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.core.metamodel.facets.collections.validate;
+
+import org.apache.isis.applib.events.ValidityEvent;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.interactions.CollectionRemoveFromContext;
+import org.apache.isis.core.metamodel.interactions.ValidityContext;
+
+public abstract class CollectionValidateRemoveFromFacetAbstract extends FacetAbstract implements CollectionValidateRemoveFromFacet {
+
+ public static Class<? extends Facet> type() {
+ return CollectionValidateRemoveFromFacet.class;
+ }
+
+ public CollectionValidateRemoveFromFacetAbstract(final FacetHolder holder) {
+ super(type(), holder, Derivation.NOT_DERIVED);
+ }
+
+ @Override
+ public String invalidates(final ValidityContext<? extends ValidityEvent> context) {
+ if (!(context instanceof CollectionRemoveFromContext)) {
+ return null;
+ }
+ final CollectionRemoveFromContext collectionRemoveFromContext = (CollectionRemoveFromContext) context;
+ return invalidReason(context.getTarget(), collectionRemoveFromContext.getProposed());
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetViaMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetViaMethod.java
new file mode 100644
index 0000000..ab94b8f
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/validate/CollectionValidateRemoveFromFacetViaMethod.java
@@ -0,0 +1,74 @@
+/*
+ * 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.core.metamodel.facets.collections.validate;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.util.AdapterInvokeUtils;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.ImperativeFacet;
+
+public class CollectionValidateRemoveFromFacetViaMethod extends CollectionValidateRemoveFromFacetAbstract implements ImperativeFacet {
+
+ private final Method method;
+
+ public CollectionValidateRemoveFromFacetViaMethod(final Method method, final FacetHolder holder) {
+ super(holder);
+ this.method = method;
+ }
+
+ /**
+ * Returns a singleton list of the {@link Method} provided in the
+ * constructor.
+ */
+ @Override
+ public List<Method> getMethods() {
+ return Collections.singletonList(method);
+ }
+
+ @Override
+ public Intent getIntent(final Method method) {
+ return Intent.CHECK_IF_VALID;
+ }
+
+ @Override
+ public boolean impliesResolve() {
+ return true;
+ }
+
+ @Override
+ public boolean impliesObjectChanged() {
+ return false;
+ }
+
+ @Override
+ public String invalidReason(final ObjectAdapter owningAdapter, final ObjectAdapter proposedAdapter) {
+ return (String) AdapterInvokeUtils.invoke(method, owningAdapter, proposedAdapter);
+ }
+
+ @Override
+ protected String toStringValues() {
+ return "method=" + method;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/describedas/DescribedAsFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/describedas/DescribedAsFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/describedas/DescribedAsFacet.java
deleted file mode 100644
index a40f08c..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/describedas/DescribedAsFacet.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.core.metamodel.facets.describedas;
-
-import org.apache.isis.core.metamodel.facets.SingleStringValueFacet;
-
-/**
- * Describes a class, a property, collection, an action or an action parameter.
- *
- * <p>
- * In the standard Apache Isis Programming Model, corresponds to annotating the
- * member with <tt>@DescribedAs</tt>.
- */
-public interface DescribedAsFacet extends SingleStringValueFacet {
-
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/describedas/DescribedAsFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/describedas/DescribedAsFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/describedas/DescribedAsFacetAbstract.java
deleted file mode 100644
index 6080846..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/describedas/DescribedAsFacetAbstract.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.core.metamodel.facets.describedas;
-
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facets.SingleStringValueFacetAbstract;
-
-public abstract class DescribedAsFacetAbstract extends SingleStringValueFacetAbstract implements DescribedAsFacet {
-
- public static Class<? extends Facet> type() {
- return DescribedAsFacet.class;
- }
-
- public DescribedAsFacetAbstract(final String value, final FacetHolder holder) {
- super(type(), holder, value);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ebc/EqualByContentFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ebc/EqualByContentFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ebc/EqualByContentFacet.java
deleted file mode 100644
index 8708cc7..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ebc/EqualByContentFacet.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.core.metamodel.facets.ebc;
-
-import org.apache.isis.core.metamodel.facets.MarkerFacet;
-import org.apache.isis.core.metamodel.facets.object.immutable.ImmutableFacet;
-import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
-
-/**
- * Indicates that the instances of this class are equal-by-content.
- *
- * <p>
- * In the standard Apache Isis Programming Model, typically corresponds to
- * applying the <tt>@EqualByContent</tt> annotation at the class level.
- *
- * @see ImmutableFacet
- * @see ValueFacet
- */
-public interface EqualByContentFacet extends MarkerFacet {
-
-}
http://git-wip-us.apache.org/repos/asf/isis/blob/7227418b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ebc/EqualByContentFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ebc/EqualByContentFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ebc/EqualByContentFacetAbstract.java
deleted file mode 100644
index 5422c4d..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/ebc/EqualByContentFacetAbstract.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.core.metamodel.facets.ebc;
-
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facets.MarkerFacetAbstract;
-
-public abstract class EqualByContentFacetAbstract extends MarkerFacetAbstract implements EqualByContentFacet {
-
- public static Class<? extends Facet> type() {
- return EqualByContentFacet.class;
- }
-
- public EqualByContentFacetAbstract(final FacetHolder holder) {
- super(type(), holder);
- }
-
-}