make it subtree
[fanfix.git] / library / RemoteLibraryException.java
diff --git a/library/RemoteLibraryException.java b/library/RemoteLibraryException.java
new file mode 100644 (file)
index 0000000..4cbb631
--- /dev/null
@@ -0,0 +1,100 @@
+package be.nikiroo.fanfix.library;
+
+import java.io.IOException;
+
+/**
+ * Exceptions sent from remote to local.
+ * 
+ * @author niki
+ */
+public class RemoteLibraryException extends IOException {
+       private static final long serialVersionUID = 1L;
+
+       private boolean wrapped;
+
+       @SuppressWarnings("unused")
+       private RemoteLibraryException() {
+               // for serialization purposes
+       }
+
+       /**
+        * Wrap an {@link IOException} to allow it to pass across the network.
+        * 
+        * @param cause
+        *            the exception to wrap
+        * @param remote
+        *            this exception is used to send the contained
+        *            {@link IOException} to the other end of the network
+        */
+       public RemoteLibraryException(IOException cause, boolean remote) {
+               this(null, cause, remote);
+       }
+
+       /**
+        * Wrap an {@link IOException} to allow it to pass across the network.
+        * 
+        * @param message
+        *            the error message
+        * @param wrapped
+        *            this exception is used to send the contained
+        *            {@link IOException} to the other end of the network
+        */
+       public RemoteLibraryException(String message, boolean wrapped) {
+               this(message, null, wrapped);
+       }
+
+       /**
+        * Wrap an {@link IOException} to allow it to pass across the network.
+        * 
+        * @param message
+        *            the error message
+        * @param cause
+        *            the exception to wrap
+        * @param wrapped
+        *            this exception is used to send the contained
+        *            {@link IOException} to the other end of the network
+        */
+       public RemoteLibraryException(String message, IOException cause,
+                       boolean wrapped) {
+               super(message, cause);
+               this.wrapped = wrapped;
+       }
+
+       /**
+        * Return the actual exception we should return to the client code. It can
+        * be:
+        * <ul>
+        * <li>the <tt>cause</tt> if {@link RemoteLibraryException#isWrapped()} is
+        * TRUE</li>
+        * <li><tt>this</tt> if {@link RemoteLibraryException#isWrapped()} is FALSE
+        * (</li>
+        * <li><tt>this</tt> if the <tt>cause</tt> is NULL (so we never return NULL)
+        * </li>
+        * </ul>
+        * It is never NULL.
+        * 
+        * @return the unwrapped exception or <tt>this</tt>, never NULL
+        */
+       public synchronized IOException unwrapException() {
+               Throwable ex = super.getCause();
+               if (!isWrapped() || !(ex instanceof IOException)) {
+                       ex = this;
+               }
+
+               return (IOException) ex;
+       }
+
+       /**
+        * This exception is used to send the contained {@link IOException} to the
+        * other end of the network.
+        * <p>
+        * In other words, do not use <tt>this</tt> exception in client code when it
+        * has reached the other end of the network, but use its cause instead (see
+        * {@link RemoteLibraryException#unwrapException()}).
+        * 
+        * @return TRUE if it is
+        */
+       public boolean isWrapped() {
+               return wrapped;
+       }
+}