Author: mreutegg
Date: Tue Mar  6 13:46:09 2018
New Revision: 1825986

URL: http://svn.apache.org/viewvc?rev=1825986&view=rev
Log:
OAK-7305: Introduce DocumentStoreException type

Added:
    
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreExceptionTest.java
   (with props)
Modified:
    
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreException.java

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreException.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreException.java?rev=1825986&r1=1825985&r2=1825986&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreException.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreException.java
 Tue Mar  6 13:46:09 2018
@@ -16,8 +16,14 @@
  */
 package org.apache.jackrabbit.oak.plugins.document;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
 import com.google.common.collect.Lists;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Collections.emptyList;
+
 /**
  * <code>DocumentStoreException</code> is a runtime exception for
  * {@code DocumentStore} implementations to signal unexpected problems like
@@ -25,35 +31,164 @@ import com.google.common.collect.Lists;
  */
 public class DocumentStoreException extends RuntimeException {
 
-    private static final long serialVersionUID = 634445274043721284L;
+    private static final long serialVersionUID = 4135594565927443068L;
+
+    public enum Type {
 
+        /**
+         * A generic type of {@code DocumentStoreException}. This type is used
+         * when no explicit type is given when a {@code DocumentStoreException}
+         * is constructed.
+         */
+        GENERIC,
+
+        /**
+         * A {@code DocumentStoreException} caused by a transient problem. E.g.
+         * a network issue. This type of exception indicates a future 
invocation
+         * of the same operation may succeed if the underlying problem gets
+         * resolved.
+         */
+        TRANSIENT
+    }
+
+    private final Type type;
+
+    /**
+     * Creates a {@link Type#GENERIC} {@code DocumentStoreException} with the
+     * given message.
+     *
+     * @param message the exception message.
+     */
     public DocumentStoreException(String message) {
-        super(message);
+        this(message, null);
     }
 
+    /**
+     * Creates a {@link Type#GENERIC} {@code DocumentStoreException} with the
+     * given cause. The message of the exception is the value returned by
+     * {@code cause.toString()} if available, otherwise {@code null}.
+     *
+     * @param cause the cause or {@code null} if nonexistent or unknown.
+     */
     public DocumentStoreException(Throwable cause) {
-        super(cause);
+        this(getMessage(cause), cause);
     }
 
+    /**
+     * Creates a {@link Type#GENERIC} {@code DocumentStoreException} with the
+     * given message and cause.
+     *
+     * @param message the exception message.
+     * @param cause the cause or {@code null} if nonexistent or unknown.
+     */
     public DocumentStoreException(String message, Throwable cause) {
+        this(message, cause, Type.GENERIC);
+    }
+
+    /**
+     * Creates a {@code DocumentStoreException} with the given message, cause
+     * and type.
+     *
+     * @param message the exception message.
+     * @param cause the cause or {@code null} if nonexistent or unknown.
+     * @param type the type of this exception.
+     */
+    public DocumentStoreException(String message, Throwable cause, Type type) {
         super(message, cause);
+        this.type = checkNotNull(type);
     }
 
-    public static DocumentStoreException convert(Throwable t) {
+    /**
+     * Converts the given {@code Throwable} into a {@link Type#GENERIC}
+     * {@code DocumentStoreException}. If the {@code Throwable} is an instance
+     * of {@code DocumentStoreException} this method returns the given
+     * {@code Throwable} as is, otherwise it will be used as the cause of the
+     * returned {@code DocumentStoreException}. The returned
+     * {@code DocumentStoreException} will have the same message as the given
+     * {@code Throwable}.
+     *
+     * @param t a {@code Throwable}.
+     * @return a {@link Type#GENERIC} DocumentStoreException.
+     */
+    public static DocumentStoreException convert(@Nonnull Throwable t) {
         return convert(t, t.getMessage());
     }
 
-    public static DocumentStoreException convert(Throwable t, String msg) {
+    /**
+     * Converts the given {@code Throwable} into a {@link Type#GENERIC}
+     * {@code DocumentStoreException}. If the {@code Throwable} is an instance
+     * of {@code DocumentStoreException} this method returns the given
+     * {@code Throwable} as is, otherwise it will be used as the cause of the
+     * returned {@code DocumentStoreException}. The returned
+     * {@code DocumentStoreException} will have the given message, unless the
+     * {@code Throwable} already is a {@code DocumentStoreException}.
+     *
+     * @param t a {@code Throwable}.
+     * @param msg a message for the {@code DocumentStoreException}.
+     * @return a {@link Type#GENERIC} DocumentStoreException.
+     */
+    public static DocumentStoreException convert(@Nonnull Throwable t, String 
msg) {
+        return asDocumentStoreException(msg, t, Type.GENERIC, emptyList());
+    }
+
+    /**
+     * Converts the given {@code Throwable} into a {@link Type#GENERIC}
+     * {@code DocumentStoreException}. If the {@code Throwable} is an instance
+     * of {@code DocumentStoreException} this method returns the given
+     * {@code Throwable} as is, otherwise it will be used as the cause of the
+     * returned {@code DocumentStoreException}. The returned
+     * {@code DocumentStoreException} will have the same message as the given
+     * {@code Throwable} appended with the list of {@code ids}.
+     *
+     * @param t a {@code Throwable}.
+     * @param ids a list of {@code DocumentStore} IDs associated with the
+     *            operation that triggered this exception.
+     * @return a {@link Type#GENERIC} DocumentStoreException.
+     */
+    public static DocumentStoreException convert(@Nonnull Throwable t,
+                                                 Iterable<String> ids) {
+        return asDocumentStoreException(t.getMessage(), t, Type.GENERIC, ids);
+    }
+
+    /**
+     * Converts the given {@code Throwable} into a {@code 
DocumentStoreException}.
+     * If the {@code Throwable} is an instance of {@code 
DocumentStoreException}
+     * this method returns the given {@code Throwable} as is, otherwise it will
+     * be used as the cause of the returned {@code DocumentStoreException}.
+     * The {@code ids} will be appended to the given {@code message} and used
+     * for the returned {@code DocumentStoreException}.
+     *
+     * @param message a message for the {@code DocumentStoreException}.
+     * @param t a {@code Throwable}.
+     * @param type the type of this exception.
+     * @param ids a list of {@code DocumentStore} IDs associated with the
+     *            operation that triggered this exception.
+     * @return a {@link Type#GENERIC} DocumentStoreException.
+     */
+    public static DocumentStoreException asDocumentStoreException(String 
message,
+                                                                  Throwable t,
+                                                                  Type type,
+                                                                  
Iterable<String> ids) {
+        String msg = message;
+        if (ids.iterator().hasNext()) {
+            msg += " " + Lists.newArrayList(ids);
+        }
         if (t instanceof DocumentStoreException) {
             return (DocumentStoreException) t;
         } else {
-            return new DocumentStoreException(msg, t);
+            return new DocumentStoreException(msg, t, type);
         }
     }
 
-    public static DocumentStoreException convert(Throwable t,
-                                                 Iterable<String> ids) {
-        String msg = t.getMessage() + " " + Lists.newArrayList(ids);
-        return convert(t, msg);
+    /**
+     * @return the type of this exception.
+     */
+    public Type getType() {
+        return type;
+    }
+
+    @CheckForNull
+    private static String getMessage(Throwable t) {
+        return t == null ? null : t.toString();
     }
 }

Added: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreExceptionTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreExceptionTest.java?rev=1825986&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreExceptionTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreExceptionTest.java
 Tue Mar  6 13:46:09 2018
@@ -0,0 +1,157 @@
+/*
+ * 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.jackrabbit.oak.plugins.document;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import org.apache.jackrabbit.oak.plugins.document.DocumentStoreException.Type;
+import org.junit.Test;
+
+import static 
org.apache.jackrabbit.oak.plugins.document.DocumentStoreException.Type.GENERIC;
+import static 
org.apache.jackrabbit.oak.plugins.document.DocumentStoreException.Type.TRANSIENT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class DocumentStoreExceptionTest {
+
+    @Test
+    public void singleParamMessage() {
+        String msg = "foo";
+        DocumentStoreException dse = new DocumentStoreException(msg);
+        assertNull(dse.getCause());
+        assertEquals(msg, dse.getMessage());
+        assertEquals(GENERIC, dse.getType());
+    }
+
+    @Test
+    public void singleParamMessageNull() {
+        DocumentStoreException dse = new DocumentStoreException((String) null);
+        assertNull(dse.getCause());
+        assertNull(dse.getMessage());
+        assertEquals(GENERIC, dse.getType());
+    }
+
+    @Test
+    public void singleParamCause() {
+        String msg = "foo";
+        Exception cause = new IllegalArgumentException(msg);
+        DocumentStoreException dse = new DocumentStoreException(cause);
+        assertSame(cause, dse.getCause());
+        
assertTrue(dse.getMessage().contains(IllegalArgumentException.class.getSimpleName()));
+        assertTrue(dse.getMessage().contains(msg));
+        assertEquals(GENERIC, dse.getType());
+    }
+
+    @Test
+    public void singleParamCauseNull() {
+        DocumentStoreException dse = new DocumentStoreException((Throwable) 
null);
+        assertNull(dse.getCause());
+        assertNull(dse.getMessage());
+        assertEquals(GENERIC, dse.getType());
+    }
+
+    @Test
+    public void dualParamMessageCause() {
+        String msg = "foo";
+        Exception cause = new IllegalArgumentException(msg);
+        DocumentStoreException dse = new DocumentStoreException(msg, cause);
+        assertSame(cause, dse.getCause());
+        assertEquals(msg, dse.getMessage());
+        assertEquals(GENERIC, dse.getType());
+    }
+
+    @Test
+    public void dualParamMessageThrowableNull() {
+        String msg = "foo";
+        DocumentStoreException dse = new DocumentStoreException(msg, null);
+        assertNull(dse.getCause());
+        assertEquals(msg, dse.getMessage());
+        assertEquals(GENERIC, dse.getType());
+    }
+
+    @Test
+    public void tripleParamMessageCauseType() {
+        String msg = "foo";
+        Exception cause = new IOException(msg);
+        Type type = TRANSIENT;
+        DocumentStoreException dse = new DocumentStoreException(msg, cause, 
type);
+        assertEquals(msg, dse.getMessage());
+        assertSame(cause, dse.getCause());
+        assertEquals(type, dse.getType());
+    }
+
+    @Test
+    public void convertDocumentStoreException() {
+        Exception cause = new DocumentStoreException("foo");
+        DocumentStoreException dse = DocumentStoreException.convert(cause);
+        assertSame(cause, dse);
+    }
+
+    @Test
+    public void convertIOException() {
+        String msg = "foo";
+        Exception cause = new IOException(msg);
+        DocumentStoreException dse = DocumentStoreException.convert(cause);
+        assertEquals(msg, dse.getMessage());
+        assertSame(cause, dse.getCause());
+        assertEquals(GENERIC, dse.getType());
+    }
+
+    @Test
+    public void convertIOExceptionWithMessage() {
+        String msg = "foo";
+        Exception cause = new IOException();
+        DocumentStoreException dse = DocumentStoreException.convert(cause, 
msg);
+        assertEquals(msg, dse.getMessage());
+        assertSame(cause, dse.getCause());
+        assertEquals(GENERIC, dse.getType());
+    }
+
+    @Test
+    public void convertIOExceptionWithIDs() {
+        String msg = "foo";
+        List<String> ids = Lists.newArrayList("one", "two", "three");
+        Exception cause = new IOException(msg);
+        DocumentStoreException dse = DocumentStoreException.convert(cause, 
ids);
+        assertTrue(dse.getMessage().contains(msg));
+        for (String id : ids) {
+            assertTrue(dse.getMessage().contains(id));
+        }
+        assertSame(cause, dse.getCause());
+        assertEquals(GENERIC, dse.getType());
+    }
+
+    @Test
+    public void asDocumentStoreException() {
+        String msg = "foo";
+        Exception cause = new IOException();
+        Type type = TRANSIENT;
+        List<String> ids = Lists.newArrayList("one", "two", "three");
+        DocumentStoreException dse = 
DocumentStoreException.asDocumentStoreException(msg, cause, type, ids);
+        assertTrue(dse.getMessage().contains(msg));
+        for (String id : ids) {
+            assertTrue(dse.getMessage().contains(id));
+        }
+        assertSame(cause, dse.getCause());
+        assertEquals(type, dse.getType());
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreExceptionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to