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 2014/10/27 15:59:32 UTC

[3/3] git commit: ISIS-935: RO viewer return 404 for not found. To enable this, introduced ExceptionRecognizer2 interface (an extension of ExceptionRecognizer) and pushed down its usage into DataNucleusObjectStore.

ISIS-935: RO viewer return 404 for not found.  To enable this, introduced ExceptionRecognizer2 interface (an extension of ExceptionRecognizer) and pushed down its usage into DataNucleusObjectStore.


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

Branch: refs/heads/master
Commit: 57c97cf1d6ef4ad9c3076a9a1f1e03c510a5cc91
Parents: e7a8157
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Mon Oct 27 14:59:21 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Mon Oct 27 14:59:21 2014 +0000

----------------------------------------------------------------------
 .../exceprecog/ExceptionRecognizer2.java        | 82 ++++++++++++++++++++
 .../exceprecog/ExceptionRecognizerAbstract.java | 27 +++++--
 .../ExceptionRecognizerComposite.java           | 31 +++++++-
 .../exceprecog/ExceptionRecognizerForType.java  | 22 ++++--
 ...ptionRecognizerForJDODataStoreException.java |  3 +-
 ...RecognizerForJDOObjectNotFoundException.java | 10 ++-
 ...nstraintViolationUniqueOrIndexException.java |  3 +-
 .../container/DomainObjectContainerDefault.java | 12 ++-
 .../jdo/datanucleus/DataNucleusObjectStore.java | 17 ++++
 9 files changed, 184 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/57c97cf1/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java
