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 2021/05/05 11:49:03 UTC
[isis] branch master updated: ISIS-2645: MM: make Identifier a
first class citizen of ObjectMember(s)
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 2892201 ISIS-2645: MM: make Identifier a first class citizen of ObjectMember(s)
2892201 is described below
commit 2892201c4cc402f7ad3c9de2c35cb8523a478809
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed May 5 13:48:45 2021 +0200
ISIS-2645: MM: make Identifier a first class citizen of ObjectMember(s)
---
...reteTypeToBeIncludedWithMetamodelValidator.java | 12 +-
.../DeriveMixinMembersPostProcessor.java | 11 +-
.../core/metamodel/spec/ObjectSpecification.java | 72 ++++++------
.../core/metamodel/spec/feature/ObjectMember.java | 7 ++
.../specloader/specimpl/MixedInMember.java | 11 +-
.../specloader/specimpl/ObjectActionDefault.java | 16 ++-
.../specloader/specimpl/ObjectActionMixedIn.java | 42 ++-----
.../specimpl/ObjectAssociationAbstract.java | 4 +-
.../specloader/specimpl/ObjectMemberAbstract.java | 21 ++--
.../specloader/specimpl/ObjectMemberContainer.java | 76 +++++++------
.../specimpl/ObjectSpecificationAbstract.java | 126 ++++++++++-----------
.../specimpl/OneToManyAssociationDefault.java | 16 ++-
.../specimpl/OneToManyAssociationMixedIn.java | 35 ++----
.../specimpl/OneToOneAssociationDefault.java | 13 ++-
.../specimpl/OneToOneAssociationMixedIn.java | 36 ++----
.../{Predicates.java => _SpecPredicates.java} | 2 +-
.../specimpl/dflt/ObjectSpecificationDefault.java | 6 +-
.../objects/ObjectActionLayoutXmlDefaultTest.java | 12 +-
.../objects/OneToManyAssociationDefaultTest.java | 10 +-
.../metamodel/MetaModelServiceDefaultTest.java | 4 +-
.../specimpl/ObjectAssociationAbstractTest.java | 7 +-
...ObjectAssociationAbstractTest_alwaysHidden.java | 11 +-
.../specimpl/OneToOneAssociationAbstractTest.java | 10 +-
.../objectref/ObjectReferenceFieldFactory.java | 16 +--
.../resources/DomainTypeResourceServerside.java | 24 ++--
25 files changed, 287 insertions(+), 313 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationShouldEnforceConcreteTypeToBeIncludedWithMetamodelValidator.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationShouldEnforceConcreteTypeToBeIncludedWithMetamodelValidator.java
index 62fbbfd..cf5aed7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationShouldEnforceConcreteTypeToBeIncludedWithMetamodelValidator.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationShouldEnforceConcreteTypeToBeIncludedWithMetamodelValidator.java
@@ -31,16 +31,16 @@ import org.apache.isis.core.metamodel.specloader.validator.ValidationFailure;
import lombok.NonNull;
import lombok.val;
-public class ActionAnnotationShouldEnforceConcreteTypeToBeIncludedWithMetamodelValidator
+public class ActionAnnotationShouldEnforceConcreteTypeToBeIncludedWithMetamodelValidator
extends MetaModelVisitingValidatorAbstract {
@Override
public void validate(@NonNull ObjectSpecification spec) {
- if(spec.getBeanSort()==BeanSort.UNKNOWN
+ if(spec.getBeanSort()==BeanSort.UNKNOWN
&& !spec.isAbstract()) {
-
- val actions = spec.streamActions(MixedIn.INCLUDED).collect(Collectors.toList());
-
+
+ val actions = spec.streamActions(MixedIn.EXCLUDED).collect(Collectors.toList());
+
final int numActions = actions.size();
if (numActions > 0) {
@@ -56,7 +56,7 @@ extends MetaModelVisitingValidatorAbstract {
numActions,
actionIds);
}
-
+
}
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/DeriveMixinMembersPostProcessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/DeriveMixinMembersPostProcessor.java
index 62fe6bf..12c5d61 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/DeriveMixinMembersPostProcessor.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/DeriveMixinMembersPostProcessor.java
@@ -38,19 +38,20 @@ implements ObjectSpecificationPostProcessor, MetaModelContextAware {
@Override
public void postProcess(final ObjectSpecification objectSpecification) {
- //TODO none of these 3 streams are actually consumed!
-
+ // calling count on these 3 streams so these are actually consumed,
+ // as a side-effect the meta-model gets (further) populated
+
// all the actions of this type
val actionTypes = metaModelContext.getSystemEnvironment().isPrototyping()
? ActionType.USER_AND_PROTOTYPE
: ActionType.USER_ONLY;
- objectSpecification.streamActions(actionTypes, MixedIn.INCLUDED);
+ objectSpecification.streamActions(actionTypes, MixedIn.INCLUDED).count();
// and all the collections of this type
- objectSpecification.streamCollections(MixedIn.INCLUDED);
+ objectSpecification.streamCollections(MixedIn.INCLUDED).count();
// and all the properties of this type
- objectSpecification.streamProperties(MixedIn.INCLUDED);
+ objectSpecification.streamProperties(MixedIn.INCLUDED).count();
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
index f1ecbf6..d2bc4b0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
@@ -81,41 +81,41 @@ import lombok.val;
* first, and then later work out its internals. Hence we create
* {@link ObjectSpecification}s as we need them, and then introspect them later.
*/
-public interface ObjectSpecification
-extends
- Specification,
+public interface ObjectSpecification
+extends
+ Specification,
ObjectActionContainer,
- ObjectAssociationContainer,
- Hierarchical,
+ ObjectAssociationContainer,
+ Hierarchical,
DefaultProvider,
HasLogicalType {
final class Comparators{
private Comparators(){}
- public static final Comparator<ObjectSpecification> FULLY_QUALIFIED_CLASS_NAME =
- (final ObjectSpecification o1, final ObjectSpecification o2) ->
+ public static final Comparator<ObjectSpecification> FULLY_QUALIFIED_CLASS_NAME =
+ (final ObjectSpecification o1, final ObjectSpecification o2) ->
o1.getFullIdentifier().compareTo(o2.getFullIdentifier());
- public static final Comparator<ObjectSpecification> SHORT_IDENTIFIER_IGNORE_CASE =
- (final ObjectSpecification s1, final ObjectSpecification s2) ->
+ public static final Comparator<ObjectSpecification> SHORT_IDENTIFIER_IGNORE_CASE =
+ (final ObjectSpecification s1, final ObjectSpecification s2) ->
s1.getShortIdentifier().compareToIgnoreCase(s2.getShortIdentifier());
}
-
+
/**
* @param memberId
- * @return optionally the ObjectMember associated with given {@code memberId},
+ * @return optionally the ObjectMember associated with given {@code memberId},
* based on whether given memberId exists
*/
Optional<? extends ObjectMember> getMember(String memberId);
-
+
/**
* @param method
- * @return optionally the ObjectMember associated with given {@code method},
+ * @return optionally the ObjectMember associated with given {@code method},
* based on whether such an association exists
*/
Optional<? extends ObjectMember> getMember(Method method);
-
+
default ObjectMember getMemberElseFail(final @NonNull Method method) {
return getMember(method).orElseThrow(()->{
val methodName = method.getName();
@@ -242,7 +242,7 @@ extends
Optional<ObjectSpecification> getElementSpecification();
/**
- *
+ *
* @since 2.0
*/
BeanSort getBeanSort();
@@ -372,16 +372,16 @@ extends
/**
* Whether this specification represents a bean, that is a managed bean
- * with scoped life-cycle, available for dependency injection.
+ * with scoped life-cycle, available for dependency injection.
*/
default boolean isManagedBean() {
return getManagedBeanName()!=null;
}
-
+
/**
* If this specification represents a bean, that is a managed bean, then
* returns the bean's name/id as recognized by the IoC container.
- * <p>Otherwise returns {@code null}.
+ * <p>Otherwise returns {@code null}.
*/
String getManagedBeanName();
@@ -400,6 +400,10 @@ extends
return isViewModel() || isEntity();
}
+ default boolean isEntityOrViewModelOrAbstract() {
+ return isViewModel() || isEntity() || isAbstract();
+ }
+
default boolean isEntity() {
return getBeanSort().isEntity();
}
@@ -425,7 +429,7 @@ extends
throw new UnrecoverableException("Failed to create instance of type " + getFullIdentifier(), e);
}
- return newInstance;
+ return newInstance;
}
/**
@@ -433,7 +437,7 @@ extends
* @since 2.0
*/
default Stream<FacetHolder> streamFacetHolders(){
-
+
val self = Stream.of(this);
val actions = streamActions(MixedIn.EXCLUDED);
val actionParameters = streamActions(MixedIn.EXCLUDED)
@@ -444,7 +448,7 @@ extends
val collections = streamCollections(MixedIn.EXCLUDED);
return _Streams.concat(self, actions, actionParameters, properties, collections);
-
+
}
/**
@@ -455,13 +459,13 @@ extends
/**
* @return whether the corresponding type can be mapped onto a REFERENCE (schema) or an Oid,
- * that is the type is 'identifiable' (aka 'referencable' or 'bookmarkable')
+ * that is the type is 'identifiable' (aka 'referencable' or 'bookmarkable')
* @since 2.0
*/
default boolean isIdentifiable() {
return isManagedBean() || isViewModel() || isEntity();
}
-
+
/**
* Delegates to {@link ObjectManager#createObject(org.apache.isis.core.metamodel.objectmanager.create.ObjectCreator.Request)}
* @since 2.0
@@ -472,16 +476,16 @@ extends
val managedObject = mmc.getObjectManager().createObject(objectCreateRequest);
return managedObject;
}
-
+
// -- TYPE COMPATIBILITY UTILITIES
-
+
default public void assertPojoCompatible(@Nullable Object pojo) {
-
+
// can do this check only when the pojo is not null, otherwise is always considered valid
if(pojo==null) {
return;
}
-
+
if(!isPojoCompatible(pojo)) {
val expectedType = getCorrespondingClass();
throw _Exceptions.illegalArgument(
@@ -492,17 +496,17 @@ extends
expectedType, pojo.getClass(), pojo.toString());
}
}
-
+
default public boolean isPojoCompatible(Object pojo) {
-
+
val expectedType = getCorrespondingClass();
val actualType = pojo.getClass();
-
+
if(expectedType.isAssignableFrom(actualType)
|| ClassExtensions.equalsWhenBoxing(expectedType, actualType)) {
return true;
}
-
+
// XXX rather hard to understand ...
// for non-scalar param types, param-spec is always the element-type spec (not the spec of any container)
val elementSpec = getElementSpecification()
@@ -513,12 +517,12 @@ extends
}
/**
- * @return whether corresponding class implements {@link java.io.Serializable} or
+ * @return whether corresponding class implements {@link java.io.Serializable} or
* {@link java.io.Externalizable}.
- * @apiNote: per se does not tell what recreation strategy to use, the corresponding class
+ * @apiNote: per se does not tell what recreation strategy to use, the corresponding class
* might be an entity or a view-model or a value with eg. encodable semantics, which have
* different object recreation mechanics
- * @since 2.0.0
+ * @since 2.0.0
*/
default boolean isSerializable() {
return
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java
index 89263e7..5fb7b26 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java
@@ -135,6 +135,13 @@ public interface ObjectMember extends ObjectFeature {
*/
boolean isAction();
+ /**
+ * Whether this member originates from a mixin.
+ */
+ default boolean isMixedIn() {
+ return false;
+ }
+
// /////////////////////////////////////////////////////////////
// Debugging
// /////////////////////////////////////////////////////////////
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/MixedInMember.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/MixedInMember.java
index 0d5c7d9..a049c15 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/MixedInMember.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/MixedInMember.java
@@ -18,7 +18,6 @@
*/
package org.apache.isis.core.metamodel.specloader.specimpl;
-import org.apache.isis.applib.annotation.DomainObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
@@ -28,13 +27,13 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
*/
public interface MixedInMember extends ObjectMember {
- /**
- * The id as it was originally {@link DomainObject#mixinMethod()}.
- */
- String getOriginalId();
-
ObjectSpecification getMixinType();
boolean hasMixinAction(ObjectAction objectAction);
+
+ @Override
+ default boolean isMixedIn() {
+ return true;
+ }
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
index 2ff5d1d..530b4e6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
@@ -25,6 +25,7 @@ import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.function.Predicate;
+import org.apache.isis.applib.Identifier;
import org.apache.isis.applib.annotation.SemanticsOf;
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.exceptions.RecoverableException;
@@ -79,15 +80,22 @@ implements ObjectAction {
return type;
}
- // -- fields
+ // -- FACTORY
+
+ public static ObjectActionDefault forMethod(final FacetedMethod facetedMethod) {
+ return new ObjectActionDefault(facetedMethod.getIdentifier(), facetedMethod);
+ }
+
+ // -- FIELDS
private final _Lazy<Can<ObjectActionParameter>> parameters = _Lazy.threadSafe(this::determineParameters);
- // -- constructors
+ // -- CONSTRUCTOR
- public ObjectActionDefault(
+ protected ObjectActionDefault(
+ final Identifier identifier,
final FacetedMethod facetedMethod) {
- super(facetedMethod, FeatureType.ACTION);
+ super(identifier, facetedMethod, FeatureType.ACTION);
}
// -- ReturnType, OnType, Actions (set)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
index 0ff85e2..82ba8de 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionMixedIn.java
@@ -62,15 +62,19 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
@Getter(onMethod = @__(@Override))
private final FacetHolder facetHolder = new FacetHolderImpl();
- private final Identifier identifier;
-
public ObjectActionMixedIn(
final Class<?> mixinType,
final String mixinMethodName,
final ObjectActionDefault mixinAction,
final ObjectSpecification mixedInType) {
- super(mixinAction.getFacetedMethod());
+ super(Identifier.actionIdentifier(
+ LogicalType.eager(
+ mixedInType.getCorrespondingClass(),
+ mixedInType.getLogicalTypeName()),
+ determineIdFrom(mixinAction),
+ mixinAction.getFacetedMethod().getIdentifier().getMemberParameterClassNames()),
+ mixinAction.getFacetedMethod());
this.mixinType = mixinType;
this.mixinAction = mixinAction;
@@ -86,16 +90,6 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
String memberName = determineNameFrom(mixinAction);
this.addFacet(new NamedFacetInferred(memberName, facetHolder));
}
-
- // calculate the identifier
- final Identifier mixinIdentifier = mixinAction.getFacetedMethod().getIdentifier();
- val memberParameterClassNames = mixinIdentifier.getMemberParameterClassNames();
- identifier = Identifier.actionIdentifier(
- LogicalType.eager(
- getOnType().getCorrespondingClass(),
- getOnType().getLogicalTypeName()),
- getId(),
- memberParameterClassNames);
}
@Override
@@ -103,17 +97,8 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
val target = mixinAdapterFor(mixinType, owner);
return InteractionHead.of(owner, target);
}
-
- @Override
- public String getId() {
- return determineIdFrom(this.mixinAction);
- }
@Override
- public String getOriginalId() {
- return super.getId();
- }
-
public boolean hasMixinAction(final ObjectAction mixinAction) {
return this.mixinAction == mixinAction;
}
@@ -164,28 +149,19 @@ public class ObjectActionMixedIn extends ObjectActionDefault implements MixedInM
final ManagedObject owner = head.getOwner();
final ManagedObject target = mixinAdapterFor(mixinType, owner);
- _Assert.assertEquals(target.getSpecification(), head.getTarget().getSpecification(),
+ _Assert.assertEquals(target.getSpecification(), head.getTarget().getSpecification(),
"head has the wrong target (should be a mixin adapter, but is the owner adapter)");
-
+
setupCommand(head.getTarget(), arguments);
return mixinAction.executeInternal(
head, arguments,
interactionInitiatedBy);
}
- /* (non-Javadoc)
- * @see ObjectMemberAbstract#getIdentifier()
- */
- @Override
- public Identifier getIdentifier() {
- return identifier;
- }
-
@Override
public ObjectSpecification getMixinType() {
return getSpecificationLoader().loadSpecification(mixinType);
}
-
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstract.java
index 1cd629f..cae288c 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstract.java
@@ -19,6 +19,7 @@
package org.apache.isis.core.metamodel.specloader.specimpl;
+import org.apache.isis.applib.Identifier;
import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
@@ -38,11 +39,12 @@ implements ObjectAssociation {
private final ObjectSpecification specification;
public ObjectAssociationAbstract(
+ final Identifier identifier,
final FacetedMethod facetedMethod,
final FeatureType featureType,
final ObjectSpecification specification) {
- super(facetedMethod, featureType);
+ super(identifier, facetedMethod, featureType);
if (specification == null) {
throw new IllegalArgumentException("field type for '" + getId() + "' must exist");
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
index 9fd36d3..a067243 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
@@ -67,33 +67,34 @@ implements ObjectMember, HasMetaModelContext, HasFacetHolder {
}
// -- fields
- private final String id;
+
+ private final Identifier identifier;
private final FacetedMethod facetedMethod;
private final FeatureType featureType;
protected ObjectMemberAbstract(
+ final Identifier identifier,
final FacetedMethod facetedMethod,
final FeatureType featureType) {
- final String id = facetedMethod.getIdentifier().getMemberName();
- if (id == null) {
- throw new IllegalArgumentException("Id must always be set");
- }
+ this.identifier = identifier;
this.facetedMethod = facetedMethod;
this.featureType = featureType;
- this.id = id;
+ if (getId() == null) {
+ throw new IllegalArgumentException("Id must always be set");
+ }
}
// -- Identifiers
@Override
- public String getId() {
- return id;
+ public final String getId() {
+ return getIdentifier().getMemberName();
}
@Override
- public Identifier getIdentifier() {
- return getFacetedMethod().getIdentifier();
+ public final Identifier getIdentifier() {
+ return identifier;
}
@Override
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberContainer.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberContainer.java
index 163de52..6ceb7db 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberContainer.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberContainer.java
@@ -38,64 +38,70 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationContainer;
import lombok.val;
/**
- * Responsibility: member lookup and streaming with support for inheritance,
+ * Responsibility: member lookup and streaming with support for inheritance,
* based on access to declared members, super-classes and interfaces.
* <p>
* TODO performance: add memoization
* <p>
- * TODO future extensions should also search the interfaces,
+ * TODO future extensions should also search the interfaces,
* but avoid doing redundant work when walking the type-hierarchy;
* (current elegant recursive solution will then need some tweaks to be efficient)
*/
public abstract class ObjectMemberContainer
-extends FacetHolderImpl
-implements
+extends FacetHolderImpl
+implements
ObjectActionContainer,
- ObjectAssociationContainer,
+ ObjectAssociationContainer,
Hierarchical {
// -- ACTIONS
-
+
@Override
public Optional<ObjectAction> getAction(String id, @Nullable ActionType type) {
val declaredAction = getDeclaredAction(id); // no inheritance nor type considered
-
+
if(declaredAction.isPresent()) {
// action found but if its not the right type, stop searching
if(type!=null
&& declaredAction.get().getType() != type) {
return Optional.empty();
}
- return declaredAction;
+ return declaredAction;
}
return isTypeHierarchyRoot()
? Optional.empty() // stop searching
: superclass().getAction(id, type);
}
-
+
@Override
public Stream<ObjectAction> streamActions(
- final ImmutableEnumSet<ActionType> types,
- final MixedIn contributed,
+ final ImmutableEnumSet<ActionType> actionTypes,
+ final MixedIn mixedIn,
final Consumer<ObjectAction> onActionOverloaded) {
-
+
val actionStream = isTypeHierarchyRoot()
- ? streamDeclaredActions(types, contributed) // stop going deeper
+ ? streamDeclaredActions(actionTypes, mixedIn) // stop going deeper
: Stream.concat(
- streamDeclaredActions(types, contributed),
- superclass().streamActions(types, contributed));
-
+ streamDeclaredActions(actionTypes, mixedIn),
+ superclass().streamActions(actionTypes, mixedIn));
+
val actionSignatures = _Sets.<String>newHashSet();
val actionIds = _Sets.<String>newHashSet();
-
+
return actionStream
-
- // as of contributing super-classes same actions might appear more than once (overriding)
- .filter(action->actionSignatures.add(
- action.getIdentifier().getMemberNameAndParameterClassNamesIdentityString()))
-
+
+ // as of contributing super-classes same actions might appear more than once (overriding)
+ .filter(action->{
+ if(action.isMixedIn()) {
+ return true; // do not filter mixedIn actions based on signature
+ }
+ val isUnique = actionSignatures
+ .add(action.getIdentifier().getMemberNameAndParameterClassNamesIdentityString());
+ return isUnique;
+ })
+
// ensure we don't emit duplicates
.filter(action->{
val isUnique = actionIds.add(action.getId());
@@ -103,39 +109,39 @@ implements
onActionOverloaded.accept(action);
}
return isUnique;
- });
+ });
}
-
+
// -- ASSOCIATIONS
-
+
@Override
public Optional<ObjectAssociation> getAssociation(String id) {
val declaredAssociation = getDeclaredAssociation(id); // no inheritance considered
-
+
if(declaredAssociation.isPresent()) {
- return declaredAssociation;
+ return declaredAssociation;
}
-
+
return isTypeHierarchyRoot()
- ? Optional.empty() // stop searching
+ ? Optional.empty() // stop searching
: superclass().getAssociation(id);
}
-
+
@Override
public Stream<ObjectAssociation> streamAssociations(MixedIn contributed) {
-
+
if(isTypeHierarchyRoot()) {
return streamDeclaredAssociations(contributed); // stop going deeper
}
-
+
val ids = _Sets.<String>newHashSet();
-
+
return Stream.concat(
- streamDeclaredAssociations(contributed),
+ streamDeclaredAssociations(contributed),
superclass().streamAssociations(contributed)
)
.filter(association->ids.add(association.getId())); // ensure we don't emit duplicates
}
-
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
index e297e11..455cd8f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
@@ -89,23 +89,23 @@ import lombok.extern.log4j.Log4j2;
@EqualsAndHashCode(of = "correspondingClass", callSuper = false)
@lombok.ToString(of = {"correspondingClass", "fullName", "beanSort"})
-@Log4j2
-public abstract class ObjectSpecificationAbstract
+@Log4j2
+public abstract class ObjectSpecificationAbstract
extends ObjectMemberContainer
implements ObjectSpecification {
- /**
+ /**
* @implNote thread-safe
*/
private static class Subclasses {
-
+
// List performs better compared to a Set, when the number of elements is low
private Can<ObjectSpecification> classes = Can.empty();
private final Object $lock = new Object();
public void addSubclass(final ObjectSpecification subclass) {
synchronized($lock) {
- classes = classes.addUnique(subclass);
+ classes = classes.addUnique(subclass);
}
}
@@ -121,48 +121,48 @@ implements ObjectSpecification {
}
}
}
-
-
+
+
// -- FIELDS
private final PostProcessor postProcessor;
private final FacetProcessor facetProcessor;
-
+
@Getter private final BeanSort beanSort;
// -- ASSOCIATIONS
-
+
private final List<ObjectAssociation> associations = _Lists.newArrayList();
-
+
// defensive immutable lazy copy of associations
- private final _Lazy<Can<ObjectAssociation>> unmodifiableAssociations =
+ private final _Lazy<Can<ObjectAssociation>> unmodifiableAssociations =
_Lazy.threadSafe(()->Can.ofCollection(associations));
-
+
// -- ACTIONS
-
+
private final List<ObjectAction> objectActions = _Lists.newArrayList();
-
+
/** not API, used for validation */
@Getter private final Set<Method> potentialOrphans = _Sets.newHashSet();
// defensive immutable lazy copy of objectActions
- private final _Lazy<Can<ObjectAction>> unmodifiableActions =
+ private final _Lazy<Can<ObjectAction>> unmodifiableActions =
_Lazy.threadSafe(()->Can.ofCollection(objectActions));
// partitions and caches objectActions by type; updated in sortCacheAndUpdateActions()
- private final ListMultimap<ActionType, ObjectAction> objectActionsByType =
+ private final ListMultimap<ActionType, ObjectAction> objectActionsByType =
_Multimaps.newConcurrentListMultimap();
-
+
// -- INTERFACES
private final List<ObjectSpecification> interfaces = _Lists.newArrayList();
-
+
// defensive immutable lazy copy of interfaces
- private final _Lazy<Can<ObjectSpecification>> unmodifiableInterfaces =
+ private final _Lazy<Can<ObjectSpecification>> unmodifiableInterfaces =
_Lazy.threadSafe(()->Can.ofCollection(interfaces));
-
-
-
+
+
+
private final Subclasses directSubclasses = new Subclasses();
// built lazily
private Subclasses transitiveSubclasses;
@@ -220,7 +220,7 @@ implements ObjectSpecification {
public LogicalType getLogicalType() {
return logicalTypeLazy.get();
}
-
+
private LogicalType lookupLogicalType() {
val objectSpecIdFacet = getFacet(ObjectSpecIdFacet.class);
if(objectSpecIdFacet == null) {
@@ -257,7 +257,7 @@ implements ObjectSpecification {
@Override
public void introspectUpTo(final IntrospectionState upTo) {
-
+
if(!isLessThan(upTo)) {
return; // optimization
}
@@ -315,7 +315,7 @@ implements ObjectSpecification {
boolean isLessThan(IntrospectionState upTo) {
return this.introspectionState.compareTo(upTo) < 0;
}
-
+
protected abstract void introspectTypeHierarchy();
protected abstract void introspectMembers();
@@ -406,7 +406,7 @@ implements ObjectSpecification {
public String getTitle(
final ManagedObject contextAdapterIfAny,
final ManagedObject targetAdapter) {
-
+
if (titleFacet != null) {
val titleString = titleFacet.title(contextAdapterIfAny, targetAdapter);
if (!_Strings.isEmpty(titleString)) {
@@ -435,7 +435,7 @@ implements ObjectSpecification {
}
// -- HIERARCHICAL
-
+
/**
* Determines if this class represents the same class, or a subclass, of the
* specified class.
@@ -459,15 +459,15 @@ implements ObjectSpecification {
*/
@Override
public boolean isOfType(final ObjectSpecification other) {
-
+
val thisClass = this.getCorrespondingClass();
val otherClass = other.getCorrespondingClass();
-
- return thisClass == otherClass
+
+ return thisClass == otherClass
|| otherClass.isAssignableFrom(thisClass);
-
-//XXX legacy of ...
-//
+
+//XXX legacy of ...
+//
// for (val interfaceSpec : interfaces()) {
// if (interfaceSpec.isOfType(other)) {
// return true;
@@ -489,7 +489,7 @@ implements ObjectSpecification {
}
// -- NAME, DESCRIPTION, PERSISTABILITY
-
+
/**
* The name according to any available {@link NamedFacet},
* but falling back to {@link #getFullIdentifier()} otherwise.
@@ -538,28 +538,28 @@ implements ObjectSpecification {
public <Q extends Facet> Q getFacet(final Class<Q> facetType) {
synchronized(unmodifiableInterfaces) {
-
+
// lookup facet holder's facet
val facets1 = _NullSafe.streamNullable(super.getFacet(facetType));
-
+
// lookup all interfaces
val facets2 = _NullSafe.stream(interfaces())
.filter(_NullSafe::isPresent) // just in case
.map(interfaceSpec->interfaceSpec.getFacet(facetType));
-
+
// search up the inheritance hierarchy
- val facets3 = _NullSafe.streamNullable(superclass())
+ val facets3 = _NullSafe.streamNullable(superclass())
.map(superSpec->superSpec.getFacet(facetType));
-
+
val facetsCombined = _Streams.concat(facets1, facets2, facets3);
val notANoopFacetFilter = new NotANoopFacetFilter<Q>();
-
+
return facetsCombined
.filter(notANoopFacetFilter)
.findFirst()
.orElse(notANoopFacetFilter.noopFacet);
-
+
}
}
@@ -601,7 +601,7 @@ implements ObjectSpecification {
@Override
public ObjectTitleContext createTitleInteractionContext(
- final ManagedObject targetObjectAdapter,
+ final ManagedObject targetObjectAdapter,
final InteractionInitiatedBy interactionMethod) {
return new ObjectTitleContext(targetObjectAdapter, getIdentifier(), targetObjectAdapter.titleString(null),
@@ -609,7 +609,7 @@ implements ObjectSpecification {
}
// -- SUPERCLASS, INTERFACES, SUBCLASSES, IS-ABSTRACT
-
+
@Override
public ObjectSpecification superclass() {
return superclassSpec;
@@ -675,12 +675,12 @@ implements ObjectSpecification {
return stream(unmodifiableAssociations.get());
}
}
-
+
synchronized(unmodifiableAssociations) {
return stream(unmodifiableAssociations.get())
- .filter(MixedIn::isNotMixedIn);
+ .filter(MixedIn::isNotMixedIn);
}
-
+
}
@Override
@@ -710,23 +710,23 @@ implements ObjectSpecification {
.filter(objectAssociation->objectAssociation.getId().equals(id))
.findFirst();
}
-
+
@Override
public Stream<ObjectAction> streamDeclaredActions(
- final ImmutableEnumSet<ActionType> types,
- final MixedIn contributed) {
+ final ImmutableEnumSet<ActionType> actionTypes,
+ final MixedIn mixedIn) {
introspectUpTo(IntrospectionState.FULLY_INTROSPECTED);
- if(contributed.isIncluded()) { // conditional not strictly required, could instead always go this code path
+ if(mixedIn.isIncluded()) { // conditional not strictly required, could instead always go this code path
createMixedInActions(); // only if not already
}
-
- return types.stream()
- .flatMap(type->stream(objectActionsByType.get(type)))
- .filter(contributed.isIncluded()
- ? _Predicates.alwaysTrue()
+
+ return actionTypes.stream()
+ .flatMap(actionType->stream(objectActionsByType.get(actionType)))
+ .filter(mixedIn.isIncluded()
+ ? _Predicates.alwaysTrue()
: MixedIn::isNotMixedIn);
}
@@ -746,7 +746,7 @@ implements ObjectSpecification {
}
private void forEachMixedInAssociation(
- final Class<?> mixinType,
+ final Class<?> mixinType,
final Consumer<ObjectAssociation> onNewMixedInAssociation) {
val specification = getSpecificationLoader().loadSpecification(mixinType,
@@ -765,7 +765,7 @@ implements ObjectSpecification {
val mixinMethodName = mixinFacet.value();
specification.streamActions(ActionType.ANY, MixedIn.INCLUDED)
- .filter(Predicates::isMixedInAssociation)
+ .filter(_SpecPredicates::isMixedInAssociation)
.map(ObjectActionDefault.class::cast)
.map(Factories.mixedInAssociation(this, mixinType, mixinMethodName))
.peek(facetProcessor::processMemberOrder)
@@ -817,7 +817,7 @@ implements ObjectSpecification {
val mixinMethodName = mixinFacet.value();
mixinSpec.streamActions(ActionType.ANY, MixedIn.INCLUDED)
- .filter(Predicates::isMixedInAction)
+ .filter(_SpecPredicates::isMixedInAction)
.map(ObjectActionDefault.class::cast)
.map(Factories.mixedInAction(this, mixinType, mixinMethodName))
.peek(facetProcessor::processMemberOrder)
@@ -826,12 +826,12 @@ implements ObjectSpecification {
}
// -- VALIDITY
-
+
@Override
public Consent isValid(
- final ManagedObject targetAdapter,
+ final ManagedObject targetAdapter,
final InteractionInitiatedBy interactionInitiatedBy) {
-
+
return isValidResult(targetAdapter, interactionInitiatedBy).createConsent();
}
@@ -894,7 +894,7 @@ implements ObjectSpecification {
synchronized (unmodifiableActions) {
if(!contributeeAndMixedInActionsAdded) {
val actions = _Lists.newArrayList(this.objectActions);
- if (isEntityOrViewModel()) {
+ if (isEntityOrViewModelOrAbstract()) {
createMixedInActions(actions::add);
}
sortCacheAndUpdateActions(actions);
@@ -909,7 +909,7 @@ implements ObjectSpecification {
synchronized (unmodifiableAssociations) {
if(!contributeeAndMixedInAssociationsAdded) {
val associations = _Lists.newArrayList(this.associations);
- if(isEntityOrViewModel()) {
+ if(isEntityOrViewModelOrAbstract()) {
createMixedInAssociations(associations::add);
}
sortAndUpdateAssociations(associations);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java
index 7e41355..d40a6bf 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationDefault.java
@@ -19,6 +19,7 @@
package org.apache.isis.core.metamodel.specloader.specimpl;
+import org.apache.isis.applib.Identifier;
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.core.metamodel.commons.ToString;
@@ -42,16 +43,19 @@ import lombok.val;
public class OneToManyAssociationDefault
extends ObjectAssociationAbstract implements OneToManyAssociation {
- public OneToManyAssociationDefault(final FacetedMethod facetedMethod) {
- this(facetedMethod, facetedMethod.getMetaModelContext()
- .getSpecificationLoader().loadSpecification(facetedMethod.getType()));
+ public static OneToManyAssociationDefault forMethod(final FacetedMethod facetedMethod) {
+ return new OneToManyAssociationDefault(
+ facetedMethod.getIdentifier(),
+ facetedMethod,
+ facetedMethod.getMetaModelContext().getSpecificationLoader()
+ .loadSpecification(facetedMethod.getType()));
}
protected OneToManyAssociationDefault(
+ final Identifier identifier,
final FacetedMethod facetedMethod,
final ObjectSpecification objectSpec) {
-
- super(facetedMethod, FeatureType.COLLECTION, objectSpec);
+ super(identifier, facetedMethod, FeatureType.COLLECTION, objectSpec);
}
@Override
@@ -106,7 +110,7 @@ extends ObjectAssociationAbstract implements OneToManyAssociation {
@Override
public boolean isEmpty(
- final ManagedObject parentAdapter,
+ final ManagedObject parentAdapter,
final InteractionInitiatedBy interactionInitiatedBy) {
// REVIEW should we be able to determine if a collection is empty
// without loading it?
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
index 5e8cfca..41770cc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToManyAssociationMixedIn.java
@@ -68,8 +68,6 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
@Getter(onMethod = @__(@Override))
private final FacetHolder facetHolder = new FacetHolderImpl();
- private final Identifier identifier;
-
private static ObjectSpecification typeOfSpec(
final ObjectActionDefault objectAction) {
@@ -90,7 +88,13 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
final Class<?> mixinType,
final String mixinMethodName) {
- super(mixinAction.getFacetedMethod(), typeOfSpec(mixinAction));
+ super(Identifier.actionIdentifier(
+ LogicalType.eager(
+ mixeeSpec.getCorrespondingClass(),
+ mixeeSpec.getLogicalTypeName()),
+ determineIdFrom(mixinAction),
+ mixinAction.getFacetedMethod().getIdentifier().getMemberParameterClassNames()),
+ mixinAction.getFacetedMethod(), typeOfSpec(mixinAction));
this.mixinType = mixinType;
this.mixinAction = mixinAction;
@@ -124,16 +128,6 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
FacetUtil.addFacet(new NamedFacetInferred(memberName, facetHolder));
}
- // calculate the identifier
- final Identifier mixinIdentifier = mixinAction.getFacetedMethod().getIdentifier();
- val memberParameterNames = mixinIdentifier.getMemberParameterClassNames();
-
- identifier = Identifier.actionIdentifier(
- LogicalType.eager(
- mixeeSpec.getCorrespondingClass(),
- mixeeSpec.getLogicalTypeName()),
- getId(),
- memberParameterNames);
}
@Override
@@ -163,21 +157,6 @@ public class OneToManyAssociationMixedIn extends OneToManyAssociationDefault imp
}
@Override
- public Identifier getIdentifier() {
- return identifier;
- }
-
- @Override
- public String getId() {
- return determineIdFrom(this.mixinAction);
- }
-
- @Override
- public String getOriginalId() {
- return super.getId();
- }
-
- @Override
public ObjectSpecification getOnType() {
return mixeeSpec;
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
index 4322cb6..4265e14 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
@@ -19,6 +19,7 @@
package org.apache.isis.core.metamodel.specloader.specimpl;
+import org.apache.isis.applib.Identifier;
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.services.command.Command;
import org.apache.isis.commons.collections.Can;
@@ -57,16 +58,20 @@ public class OneToOneAssociationDefault
extends ObjectAssociationAbstract
implements OneToOneAssociation {
- public OneToOneAssociationDefault(final FacetedMethod facetedMethod) {
- this(facetedMethod, facetedMethod.getMetaModelContext()
- .getSpecificationLoader().loadSpecification(facetedMethod.getType()));
+ public static OneToOneAssociationDefault forMethod(final FacetedMethod facetedMethod) {
+ return new OneToOneAssociationDefault(
+ facetedMethod.getIdentifier(),
+ facetedMethod,
+ facetedMethod.getMetaModelContext().getSpecificationLoader()
+ .loadSpecification(facetedMethod.getType()));
}
protected OneToOneAssociationDefault(
+ final Identifier identifier,
final FacetedMethod facetedMethod,
final ObjectSpecification objectSpec) {
- super(facetedMethod, FeatureType.PROPERTY, objectSpec);
+ super(identifier, facetedMethod, FeatureType.PROPERTY, objectSpec);
}
// -- visible, usable
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
index 6c591a0..317983b 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationMixedIn.java
@@ -64,15 +64,19 @@ public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault imple
@Getter(onMethod = @__(@Override))
private final FacetHolder facetHolder = new FacetHolderImpl();
- private final Identifier identifier;
-
public OneToOneAssociationMixedIn(
final ObjectActionDefault mixinAction,
final ObjectSpecification mixeeSpec,
final Class<?> mixinType,
final String mixinMethodName) {
- super(mixinAction.getFacetedMethod(), mixinAction.getReturnType());
+ super(Identifier.actionIdentifier(
+ LogicalType.eager(
+ mixeeSpec.getCorrespondingClass(),
+ mixeeSpec.getLogicalTypeName()),
+ determineIdFrom(mixinAction),
+ mixinAction.getFacetedMethod().getIdentifier().getMemberParameterClassNames()),
+ mixinAction.getFacetedMethod(), mixinAction.getReturnType());
this.mixinType = mixinType;
this.mixinAction = mixinAction;
@@ -103,17 +107,6 @@ public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault imple
FacetUtil.addFacet(new NamedFacetInferred(memberName, facetHolder));
}
-
- // calculate the identifier
- final Identifier mixinIdentifier = mixinAction.getFacetedMethod().getIdentifier();
- val memberParameterClassNames = mixinIdentifier.getMemberParameterClassNames();
-
- identifier = Identifier.actionIdentifier(
- LogicalType.eager(
- mixeeSpec.getCorrespondingClass(),
- mixeeSpec.getLogicalTypeName()),
- getId(),
- memberParameterClassNames);
}
@Override
@@ -145,21 +138,6 @@ public class OneToOneAssociationMixedIn extends OneToOneAssociationDefault imple
}
@Override
- public Identifier getIdentifier() {
- return identifier;
- }
-
- @Override
- public String getId() {
- return determineIdFrom(this.mixinAction);
- }
-
- @Override
- public String getOriginalId() {
- return super.getId();
- }
-
- @Override
public ObjectSpecification getOnType() {
return mixeeSpec;
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/Predicates.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/_SpecPredicates.java
similarity index 98%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/Predicates.java
rename to core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/_SpecPredicates.java
index a74443b..15ee2a0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/Predicates.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/_SpecPredicates.java
@@ -27,7 +27,7 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import lombok.val;
/** package private utility */
-final class Predicates {
+final class _SpecPredicates {
// -- LOWER LEVEL
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
index e3151ff..5459595 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
@@ -216,9 +216,9 @@ implements FacetHolder {
private ObjectAssociation createAssociation(final FacetedMethod facetMethod) {
if (facetMethod.getFeatureType().isCollection()) {
- return new OneToManyAssociationDefault(facetMethod);
+ return OneToManyAssociationDefault.forMethod(facetMethod);
} else if (facetMethod.getFeatureType().isProperty()) {
- return new OneToOneAssociationDefault(facetMethod);
+ return OneToOneAssociationDefault.forMethod(facetMethod);
} else {
return null;
}
@@ -239,7 +239,7 @@ implements FacetHolder {
private ObjectAction createAction(final FacetedMethod facetedMethod) {
if (facetedMethod.getFeatureType().isAction()) {
- return new ObjectActionDefault(facetedMethod);
+ return ObjectActionDefault.forMethod(facetedMethod);
} else {
return null;
}
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/ObjectActionLayoutXmlDefaultTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/ObjectActionLayoutXmlDefaultTest.java
index f3af061..7dd7374 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/ObjectActionLayoutXmlDefaultTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/ObjectActionLayoutXmlDefaultTest.java
@@ -24,6 +24,11 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+
import org.apache.isis.applib.Identifier;
import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2.Mode;
@@ -37,11 +42,6 @@ import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionDefault;
import org.apache.isis.core.security.authentication.AuthenticationContext;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertEquals;
-
public class ObjectActionLayoutXmlDefaultTest {
@Rule public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
@@ -70,7 +70,7 @@ public class ObjectActionLayoutXmlDefaultTest {
}
});
- action = new ObjectActionDefault(mockFacetedMethod);
+ action = ObjectActionDefault.forMethod(mockFacetedMethod);
}
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java
index a1ca135..966a6db 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/objects/OneToManyAssociationDefaultTest.java
@@ -25,6 +25,10 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
import org.apache.isis.applib.Identifier;
import org.apache.isis.applib.services.message.MessageService;
import org.apache.isis.core.internaltestsupport.jmocking.JUnitRuleMockery2;
@@ -40,10 +44,6 @@ import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.core.metamodel.specloader.specimpl.OneToManyAssociationDefault;
import org.apache.isis.core.security.authentication.AuthenticationContext;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
-
public class OneToManyAssociationDefaultTest {
private static final String COLLECTION_ID = "orders";
@@ -80,7 +80,7 @@ public class OneToManyAssociationDefaultTest {
allowingPeerToReturnCollectionType();
allowingPeerToReturnIdentifier();
allowingSpecLoaderToReturnSpecs();
- association = new OneToManyAssociationDefault(mockPeer);
+ association = OneToManyAssociationDefault.forMethod(mockPeer);
}
private void allowingSpecLoaderToReturnSpecs() {
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefaultTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefaultTest.java
index 3bd3cc8..23d144b 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefaultTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefaultTest.java
@@ -105,7 +105,7 @@ class MetaModelServiceDefaultTest {
}
});
- action = new ObjectActionDefault(mockFacetedMethod);
+ action = ObjectActionDefault.forMethod(mockFacetedMethod);
mockMetaModelService = context.mock(MetaModelServiceDefault.class);
context.checking(new Expectations() {
@@ -160,7 +160,7 @@ class MetaModelServiceDefaultTest {
private OutputStream noopOutput(){
return new OutputStream() {
@Override public void write(int b) throws IOException {}
- };
+ };
}
@XmlRootElement(name = "employee")
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstractTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstractTest.java
index 6bf2dd4..b075037 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstractTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstractTest.java
@@ -25,6 +25,9 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.services.inject.ServiceInjector;
import org.apache.isis.commons.collections.Can;
@@ -42,9 +45,6 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
public class ObjectAssociationAbstractTest {
@Rule
@@ -78,6 +78,7 @@ public class ObjectAssociationAbstractTest {
}});
objectAssociation = new ObjectAssociationAbstract(
+ facetedMethod.getIdentifier(),
facetedMethod, FeatureType.PROPERTY, objectSpecification) {
@Override
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstractTest_alwaysHidden.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstractTest_alwaysHidden.java
index c79c609..f116e5d 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstractTest_alwaysHidden.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectAssociationAbstractTest_alwaysHidden.java
@@ -25,6 +25,11 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.services.inject.ServiceInjector;
import org.apache.isis.commons.collections.Can;
@@ -43,11 +48,6 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
public class ObjectAssociationAbstractTest_alwaysHidden {
@Rule
@@ -80,6 +80,7 @@ public class ObjectAssociationAbstractTest_alwaysHidden {
}});
objectAssociation = new ObjectAssociationAbstract(
+ facetedMethod.getIdentifier(),
facetedMethod, FeatureType.PROPERTY, mockObjectSpecification) {
@Override
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationAbstractTest.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationAbstractTest.java
index 718cf5c..00bf181 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationAbstractTest.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationAbstractTest.java
@@ -25,6 +25,9 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import org.apache.isis.applib.annotation.Where;
import org.apache.isis.applib.services.inject.ServiceInjector;
import org.apache.isis.commons.collections.Can;
@@ -41,9 +44,6 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
public class OneToOneAssociationAbstractTest {
@Rule
@@ -76,7 +76,9 @@ public class OneToOneAssociationAbstractTest {
// will(returnValue(mockPersistenceSessionServiceInternal));
}});
- objectAssociation = new OneToOneAssociationDefault(facetedMethod, objectSpecification) {
+ objectAssociation = new OneToOneAssociationDefault(
+ facetedMethod.getIdentifier(),
+ facetedMethod, objectSpecification) {
@Override
public ManagedObject get(
diff --git a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/objectref/ObjectReferenceFieldFactory.java b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/objectref/ObjectReferenceFieldFactory.java
index 989f7de..60927c5 100644
--- a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/objectref/ObjectReferenceFieldFactory.java
+++ b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/objectref/ObjectReferenceFieldFactory.java
@@ -42,7 +42,7 @@ public class ObjectReferenceFieldFactory implements UiComponentHandlerFx {
@Override
public boolean isHandling(ComponentRequest request) {
//return request.hasFeatureFacet(StringValueFacet.class);
- return request.getFeatureTypeSpec().isEntityOrViewModel()
+ return request.getFeatureTypeSpec().isEntityOrViewModelOrAbstract()
|| request.getFeatureType().isEnum();
}
@@ -57,19 +57,19 @@ public class ObjectReferenceFieldFactory implements UiComponentHandlerFx {
// .orElse("");
val uiComponent = new Label(request.getManagedFeature().getIdentifier().toString());
-
+
if(request.getManagedFeature() instanceof ManagedParameter) {
-
+
val managedParameter = (ManagedParameter)request.getManagedFeature();
-
+
// uiComponent.textProperty().
-//
+//
// managedParameter.validate(proposedValue)
-
+
//TODO bind to parameter model
-
+
} else if(request.getManagedFeature() instanceof ManagedProperty) {
-
+
val managedProperty = (ManagedProperty)request.getManagedFeature();
//TODO bind to property model
}
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
index 38e0834..d274727 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/resources/DomainTypeResourceServerside.java
@@ -94,9 +94,9 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
RepresentationType.TYPE_LIST, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
val domainTypeSpecifications = getSpecificationLoader().snapshotSpecifications()
- .filter(spec->spec.isEntityOrViewModel());
+ .filter(spec->spec.isEntityOrViewModel()); // concrete types only, no abstract types
- final TypeListReprRenderer renderer =
+ final TypeListReprRenderer renderer =
new TypeListReprRenderer(resourceContext, null, JsonRepresentation.newMap());
renderer.with(domainTypeSpecifications).includesSelf();
@@ -131,13 +131,13 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
val resourceContext = createResourceContext(
RepresentationType.LAYOUT, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
-
+
val serializationStrategy = resourceContext.getSerializationStrategy();
val gridFacet = getSpecificationLoader().specForLogicalTypeName(domainType)
.map(spec->spec.getFacet(GridFacet.class))
.orElse(null);
-
+
final Response.ResponseBuilder builder;
if(gridFacet == null) {
builder = Responses.ofNotFound();
@@ -167,7 +167,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
val objectMember = parentSpec.getAssociation(propertyId)
.orElseThrow(()->RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
-
+
if (objectMember.isOneToManyAssociation()) {
throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND);
}
@@ -184,7 +184,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
@Path("/{domainType}/collections/{collectionId}")
@Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_COLLECTION_DESCRIPTION })
public Response typeCollection(@PathParam("domainType") final String domainType, @PathParam("collectionId") final String collectionId) {
-
+
val resourceContext = createResourceContext(
RepresentationType.COLLECTION_DESCRIPTION, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -195,7 +195,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
val objectMember = parentSpec.getAssociation(collectionId)
.orElseThrow(()->RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
-
+
if (objectMember.isOneToOneAssociation()) {
throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND);
}
@@ -212,7 +212,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
@Path("/{domainType}/actions/{actionId}")
@Produces({ MediaType.APPLICATION_JSON, RestfulMediaType.APPLICATION_JSON_ACTION_DESCRIPTION })
public Response typeAction(@PathParam("domainType") final String domainType, @PathParam("actionId") final String actionId) {
-
+
val resourceContext = createResourceContext(
RepresentationType.ACTION_DESCRIPTION, Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE);
@@ -223,7 +223,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
val action = parentSpec.getAction(actionId)
.orElseThrow(()->RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
-
+
final ActionDescriptionReprRenderer renderer = new ActionDescriptionReprRenderer(resourceContext, null, JsonRepresentation.newMap());
renderer.with(new ParentSpecAndAction(parentSpec, action)).includesSelf();
@@ -246,7 +246,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
val parentAction = parentSpec.getAction(actionId)
.orElseThrow(()->RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND));
-
+
final ObjectActionParameter actionParam = parentAction.getParameterByName(paramName);
final ActionParameterDescriptionReprRenderer renderer = new ActionParameterDescriptionReprRenderer(resourceContext, null, JsonRepresentation.newMap());
@@ -268,7 +268,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
@QueryParam("supertype") final String superTypeStr, // simple style
@QueryParam("args") final String argsUrlEncoded // formal style
) {
-
+
val resourceContext = createResourceContext(
ResourceDescriptor.generic(Where.ANYWHERE, RepresentationService.Intent.NOT_APPLICABLE));
@@ -280,7 +280,7 @@ public class DomainTypeResourceServerside extends ResourceAbstract implements Do
|| supertypeSpec == null) {
throw RestfulObjectsApplicationException.create(HttpStatusCode.NOT_FOUND);
}
-
+
final TypeActionResultReprRenderer renderer = new TypeActionResultReprRenderer(resourceContext, null, JsonRepresentation.newMap());
final String url = "domain-types/" + domainType + "/type-actions/isSubtypeOf/invoke";