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 3b820c96e3 ISIS-3316: JaxbService: encapsulates verbose exception 
handling with JaxbUtils
3b820c96e3 is described below

commit 3b820c96e3b855bebb5fd44781a9d21d43d7131c
Author: Andi Huber <[email protected]>
AuthorDate: Thu Dec 22 11:29:54 2022 +0100

    ISIS-3316: JaxbService: encapsulates verbose exception handling with
    JaxbUtils
---
 .../causeway/applib/services/jaxb/JaxbService.java | 13 ++-----
 .../org/apache/causeway/commons/io/JaxbUtils.java  | 42 ++++++++++++++--------
 .../runtimeservices/jaxb/JaxbServiceDefault.java   | 22 +++++-------
 3 files changed, 38 insertions(+), 39 deletions(-)

diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/services/jaxb/JaxbService.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/services/jaxb/JaxbService.java
index f0f29ee976..d3b9996caf 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/services/jaxb/JaxbService.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/services/jaxb/JaxbService.java
@@ -105,7 +105,6 @@ public interface JaxbService {
     class Simple implements JaxbService {
 
         @Override
-        @SneakyThrows
         @Nullable
         public final <T> T fromXml(
                 final @NonNull Class<T> domainClass,
@@ -115,7 +114,6 @@ public interface JaxbService {
             if (xml == null) {
                 return null;
             }
-
             return JaxbUtils.tryRead(domainClass, xml, opts->{
                 for (val entry : _NullSafe.entrySet(unmarshallerProperties)) {
                     opts.property(entry.getKey(), entry.getValue());
@@ -123,24 +121,18 @@ public interface JaxbService {
                 opts.unmarshallerConfigurer(this::configure);
                 return opts;
             })
-            .mapFailure(cause->JaxbUtils.verboseException("unmarshalling XML", 
domainClass, cause))
             .ifFailureFail()
             .getValue().orElse(null);
-
         }
 
         @Override
-        @SneakyThrows
         public final String toXml(
                 final @NonNull Object domainObject,
                 final @Nullable Map<String, Object> marshallerProperties) {
 
-            val jaxbContext = Try.call(()->domainObject instanceof 
DomainObjectList
+            val jaxbContext = domainObject instanceof DomainObjectList
                     ? jaxbContextForList((DomainObjectList)domainObject)
-                    : JaxbUtils.jaxbContextFor(domainObject.getClass(), true))
-                .mapFailure(cause->JaxbUtils.verboseException("creating JAXB 
context for domain object", domainObject.getClass(), cause))
-                .ifFailureFail()
-                .getValue().orElseThrow();
+                    : JaxbUtils.jaxbContextFor(domainObject.getClass(), true);
 
             return Try.call(()->JaxbUtils.toStringUtf8(domainObject, opts->{
                 for (val entry : _NullSafe.entrySet(marshallerProperties)) {
@@ -150,7 +142,6 @@ public interface JaxbService {
                 opts.jaxbContextOverride(jaxbContext);
                 return opts;
             }))
-            .mapFailure(cause->JaxbUtils.verboseException("marshalling domain 
object to XML", domainObject.getClass(), cause))
             .ifFailureFail()
             .getValue().orElse(null);
         }
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 da513d9471..08ee9b191f 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
@@ -39,6 +39,8 @@ import org.apache.causeway.commons.functional.Try;
 import org.apache.causeway.commons.internal.base._Casts;
 import org.apache.causeway.commons.internal.base._NullSafe;
 import org.apache.causeway.commons.internal.codec._DocumentFactories;
+import org.apache.causeway.commons.internal.collections._Arrays;
+import org.apache.causeway.commons.internal.collections._Lists;
 import org.apache.causeway.commons.internal.collections._Maps;
 import org.apache.causeway.commons.internal.exceptions._Exceptions;
 import org.apache.causeway.commons.internal.functions._Functions;
@@ -230,7 +232,8 @@ public class JaxbUtils {
             final JaxbUtils.JaxbCustomizer ... customizers) {
         return source.readAll((final InputStream is)->{
             val opts = createOptions(customizers);
-            return Try.call(()->opts.unmarshal(mappedType, is));
+            return Try.call(()->opts.unmarshal(mappedType, is))
+                    .mapFailure(cause->verboseException("unmarshalling XML", 
mappedType, cause));
         });
     }
 
@@ -245,26 +248,25 @@ public class JaxbUtils {
             final JaxbUtils.JaxbCustomizer ... customizers) {
         if(pojo==null) return;
         val opts = createOptions(customizers);
-        sink.writeAll(os->Try.run(()->opts.marshal(pojo, os)));
+        try {
+            sink.writeAll(os->Try.run(()->opts.marshal(pojo, os)));
+        } catch (Exception cause) {
+            throw verboseException("marshalling domain object to XML", 
pojo.getClass(), cause);
+        }
     }
 
     /**
      * Converts given {@code pojo} to an UTF8 encoded {@link String}.
      * @return <code>null</code> if pojo is <code>null</code>
      */
-    @SneakyThrows
     @Nullable
     public <T> String toStringUtf8(
             final @Nullable T pojo,
             final JaxbUtils.JaxbCustomizer ... customizers) {
         if(pojo==null) return null;
-        class StringHolder implements Consumer<String> {
-            String s;
-            @Override public void accept(String s) { this.s = s; }
-        }
-        val sh = new StringHolder();
-        write(pojo, DataSink.ofStringUtf8Consumer(sh), customizers);
-        return sh.s;
+        val sh = _Lists.<String>newArrayList(1);
+        write(pojo, DataSink.ofStringUtf8Consumer(sh::add), customizers);
+        return sh.stream().findFirst().orElse(null);
     }
 
     // -- CUSTOMIZERS
@@ -281,7 +283,12 @@ public class JaxbUtils {
         return opts.build();
     }
 
-    // -- JAXB CONTEXT CACHE
+    // -- JAXB CONTEXT FACTORIES AND CACHING
+
+    /** not cached */
+    public static JAXBContext jaxbContextFor(final @NonNull Class<?> 
primaryClass, final Class<?> ... additionalClassesToBeBound) {
+        return contextOf(_Arrays.combine(primaryClass, 
additionalClassesToBeBound));
+    }
 
     private static Map<Class<?>, JAXBContext> jaxbContextByClass = 
_Maps.newConcurrentHashMap();
 
@@ -292,17 +299,20 @@ public class JaxbUtils {
     }
 
     @SneakyThrows
-    private static <T> JAXBContext contextOf(final Class<T> dtoClass) {
+    private static <T> JAXBContext contextOf(final Class<?> ... 
classesToBeBound) {
         try {
-            return JAXBContext.newInstance(dtoClass);
+            return JAXBContext.newInstance(classesToBeBound);
         } catch (Exception e) {
-            throw verboseException("obtaining JAXBContext for class", 
dtoClass, e);
+            val msg = String.format("obtaining JAXBContext for classes (to be 
bound) {%s}", _NullSafe.stream(classesToBeBound)
+                    .map(Class::getName)
+                    .collect(Collectors.joining(", ")));
+            throw verboseException(msg, classesToBeBound[0], e); // assuming 
we have at least one argument
         }
     }
 
     // -- ENHANCE EXCEPTION MESSAGE IF POSSIBLE
 
-    public static Exception verboseException(final String doingWhat, @Nullable 
final Class<?> dtoClass, final Throwable cause) {
+    private static RuntimeException verboseException(final String doingWhat, 
@Nullable final Class<?> dtoClass, final Throwable cause) {
 
         val dtoClassName = 
Optional.ofNullable(dtoClass).map(Class::getName).orElse("unknown");
 
@@ -344,4 +354,6 @@ public class JaxbUtils {
     }
 
 
+
+
 }
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/jaxb/JaxbServiceDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/jaxb/JaxbServiceDefault.java
index 88cd94a59a..eacbd2203d 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/jaxb/JaxbServiceDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/jaxb/JaxbServiceDefault.java
@@ -59,19 +59,15 @@ public class JaxbServiceDefault extends Simple {
     @SneakyThrows
     @Override
     protected JAXBContext jaxbContextForList(@NonNull final DomainObjectList 
domainObjectList) {
-        try {
-            val elementType = specLoader
-                    
.specForType(_Context.loadClass(domainObjectList.getElementTypeFqcn()))
-                    .map(ObjectSpecification::getCorrespondingClass)
-                    .orElse(null);
-            if (elementType!=null
-                    && elementType.getAnnotation(XmlJavaTypeAdapter.class) == 
null) {
-                return JAXBContext.newInstance(DomainObjectList.class, 
elementType);
-            } else {
-                return JaxbUtils.jaxbContextFor(DomainObjectList.class, true);
-            }
-        } catch (Exception e) {
-            throw JaxbUtils.verboseException("obtaining JAXBContext for a 
DomainObjectList", DomainObjectList.class, e);
+        val elementType = specLoader
+                
.specForType(_Context.loadClass(domainObjectList.getElementTypeFqcn()))
+                .map(ObjectSpecification::getCorrespondingClass)
+                .orElse(null);
+        if (elementType!=null
+                && elementType.getAnnotation(XmlJavaTypeAdapter.class) == 
null) {
+            return JaxbUtils.jaxbContextFor(DomainObjectList.class, 
elementType);
+        } else {
+            return JaxbUtils.jaxbContextFor(DomainObjectList.class, true);
         }
     }
 

Reply via email to