new file mode 100644
index 0000000..d69f9d3
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizer2.java
@@ -0,0 +1,82 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.applib.services.exceprecog;
+
+/**
+ * An extension of the {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer} interface that
+ * allows recognized exceptions to be {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2.Category categorize}d.
+ */
+public interface ExceptionRecognizer2 extends ExceptionRecognizer {
+
+    public enum Category {
+        /**
+         * A violation of some declarative constraint (eg uniqueness or referential integrity) was detected.
+         */
+        CONSTRAINT_VIOLATION,
+        /**
+         * The object to be acted upon cannot be found (404)
+         */
+        NOT_FOUND,
+        /**
+         * A concurrency exception, in other words some other user has changed this object.
+         */
+        CONCURRENCY,
+        /**
+         * Recognized, but for some other reason... 40x error
+         */
+        CLIENT_ERROR,
+        /**
+         * 50x error
+         */
+        SERVER_ERROR,
+        /**
+         * Recognized, but uncategorized (typically: a recognizer of the original ExceptionRecognizer API).
+         */
+        OTHER
+    }
+
+    public static class Recognition {
+
+        /**
+         * Returns a recognition of the specified type (assuming a non-null reason); else null.
+         */
+        public static Recognition of(Category category, String reason) {
+            return reason != null? new Recognition(category, reason): null;
+        }
+
+        private final Category category;
+        private final String reason;
+
+        public Recognition(Category category, String reason) {
+            this.category = category;
+            this.reason = reason;
+        }
+
+        public Category getCategory() {
+            return category;
+        }
+
+        public String getReason() {
+            return reason;
+        }
+    }
+
+    public Recognition recognize2(final Throwable ex);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/57c97cf1/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerAbstract.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerAbstract.java
index b84c452..8c9c98c 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerAbstract.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerAbstract.java
@@ -45,7 +45,7 @@ import org.apache.isis.applib.annotation.Hidden;
  * then the message can be altered.  Otherwise the exception's {@link Throwable#getMessage() message} is returned as-is.
  */
 @Hidden
-public abstract class ExceptionRecognizerAbstract implements ExceptionRecognizer {
+public abstract class ExceptionRecognizerAbstract implements ExceptionRecognizer2 {
 
     public static final Logger LOG = LoggerFactory.getLogger(ExceptionRecognizerAbstract.class);
 
@@ -57,6 +57,7 @@ public abstract class ExceptionRecognizerAbstract implements ExceptionRecognizer
      */
     private static final String KEY_LOG_RECOGNIZED_EXCEPTIONS = "isis.services.exceprecog.logRecognizedExceptions";
 
+
     /**
      * Convenience for subclass implementations that always return a fixed message.
      */
@@ -86,7 +87,8 @@ public abstract class ExceptionRecognizerAbstract implements ExceptionRecognizer
     
     // //////////////////////////////////////
 
-    
+
+    private final Category category;
     private final Predicate<Throwable> predicate;
     private final Function<String,String> messageParser;
     
@@ -94,16 +96,25 @@ public abstract class ExceptionRecognizerAbstract implements ExceptionRecognizer
 
     // //////////////////////////////////////
 
-    public ExceptionRecognizerAbstract(Predicate<Throwable> predicate, final Function<String,String> messageParser) {
+    public ExceptionRecognizerAbstract(final Category category, Predicate<Throwable> predicate, final Function<String,String> messageParser) {
+        this.category = category;
         this.predicate = predicate;
         this.messageParser = messageParser != null? messageParser: Functions.<String>identity();
     }
 
+    public ExceptionRecognizerAbstract(Predicate<Throwable> predicate, final Function<String,String> messageParser) {
+        this(Category.OTHER, predicate, messageParser);
+    }
+
+    public ExceptionRecognizerAbstract(Category category, Predicate<Throwable> predicate) {
+        this(category, predicate, null);
+    }
+
     public ExceptionRecognizerAbstract(Predicate<Throwable> predicate) {
-        this(predicate, null);
+        this(Category.OTHER, predicate);
     }
 
-    
+
     @PostConstruct
     public void init(Map<String, String> properties) {
         final String prop = properties.get(KEY_LOG_RECOGNIZED_EXCEPTIONS);
@@ -131,4 +142,10 @@ public abstract class ExceptionRecognizerAbstract implements ExceptionRecognizer
         }
         return null;
     }
+
+    @Override
+    public Recognition recognize2(Throwable ex) {
+        return Recognition.of(category, recognize(ex));
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/57c97cf1/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
index af31fc9..390e797 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerComposite.java
@@ -43,7 +43,7 @@ import org.apache.isis.applib.annotation.Hidden;
  * set through the use of this class.
  */
 @Hidden
-public class ExceptionRecognizerComposite implements ExceptionRecognizer {
+public class ExceptionRecognizerComposite implements ExceptionRecognizer2 {
 
     private final List<ExceptionRecognizer> services = Lists.newArrayList();
 
@@ -59,7 +59,7 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer {
 
     /**
      * Register an {@link ExceptionRecognizer} to be consulted when
-     * {@link #recognize(Exception)} is called.
+     * {@link #recognize(Throwable)} is called.
      * 
      * <p>
      * The most specific {@link ExceptionRecognizer recognizer}s should be registered
@@ -83,7 +83,32 @@ public class ExceptionRecognizerComposite implements ExceptionRecognizer {
         }
         return null;
     }
-    
+
+    /**
+     * Returns the non-<tt>null</tt> recognition of the first {@link #add(ExceptionRecognizer) add}ed
+     * (that is also an {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2}).
+     *
+     * <p>
+     *     If none (as {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2}) recognize
+     *     the exception, then falls back to using {@link #recognize(Throwable)}, returning a
+     *     {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2.Recognition} with a
+     *     category of {@link org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2.Category#CLIENT_ERROR}.
+     * </p>
+     */
+    public final Recognition recognize2(Throwable ex) {
+        for (ExceptionRecognizer ers : services) {
+            if(ers instanceof ExceptionRecognizer2) {
+                final ExceptionRecognizer2 recognizer2 = (ExceptionRecognizer2) ers;
+                final Recognition recognition = recognizer2.recognize2(ex);
+                if(recognition != null) {
+                    return recognition;
+                }
+            }
+        }
+        // backward compatible so far as possible.
+        return Recognition.of(Category.OTHER, recognize(ex));
+    }
+
     @PostConstruct
     @Override
     public final void init(Map<String, String> properties) {

http://git-wip-us.apache.org/repos/asf/isis/blob/57c97cf1/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerForType.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerForType.java b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerForType.java
index 56908b0..876b369 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerForType.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/exceprecog/ExceptionRecognizerForType.java
@@ -109,16 +109,28 @@ public class ExceptionRecognizerForType extends ExceptionRecognizerAbstract {
         };
     }
 
-    public ExceptionRecognizerForType(final Class<? extends Exception> exceptionType, final Function<String,String> messageParser) {
-        this(ofType(exceptionType), messageParser);
+    public ExceptionRecognizerForType(Category category, final Class<? extends Exception> exceptionType, final Function<String,String> messageParser) {
+        this(category, ofType(exceptionType), messageParser);
     }
     
-    public ExceptionRecognizerForType(final Predicate<Throwable> predicate, final Function<String,String> messageParser) {
-        super(predicate, messageParser);
+    public ExceptionRecognizerForType(Category category, final Predicate<Throwable> predicate, final Function<String,String> messageParser) {
+        super(category, predicate, messageParser);
     }
     
+    public ExceptionRecognizerForType(Category category, Class<? extends Exception> exceptionType) {
+        this(category, exceptionType, null);
+    }
+
+    public ExceptionRecognizerForType(final Class<? extends Exception> exceptionType, final Function<String,String> messageParser) {
+        this(Category.OTHER, exceptionType, messageParser);
+    }
+
+    public ExceptionRecognizerForType(final Predicate<Throwable> predicate, final Function<String,String> messageParser) {
+        this(Category.OTHER, predicate, messageParser);
+    }
+
     public ExceptionRecognizerForType(Class<? extends Exception> exceptionType) {
-        this(exceptionType, null);
+        this(Category.OTHER, exceptionType);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/57c97cf1/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForJDODataStoreException.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForJDODataStoreException.java b/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForJDODataStoreException.java
index a79e090..93ddee9 100644
--- a/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForJDODataStoreException.java
+++ b/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForJDODataStoreException.java
@@ -23,7 +23,8 @@ import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerForType;
 public class ExceptionRecognizerForJDODataStoreException extends ExceptionRecognizerForType {
 
     public ExceptionRecognizerForJDODataStoreException() {
-        super(ofTypeExcluding(javax.jdo.JDODataStoreException.class, "NOT NULL check constraint"), 
+        super(Category.SERVER_ERROR,
+                ofTypeExcluding(javax.jdo.JDODataStoreException.class, "NOT NULL check constraint"),
             prefix("Unable to save changes.  " +
             	   "Does similar data already exist, or has referenced data been deleted?"));
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/57c97cf1/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForJDOObjectNotFoundException.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForJDOObjectNotFoundException.java b/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForJDOObjectNotFoundException.java
index c80a30a..025371e 100644
--- a/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForJDOObjectNotFoundException.java
+++ b/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForJDOObjectNotFoundException.java
@@ -20,12 +20,14 @@ package org.apache.isis.objectstore.jdo.applib.service.exceprecog;
 
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerForType;
 
-public class ExceptionRecognizerForJDOObjectNotFoundException extends ExceptionRecognizerForType {
+public class ExceptionRecognizerForJDOObjectNotFoundException
+        extends ExceptionRecognizerForType {
 
     public ExceptionRecognizerForJDOObjectNotFoundException() {
-        super(javax.jdo.JDOObjectNotFoundException.class, 
-            prefix("Unable to load object.  " +
-            	   "Has it been deleted by someone else?"));
+        super(Category.NOT_FOUND,
+              javax.jdo.JDOObjectNotFoundException.class,
+              prefix("Unable to load object.  " +
+                   "Has it been deleted by someone else?"));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/57c97cf1/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForSQLIntegrityConstraintViolationUniqueOrIndexException.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForSQLIntegrityConstraintViolationUniqueOrIndexException.java b/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForSQLIntegrityConstraintViolationUniqueOrIndexException.java
index eadaa30..2469c59 100644
--- a/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForSQLIntegrityConstraintViolationUniqueOrIndexException.java
+++ b/core/applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/exceprecog/ExceptionRecognizerForSQLIntegrityConstraintViolationUniqueOrIndexException.java
@@ -23,7 +23,8 @@ import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerForType;
 public class ExceptionRecognizerForSQLIntegrityConstraintViolationUniqueOrIndexException extends ExceptionRecognizerForType {
 
     public ExceptionRecognizerForSQLIntegrityConstraintViolationUniqueOrIndexException() {
-        super(ofTypeIncluding(java.sql.SQLIntegrityConstraintViolationException.class, "unique constraint or index violation"), 
+        super(Category.SERVER_ERROR,
+              ofTypeIncluding(java.sql.SQLIntegrityConstraintViolationException.class, "unique constraint or index violation"),
                 prefix("Data already exists"));
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/57c97cf1/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
index 8df17d1..f864ac6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
@@ -25,7 +25,10 @@ import java.util.Map;
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import com.google.common.base.Predicate;
-import org.apache.isis.applib.*;
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.PersistFailedException;
+import org.apache.isis.applib.RecoverableException;
+import org.apache.isis.applib.RepositoryException;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.filter.Filter;
@@ -541,14 +544,15 @@ public class  DomainObjectContainerDefault implements DomainObjectContainer, Que
 
     //region > ExceptionRecognizer
 
-    static class ExceptionRecognizerForConcurrencyException extends ExceptionRecognizerForType {
+    static class ExceptionRecognizerForConcurrencyException
+            extends ExceptionRecognizerForType {
         public ExceptionRecognizerForConcurrencyException() {
-            super(ConcurrencyException.class, prefix("Another user has just changed this data"));
+            super(Category.CONCURRENCY, ConcurrencyException.class, prefix("Another user has just changed this data"));
         }
     }
     static class ExceptionRecognizerForRecoverableException extends ExceptionRecognizerForType {
         public ExceptionRecognizerForRecoverableException() {
-            super(RecoverableException.class);
+            super(Category.CLIENT_ERROR, RecoverableException.class);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/57c97cf1/core/objectstore-jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusObjectStore.java
----------------------------------------------------------------------
diff --git a/core/objectstore-jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusObjectStore.java b/core/objectstore-jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusObjectStore.java
index 754ab27..3c6d792 100644
--- a/core/objectstore-jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusObjectStore.java
+++ b/core/objectstore-jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusObjectStore.java
@@ -31,6 +31,9 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
+import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2;
 import org.apache.isis.core.commons.config.ConfigurationConstants;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.debug.DebugBuilder;
@@ -396,6 +399,20 @@ public class DataNucleusObjectStore implements ObjectStoreSpi {
             fetchPlan.addGroup(FetchGroup.DEFAULT);
             result = pm.getObjectById(cls, jdoObjectId);
         } catch (final RuntimeException e) {
+
+            final List<ExceptionRecognizer> exceptionRecognizers = getPersistenceSession().getServicesInjector().lookupServices(ExceptionRecognizer.class);
+            for (ExceptionRecognizer exceptionRecognizer : exceptionRecognizers) {
+                if(exceptionRecognizer instanceof ExceptionRecognizer2) {
+                    final ExceptionRecognizer2 recognizer = (ExceptionRecognizer2) exceptionRecognizer;
+                    final ExceptionRecognizer2.Recognition recognition = recognizer.recognize2(e);
+                    if(recognition != null) {
+                        if(recognition.getCategory() == ExceptionRecognizer2.Category.NOT_FOUND) {
+                            throw new ObjectNotFoundException(oid);
+                        }
+                    }
+                }
+            }
+
             throw e;
         }