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 2022/12/21 14:45:58 UTC

[isis] branch master updated: ISIS-3316: use _ClassCache for check on presence of XmlRootElement annot.

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 8a5af84c41 ISIS-3316: use _ClassCache for check on presence of XmlRootElement annot.
8a5af84c41 is described below

commit 8a5af84c41d115930b50cd51d07b6f943493483d
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Dec 21 15:45:53 2022 +0100

    ISIS-3316: use _ClassCache for check on presence of XmlRootElement
    annot.
---
 .../commons/internal/reflection/_ClassCache.java    | 21 ++++++++++++++++++++-
 .../org/apache/causeway/commons/io/JaxbUtils.java   |  6 +++---
 .../beans/CausewayBeanTypeClassifierDefault.java    |  5 ++---
 .../object/viewmodel/ViewModelFacetFactory.java     |  6 +++---
 .../ViewModelFacetForXmlRootElementAnnotation.java  | 10 ++++------
 .../conneg/ContentNegotiationServiceAbstract.java   |  4 ++--
 6 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java b/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java
index 375311e2bc..7d310367dc 100644
--- a/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java
+++ b/commons/src/main/java/org/apache/causeway/commons/internal/reflection/_ClassCache.java
@@ -30,6 +30,7 @@ import java.util.stream.Stream;
 
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
+import javax.xml.bind.annotation.XmlRootElement;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.lang.Nullable;
@@ -82,6 +83,14 @@ public final class _ClassCache implements AutoCloseable {
         inspectType(type);
     }
 
+    // -- TYPE SPECIFIC SEMANTICS
+
+    public boolean hasJaxbRootElementSemantics(final Class<?> type) {
+        return inspectType(type).hasJaxbRootElementSemantics;
+    }
+
+    // -- CONSTRUCTOR SEMANTICS
+
     public <T> Stream<Constructor<T>> streamPublicConstructors(final Class<T> type) {
         return _Casts.uncheckedCast(inspectType(type).publicConstructorsByKey.values().stream());
     }
@@ -94,10 +103,14 @@ public final class _ClassCache implements AutoCloseable {
         return Optional.ofNullable(lookupConstructor(false, type, paramTypes));
     }
 
+    // -- POST CONSTRUCT SEMANTICS
+
     public Stream<Method> streamPostConstructMethods(final Class<?> type) {
         return inspectType(type).postConstructMethodsByKey.values().stream();
     }
 
