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 2015/11/13 18:57:17 UTC

[06/11] isis git commit: ISIS-915: improving the error handling.

ISIS-915: improving the error handling.


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

Branch: refs/heads/master
Commit: 0e9d1b2be4cd513685fe4f0999c43fedb7e78f5a
Parents: d654fc8
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Fri Nov 13 11:58:52 2015 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Fri Nov 13 11:58:52 2015 +0000

----------------------------------------------------------------------
 .../isis/applib/services/jaxb/JaxbService.java  |  2 +-
 .../services/jaxb/JaxbServiceDefault.java       | 51 +++++++++++++++++---
 .../jaxbadapters/PersistentEntityAdapter.java   | 14 +++++-
 3 files changed, 59 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/0e9d1b2b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
index 4c7c03b..0cdd9e5 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/jaxb/JaxbService.java
@@ -23,7 +23,7 @@ import org.apache.isis.applib.annotation.Programmatic;
 public interface JaxbService {
 
     @Programmatic
-    <T> T fromXml(Class<T> domainClass, String memento);
+    <T> T fromXml(Class<T> domainClass, String xml);
 
     @Programmatic
     public String toXml(final Object domainObject);

http://git-wip-us.apache.org/repos/asf/isis/blob/0e9d1b2b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/JaxbServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/JaxbServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/JaxbServiceDefault.java
index 562a666..6d86f4f 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/JaxbServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/jaxb/JaxbServiceDefault.java
@@ -19,6 +19,8 @@ package org.apache.isis.core.runtime.services.jaxb;
 import java.io.IOException;
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.util.List;
 import java.util.Map;
 
 import javax.inject.Inject;
@@ -27,8 +29,13 @@ import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.Unmarshaller;
 
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Iterables;
+
 import org.apache.isis.applib.ApplicationException;
 import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.NonRecoverableException;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.jaxb.JaxbService;
@@ -41,7 +48,7 @@ import org.apache.isis.schema.utils.jaxbadapters.PersistentEntityAdapter;
 public class JaxbServiceDefault implements JaxbService {
 
     @Override
-    public <T> T fromXml(final Class<T> domainClass, final String memento) {
+    public <T> T fromXml(final Class<T> domainClass, final String xml) {
         try {
             final JAXBContext context = JAXBContext.newInstance(domainClass);
 
@@ -51,19 +58,19 @@ public class JaxbServiceDefault implements JaxbService {
             final Unmarshaller unmarshaller = context.createUnmarshaller();
             unmarshaller.setAdapter(PersistentEntityAdapter.class, adapter);
 
-            final Object unmarshal = unmarshaller.unmarshal(new StringReader(memento));
+            final Object unmarshal = unmarshaller.unmarshal(new StringReader(xml));
             return (T) unmarshal;
 
         } catch (final JAXBException ex) {
-            throw new ApplicationException(ex);
+            throw new NonRecoverableException("Error unmarshalling domain object from XML; domain object class is '" + domainClass.getName() + "'", ex);
         }
     }
 
     @Override
     public String toXml(final Object domainObject)  {
 
+        final Class<?> domainClass = domainObject.getClass();
         try {
-            final Class<?> domainClass = domainObject.getClass();
             final JAXBContext context = JAXBContext.newInstance(domainClass);
 
             final PersistentEntityAdapter adapter = new PersistentEntityAdapter();
@@ -75,10 +82,42 @@ public class JaxbServiceDefault implements JaxbService {
 
             final StringWriter sw = new StringWriter();
             marshaller.marshal(domainObject, sw);
-            return sw.toString();
+            final String xml = sw.toString();
+
+            return xml;
 
         } catch (final JAXBException ex) {
-            throw new ApplicationException(ex);
+            final Class<? extends JAXBException> exClass = ex.getClass();
+
+            final String name = exClass.getName();
+            if(name.equals("com.sun.xml.bind.v2.runtime.IllegalAnnotationsException")) {
+                // report a better error if possible
+                // this is done reflectively so as to not have to bring in a new Maven dependency
+                List<? extends Exception> errors = null;
+                String annotationExceptionMessages = null;
+                try {
+                    final Method getErrorsMethod = exClass.getMethod("getErrors");
+                    errors = (List<? extends Exception>) getErrorsMethod.invoke(ex);
+                    annotationExceptionMessages = ": " + Joiner.on("; ").join(
+                            Iterables.transform(errors, new Function<Exception, String>() {
+                                @Override public String apply(final Exception e) {
+                                    return e.getMessage();
+                                }
+                            }));
+                } catch (Exception e) {
+                    // fall through if we hit any snags, and instead throw the more generic error message.
+                }
+                if(errors != null) {
+                    throw new NonRecoverableException(
+                            "Error marshalling domain object to XML, due to illegal annotations on domain object class '"
+                                    + domainClass.getName() + "'; " + errors.size() + " error"
+                                    + (errors.size() == 1? "": "s")
+                                    + " reported" + (!errors
+                                    .isEmpty() ? annotationExceptionMessages : ""), ex);
+                }
+            }
+
+            throw new NonRecoverableException("Error marshalling domain object to XML; domain object class is '" + domainClass.getName() + "'", ex);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/0e9d1b2b/core/schema/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntityAdapter.java
----------------------------------------------------------------------
diff --git a/core/schema/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntityAdapter.java b/core/schema/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntityAdapter.java
index 0ff29b3..612205b 100644
--- a/core/schema/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntityAdapter.java
+++ b/core/schema/src/main/java/org/apache/isis/schema/utils/jaxbadapters/PersistentEntityAdapter.java
@@ -38,14 +38,26 @@ public class PersistentEntityAdapter extends XmlAdapter<OidDto, Object> {
 
     @Override
     public OidDto marshal(final Object domainObject) throws Exception {
+        if(domainObject == null) {
+            return null;
+        }
         final Bookmark bookmark = bookmarkService.bookmarkFor(domainObject);
         final OidDto oidDto = new OidDto();
         oidDto.setObjectIdentifier(bookmark.getIdentifier());
-        oidDto.setObjectState(BookmarkObjectState.PERSISTENT);
+        oidDto.setObjectState(convert(bookmark.getObjectState()));
         oidDto.setObjectType(bookmark.getObjectType());
         return oidDto;
     }
 
+    private BookmarkObjectState convert(final Bookmark.ObjectState objectState) {
+        switch (objectState) {
+            case VIEW_MODEL:return BookmarkObjectState.VIEW_MODEL;
+            case TRANSIENT:return BookmarkObjectState.TRANSIENT;
+            case PERSISTENT:return BookmarkObjectState.PERSISTENT;
+        }
+        throw new IllegalArgumentException("Not recognized: " + objectState.name());
+    }
+
     @Inject
     BookmarkService bookmarkService;
 }