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 2013/10/07 10:56:14 UTC

git commit: ISIS-543: title() take precedence over @Title

Updated Branches:
  refs/heads/master c1e5ab7da -> 7c96689cd


ISIS-543: title() take precedence over @Title

If a class has both a title() and (non-inherited) methods annotated with @Title,
then this is a metamodel violation.

Patch contributed by: Othmen Tiliouine <ti...@gmail.com>

Signed-off-by: Dan Haywood <da...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/7c96689c
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/7c96689c
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/7c96689c

Branch: refs/heads/master
Commit: 7c96689cda4afa0cd3f206909872bc2d032a4b2e
Parents: c1e5ab7
Author: Dan Haywood <da...@apache.org>
Authored: Mon Oct 7 09:55:53 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Mon Oct 7 09:55:53 2013 +0100

----------------------------------------------------------------------
 .../object/title/TitleMethodFacetFactory.java   | 13 ++---
 .../annotation/TitleAnnotationFacetFactory.java | 58 +++++++++++++++++++-
 2 files changed, 63 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/7c96689c/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleMethodFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleMethodFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleMethodFacetFactory.java
index 9ee6720..1822ef7 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleMethodFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/TitleMethodFacetFactory.java
@@ -51,19 +51,18 @@ public class TitleMethodFacetFactory extends MethodPrefixBasedFacetFactoryAbstra
         final Class<?> cls = processClassContext.getCls();
         final FacetHolder facetHolder = processClassContext.getFacetHolder();
 
-        // may have a facet by virtue of @Title, say.
-        final TitleFacet existingTitleFacet = facetHolder.getFacet(TitleFacet.class);
-        if(existingTitleFacet != null && !existingTitleFacet.isNoop()) {
-            return;
-        }
-        
         Method method = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, TITLE, String.class, null);
         if (method != null) {
             processClassContext.removeMethod(method);
             FacetUtil.addFacet(new TitleFacetViaTitleMethod(method, facetHolder));
             return;
         }
-        
+
+        // may have a facet by virtue of @Title, say.
+        final TitleFacet existingTitleFacet = facetHolder.getFacet(TitleFacet.class);
+        if(existingTitleFacet != null && !existingTitleFacet.isNoop()) {
+            return;
+        }
 
         try {
             method = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, TO_STRING, String.class, null);

http://git-wip-us.apache.org/repos/asf/isis/blob/7c96689c/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
index 6864b16..ee4c9d8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/title/annotation/TitleAnnotationFacetFactory.java
@@ -28,18 +28,27 @@ import com.google.common.base.Splitter;
 import com.google.common.collect.Lists;
 
 import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManagerAware;
 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.FacetFactoryAbstract;
 import org.apache.isis.core.metamodel.methodutils.MethodScope;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+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.ValidationFailures;
 import org.apache.isis.core.progmodel.facets.MethodFinderUtils;
 import org.apache.isis.core.progmodel.facets.fallback.FallbackFacetFactory;
+import org.apache.isis.core.progmodel.facets.object.title.TitleMethodFacetFactory;
 import org.apache.isis.core.progmodel.facets.object.title.annotation.TitleFacetViaTitleAnnotation.TitleComponent;
 
-public class TitleAnnotationFacetFactory extends FacetFactoryAbstract implements AdapterManagerAware {
+public class TitleAnnotationFacetFactory extends FacetFactoryAbstract implements AdapterManagerAware, MetaModelValidatorRefiner {
+
+    private static final String TITLE_METHOD_NAME = "title";
 
     private AdapterManager adapterManager;
 
@@ -137,4 +146,51 @@ public class TitleAnnotationFacetFactory extends FacetFactoryAbstract implements
     public void setAdapterManager(final AdapterManager adapterMap) {
         this.adapterManager = adapterMap;
     }
+
+    /**
+     * Violation if there is a class that has both a <tt>title()</tt> method and also any non-inherited method 
+     * annotated with <tt>@Title</tt>.
+     * 
+     * <p>
+     * If there are only inherited methods annotated with <tt>@Title</tt> then this is <i>not</i> a violation; but 
+     * (from the implementation of {@link TitleMethodFacetFactory} the imperative <tt>title()</tt> method will take
+     * precedence.
+     */
+    @Override
+    public void refineMetaModelValidator(MetaModelValidatorComposite metaModelValidator, IsisConfiguration configuration) {
+        metaModelValidator.add(new MetaModelValidatorVisiting(new MetaModelValidatorVisiting.Visitor() {
+
+            @Override
+            public boolean visit(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
+                final Class<?> cls = objectSpec.getCorrespondingClass();
+
+                final Method titleMethod = MethodFinderUtils.findMethod(cls, MethodScope.OBJECT, TITLE_METHOD_NAME, String.class, null);
+                if (titleMethod == null) {
+                    return true;
+                }
+                
+                // determine if cls contains an @Title annotated method, not inherited from superclass
+                final Class<?> supClass = cls.getSuperclass();
+                if (supClass == null) {
+                    return true;
+                }
+                
+                final List<Method> methods = methodsWithTitleAnnotation(cls);
+                final List<Method> superClassMethods = methodsWithTitleAnnotation(supClass);
+                if (methods.size() > superClassMethods.size()) {
+                    validationFailures.add(
+                            "Conflict for determining a strategy for retrieval of title for class %s "
+                            + "that contains a method '%s' and an annotation '@%s'", 
+                            objectSpec.getIdentifier().getClassName(), TITLE_METHOD_NAME, Title.class.getName());
+                }
+
+                return true;
+            }
+
+            private List<Method> methodsWithTitleAnnotation(final Class<?> cls) {
+                return MethodFinderUtils.findMethodsWithAnnotation(cls, MethodScope.OBJECT, Title.class);
+            }
+
+        }));
+    }
 }