+    // -- METHOD SEMANTICS
+
     /**
      * A drop-in replacement for {@link Class#getMethod(String, Class...)} that only looks up
      * public methods and does not throw {@link NoSuchMethodException}s.
@@ -130,6 +143,8 @@ public final class _ClassCache implements AutoCloseable {
         return inspectType(type).declaredMethods.stream();
     }
 
+    // -- FIELD SEMANTICS
+
     public Stream<Field> streamDeclaredFields(final Class<?> type) {
         return inspectType(type).declaredFields.stream();
     }
@@ -184,6 +199,7 @@ public final class _ClassCache implements AutoCloseable {
         private final Map<MethodKey, Method> postConstructMethodsByKey = new HashMap<>();
         private final Map<MethodKey, Method> nonPublicDeclaredMethodsByKey = new HashMap<>();
         private final Map<String, Can<Method>> declaredMethodsByAttribute = new HashMap<>();
+        private final boolean hasJaxbRootElementSemantics;
     }
 
     private final Map<Class<?>, ClassModel> inspectedTypes = new HashMap<>();
@@ -230,7 +246,8 @@ public final class _ClassCache implements AutoCloseable {
 
                 val model = new ClassModel(
                         Can.ofArray(declaredFields),
-                        declaredMethods);
+                        declaredMethods,
+                        _Annotations.isPresent(type, XmlRootElement.class));
 
                 for(val constr : publicConstr) {
                     val key = ConstructorKey.of(type, constr);
@@ -362,4 +379,6 @@ public final class _ClassCache implements AutoCloseable {
         return _Strings.decapitalize(fieldName);
     }
 
+
+
 }
diff --git a/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java b/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java
index b0a9ae5fd7..da513d9471 100644
--- a/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java
+++ b/commons/src/main/java/org/apache/causeway/commons/io/JaxbUtils.java
@@ -31,7 +31,6 @@ import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.namespace.QName;
 
 import org.springframework.lang.Nullable;
@@ -43,7 +42,7 @@ import org.apache.causeway.commons.internal.codec._DocumentFactories;
 import org.apache.causeway.commons.internal.collections._Maps;
 import org.apache.causeway.commons.internal.exceptions._Exceptions;
 import org.apache.causeway.commons.internal.functions._Functions;
-import org.apache.causeway.commons.internal.reflection._Annotations;
+import org.apache.causeway.commons.internal.reflection._ClassCache;
 
 import lombok.Builder;
 import lombok.Data;
@@ -100,7 +99,8 @@ public class JaxbUtils {
 
         private boolean shouldMissingXmlRootElementBeHandledOn(final Class<?> mappedType) {
             return isAllowMissingRootElement()
-                    && !_Annotations.isPresent(mappedType, XmlRootElement.class); //TODO ask _ClassCache
+                    // looking for presence of XmlRootElement annotation
+                    && !_ClassCache.getInstance().hasJaxbRootElementSemantics(mappedType);
         }
         @SneakyThrows
         private JAXBContext jaxbContext(final Class<?> mappedType) {
diff --git a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifierDefault.java b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifierDefault.java
index 36f53d989c..7ae4302e2a 100644
--- a/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifierDefault.java
+++ b/core/config/src/main/java/org/apache/causeway/core/config/beans/CausewayBeanTypeClassifierDefault.java
@@ -22,7 +22,6 @@ import java.io.Serializable;
 import java.lang.reflect.Modifier;
 
 import javax.persistence.Entity;
-import javax.xml.bind.annotation.XmlRootElement;
 
 import org.springframework.context.annotation.Profile;
 import org.springframework.stereotype.Component;
@@ -35,6 +34,7 @@ import org.apache.causeway.applib.services.metamodel.BeanSort;
 import org.apache.causeway.commons.collections.Can;
 import org.apache.causeway.commons.internal.base._Strings;
 import org.apache.causeway.commons.internal.reflection._Annotations;
+import org.apache.causeway.commons.internal.reflection._ClassCache;
 import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants;
 import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants.TypeExcludeMarker;
 
@@ -160,8 +160,7 @@ implements CausewayBeanTypeClassifier {
             }
         }
 
-        val jaxbAnnotation = _Annotations.synthesize(type, XmlRootElement.class).orElse(null);
-        if(jaxbAnnotation!=null) {
+        if(_ClassCache.getInstance().hasJaxbRootElementSemantics(type)) {
             return CausewayBeanMetaData.causewayManaged(BeanSort.VIEW_MODEL, type);
         }
 
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetFactory.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetFactory.java
index 2c0c066936..ee401add8a 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetFactory.java
@@ -19,8 +19,8 @@
 package org.apache.causeway.core.metamodel.facets.object.viewmodel;
 
 import javax.inject.Inject;
-import javax.xml.bind.annotation.XmlRootElement;
 
+import org.apache.causeway.commons.internal.reflection._ClassCache;
 import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants;
 import org.apache.causeway.core.metamodel.context.MetaModelContext;
 import org.apache.causeway.core.metamodel.facetapi.FacetUtil;
@@ -56,11 +56,11 @@ implements
         val type = processClassContext.getCls();
 
         // XmlRootElement annotation (with default precedence)
-        val xmlRootElementIfAny = processClassContext.synthesizeOnType(XmlRootElement.class);
+        val hasXmlRootElementAnnotation = _ClassCache.getInstance().hasJaxbRootElementSemantics(type);
         FacetUtil
         .addFacetIfPresent(
                 ViewModelFacetForXmlRootElementAnnotation
-                .create(xmlRootElementIfAny, facetHolder));
+                .create(hasXmlRootElementAnnotation, facetHolder));
 
         // (with high precedence)
         FacetUtil
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetForXmlRootElementAnnotation.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetForXmlRootElementAnnotation.java
index 5d62ff4ac4..6649aaf7e6 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetForXmlRootElementAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/object/viewmodel/ViewModelFacetForXmlRootElementAnnotation.java
@@ -20,8 +20,6 @@ package org.apache.causeway.core.metamodel.facets.object.viewmodel;
 
 import java.util.Optional;
 
-import javax.xml.bind.annotation.XmlRootElement;
-
 import org.apache.causeway.applib.services.bookmark.Bookmark;
 import org.apache.causeway.applib.services.jaxb.JaxbService;
 import org.apache.causeway.applib.services.urlencoding.UrlEncodingService;
@@ -39,12 +37,12 @@ public class ViewModelFacetForXmlRootElementAnnotation
 extends ViewModelFacetAbstract {
 
     public static Optional<ViewModelFacet> create(
-            final Optional<XmlRootElement> xmlRootElementIfAny,
+            final boolean hasRootElementAnnotation,
             final FacetHolder facetHolder) {
 
-        return xmlRootElementIfAny.map(xmlRootElement->
-            new ViewModelFacetForXmlRootElementAnnotation(
-                    facetHolder));
+        return hasRootElementAnnotation
+                ? Optional.of(new ViewModelFacetForXmlRootElementAnnotation(facetHolder))
+                : Optional.empty();
     }
 
     private ViewModelFacetForXmlRootElementAnnotation(
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
index 8abc7bc1ad..4d533d222d 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/causeway/viewer/restfulobjects/rendering/service/conneg/ContentNegotiationServiceAbstract.java
@@ -23,11 +23,11 @@ import java.util.Objects;
 
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.causeway.commons.internal.base._Strings;
 import org.apache.causeway.commons.internal.collections._Lists;
 import org.apache.causeway.commons.internal.factory._InstanceUtil;
+import org.apache.causeway.commons.internal.reflection._ClassCache;
 import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
 import org.apache.causeway.core.metamodel.interactions.managed.ManagedCollection;
 import org.apache.causeway.core.metamodel.interactions.managed.ManagedProperty;
@@ -103,7 +103,7 @@ public abstract class ContentNegotiationServiceAbstract implements ContentNegoti
     }
 
     protected void ensureJaxbAnnotated(final Class<?> domainType) {
-        if(domainType.getAnnotation(XmlRootElement.class) == null) {
+        if(!_ClassCache.getInstance().hasJaxbRootElementSemantics(domainType)) {
             throw RestfulObjectsApplicationException.createWithMessage(RestfulResponse.HttpStatusCode.BAD_REQUEST, "Requested domain Type '" + domainType.getName() + "' is not annotated with JAXB @XmlRootElement annotation");
         }
     }