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);
}
}