]> source.dussan.org Git - vaadin-framework.git/commitdiff
Refactor error messages on server side (#8437).
authorHenri Sara <hesara@vaadin.com>
Wed, 14 Mar 2012 10:32:21 +0000 (12:32 +0200)
committerArtur Signell <artur@vaadin.com>
Wed, 21 Mar 2012 15:42:34 +0000 (17:42 +0200)
This is an intermediate step towards moving error messages from UIDL to
shared state.

20 files changed:
src/com/vaadin/data/Buffered.java
src/com/vaadin/data/Validator.java
src/com/vaadin/terminal/AbstractErrorMessage.java [new file with mode: 0644]
src/com/vaadin/terminal/CompositeErrorMessage.java
src/com/vaadin/terminal/ErrorMessage.java
src/com/vaadin/terminal/SystemError.java
src/com/vaadin/terminal/UserError.java
src/com/vaadin/terminal/gwt/client/VCaption.java
src/com/vaadin/terminal/gwt/client/ui/ButtonConnector.java
src/com/vaadin/terminal/gwt/client/ui/CheckBoxConnector.java
src/com/vaadin/terminal/gwt/client/ui/FormConnector.java
src/com/vaadin/terminal/gwt/client/ui/LinkConnector.java
src/com/vaadin/terminal/gwt/client/ui/NativeButtonConnector.java
src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java
src/com/vaadin/terminal/gwt/client/ui/VPanel.java
src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java
src/com/vaadin/ui/AbstractField.java
src/com/vaadin/ui/Form.java
tests/testbench/com/vaadin/tests/components/checkbox/CheckBoxNullValue.java
tests/testbench/com/vaadin/tests/layouts/GridLayoutCaptions.java

index 552bd16d04c4458ea1a31401c1b132ab4dfe4da4..1387cb965b7959234a435c3d2d4bac16145a8506 100644 (file)
@@ -5,16 +5,8 @@
 package com.vaadin.data;
 
 import java.io.Serializable;
-import java.util.Collections;
-import java.util.List;
 
 import com.vaadin.data.Validator.InvalidValueException;
-import com.vaadin.terminal.ErrorMessage;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.SystemError;
-import com.vaadin.terminal.gwt.client.communication.SharedState;
-import com.vaadin.terminal.gwt.server.ClientMethodInvocation;
 
 /**
  * <p>
@@ -209,7 +201,7 @@ public interface Buffered extends Serializable {
      */
     @SuppressWarnings("serial")
     public class SourceException extends RuntimeException implements
-            ErrorMessage, Serializable {
+            Serializable {
 
         /** Source class implementing the buffered interface */
         private final Buffered source;
@@ -256,11 +248,7 @@ public interface Buffered extends Serializable {
         /**
          * Gets the cause of the exception.
          * 
-         * @return The cause for the exception.
-         * @throws MoreThanOneCauseException
-         *             if there is more than one cause for the exception. This
-         *             is possible if the commit operation triggers more than
-         *             one error at the same time.
+         * @return The (first) cause for the exception, null if no cause.
          */
         @Override
         public final Throwable getCause() {
@@ -288,88 +276,5 @@ public interface Buffered extends Serializable {
             return source;
         }
 
-        /**
-         * Gets the error level of this buffered source exception. The level of
-         * the exception is maximum error level of all the contained causes.
-         * <p>
-         * The causes that do not specify error level default to
-         * <code>ERROR</code> level. Also source exception without any causes
-         * are of level <code>ERROR</code>.
-         * </p>
-         * 
-         * @see com.vaadin.terminal.ErrorMessage#getErrorLevel()
-         */
-        public ErrorLevel getErrorLevel() {
-
-            ErrorLevel level = null;
-
-            for (int i = 0; i < causes.length; i++) {
-                final ErrorLevel causeLevel = (causes[i] instanceof ErrorMessage) ? ((ErrorMessage) causes[i])
-                        .getErrorLevel() : ErrorLevel.ERROR;
-                if (level == null) {
-                    level = causeLevel;
-                } else {
-                    if (causeLevel.intValue() > level.intValue()) {
-                        level = causeLevel;
-                    }
-                }
-            }
-
-            return level == null ? ErrorLevel.ERROR : level;
-        }
-
-        /* Documented in super interface */
-        public void paint(PaintTarget target) throws PaintException {
-            target.startTag("error");
-            target.addAttribute("level", getErrorLevel().getText());
-
-            // Paint all the exceptions
-            for (int i = 0; i < causes.length; i++) {
-                if (causes[i] instanceof ErrorMessage) {
-                    ((ErrorMessage) causes[i]).paint(target);
-                } else {
-                    new SystemError(causes[i]).paint(target);
-                }
-            }
-
-            target.endTag("error");
-
-        }
-
-        public SharedState getState() {
-            // TODO implement: move relevant parts from paint() to getState()
-            return null;
-        }
-
-        public List<ClientMethodInvocation> retrievePendingRpcCalls() {
-            return Collections.emptyList();
-        }
-
-        /* Documented in super interface */
-        public void addListener(RepaintRequestListener listener) {
-        }
-
-        /* Documented in super interface */
-        public void removeListener(RepaintRequestListener listener) {
-        }
-
-        /* Documented in super interface */
-        public void requestRepaint() {
-        }
-
-        /* Documented in super interface */
-        public void requestRepaintRequests() {
-        }
-
-        public String getDebugId() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        public void setDebugId(String id) {
-            throw new UnsupportedOperationException(
-                    "Setting testing id for this Paintable is not implemented");
-        }
-
     }
 }
index f07e957395f2ddacc2f42b91a4b8048d84fe129b..768a02babe5dc475a528d99459bf1f43fea72dac 100644 (file)
@@ -5,15 +5,8 @@
 package com.vaadin.data;
 
 import java.io.Serializable;
-import java.util.Collections;
-import java.util.List;
 
-import com.vaadin.terminal.ErrorMessage;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.communication.SharedState;
 import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
-import com.vaadin.terminal.gwt.server.ClientMethodInvocation;
 
 /**
  * Interface that implements a method for validating if an {@link Object} is
@@ -73,8 +66,7 @@ public interface Validator extends Serializable {
      * @since 3.0
      */
     @SuppressWarnings("serial")
-    public class InvalidValueException extends RuntimeException implements
-            ErrorMessage {
+    public class InvalidValueException extends RuntimeException {
 
         /**
          * Array of one or more validation errors that are causing this
@@ -138,113 +130,16 @@ public interface Validator extends Serializable {
             return true;
         }
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see com.vaadin.terminal.ErrorMessage#getErrorLevel()
-         */
-        public final ErrorLevel getErrorLevel() {
-            return ErrorLevel.ERROR;
-        }
-
-        /*
-         * (non-Javadoc)
-         * 
-         * @see
-         * com.vaadin.terminal.Paintable#paint(com.vaadin.terminal.PaintTarget)
-         */
-        public void paint(PaintTarget target) throws PaintException {
-            target.startTag("error");
-            target.addAttribute("level", ErrorLevel.ERROR.getText());
-
-            // Error message
-            final String message = getHtmlMessage();
-            if (message != null) {
-                target.addText(message);
-            }
-
-            // Paint all the causes
-            for (int i = 0; i < causes.length; i++) {
-                causes[i].paint(target);
-            }
-
-            target.endTag("error");
-        }
-
-        public SharedState getState() {
-            // TODO implement: move relevant parts from paint() to getState()
-            return null;
-        }
-
-        public List<ClientMethodInvocation> retrievePendingRpcCalls() {
-            return Collections.emptyList();
-        }
-
         /**
          * Returns the message of the error in HTML.
          * 
          * Note that this API may change in future versions.
          */
-        protected String getHtmlMessage() {
+        public String getHtmlMessage() {
             return AbstractApplicationServlet
                     .safeEscapeForHtml(getLocalizedMessage());
         }
 
-        /*
-         * (non-Javadoc)
-         * 
-         * @see
-         * com.vaadin.terminal.ErrorMessage#addListener(com.vaadin.terminal.
-         * Paintable.RepaintRequestListener)
-         */
-        public void addListener(RepaintRequestListener listener) {
-        }
-
-        /*
-         * (non-Javadoc)
-         * 
-         * @see
-         * com.vaadin.terminal.ErrorMessage#removeListener(com.vaadin.terminal
-         * .Paintable.RepaintRequestListener)
-         */
-        public void removeListener(RepaintRequestListener listener) {
-        }
-
-        /*
-         * (non-Javadoc)
-         * 
-         * @see com.vaadin.terminal.ErrorMessage#requestRepaint()
-         */
-        public void requestRepaint() {
-        }
-
-        /*
-         * (non-Javadoc)
-         * 
-         * @see com.vaadin.terminal.Paintable#requestRepaintRequests()
-         */
-        public void requestRepaintRequests() {
-        }
-
-        /*
-         * (non-Javadoc)
-         * 
-         * @see com.vaadin.terminal.Paintable#getDebugId()
-         */
-        public String getDebugId() {
-            return null;
-        }
-
-        /*
-         * (non-Javadoc)
-         * 
-         * @see com.vaadin.terminal.Paintable#setDebugId(java.lang.String)
-         */
-        public void setDebugId(String id) {
-            throw new UnsupportedOperationException(
-                    "InvalidValueException cannot have a debug id");
-        }
-
         /**
          * Returns the {@code InvalidValueExceptions} that caused this
          * exception.
diff --git a/src/com/vaadin/terminal/AbstractErrorMessage.java b/src/com/vaadin/terminal/AbstractErrorMessage.java
new file mode 100644 (file)
index 0000000..ce0238d
--- /dev/null
@@ -0,0 +1,172 @@
+/* 
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vaadin.data.Buffered;
+import com.vaadin.data.Validator;
+import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector;
+import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
+
+/**
+ * Base class for component error messages.
+ * 
+ * This class is used on the server side to construct the error messages to send
+ * to the client.
+ * 
+ * @since 7.0
+ */
+public abstract class AbstractErrorMessage implements ErrorMessage {
+
+    public enum ContentMode {
+        /**
+         * Content mode, where the error contains only plain text.
+         */
+        TEXT,
+        /**
+         * Content mode, where the error contains preformatted text.
+         */
+        PREFORMATTED,
+        /**
+         * Content mode, where the error contains XHTML.
+         */
+        XHTML;
+    }
+
+    /**
+     * Content mode.
+     */
+    private ContentMode mode = ContentMode.TEXT;
+
+    /**
+     * Message in content mode.
+     */
+    private String message;
+
+    /**
+     * Error level.
+     */
+    private ErrorLevel level = ErrorLevel.ERROR;
+
+    private List<ErrorMessage> causes = new ArrayList<ErrorMessage>();
+
+    protected AbstractErrorMessage(String message) {
+        this.message = message;
+    }
+
+    protected String getMessage() {
+        return message;
+    }
+
+    protected void setMessage(String message) {
+        this.message = message;
+    }
+
+    /* Documented in interface */
+    public ErrorLevel getErrorLevel() {
+        return level;
+    }
+
+    protected void setErrorLevel(ErrorLevel level) {
+        this.level = level;
+    }
+
+    protected ContentMode getMode() {
+        return mode;
+    }
+
+    protected void setMode(ContentMode mode) {
+        this.mode = mode;
+    }
+
+    protected List<ErrorMessage> getCauses() {
+        return causes;
+    }
+
+    protected void addCause(ErrorMessage cause) {
+        causes.add(cause);
+    }
+
+    @Deprecated
+    public void paint(PaintTarget target) throws PaintException {
+
+        // TODO if no message and only one cause, paint cause only? error level?
+
+        target.startTag(AbstractComponentConnector.ATTRIBUTE_ERROR);
+        target.addAttribute("level", level.getText());
+
+        paintContent(target);
+
+        target.endTag(AbstractComponentConnector.ATTRIBUTE_ERROR);
+    }
+
+    // TODO temporary method - move logic to client side
+    @Deprecated
+    protected void paintContent(PaintTarget target) throws PaintException {
+        // Paint the message
+        switch (getMode()) {
+        case TEXT:
+            target.addText(AbstractApplicationServlet
+                    .safeEscapeForHtml(getMessage()));
+            break;
+        case PREFORMATTED:
+            target.addText("<pre>"
+                    + AbstractApplicationServlet
+                            .safeEscapeForHtml(getMessage()) + "</pre>");
+            break;
+        case XHTML:
+            target.addText(getMessage());
+            break;
+        }
+
+        if (getCauses().size() > 0) {
+            for (ErrorMessage cause : getCauses()) {
+                cause.paint(target);
+            }
+        }
+    }
+
+    // TODO replace this with a helper method elsewhere?
+    public static ErrorMessage getErrorMessageForException(Throwable t) {
+        if (null == t) {
+            return null;
+        } else if (t instanceof ErrorMessage) {
+            // legacy case for custom error messages
+            return (ErrorMessage) t;
+        } else if (t instanceof Validator.InvalidValueException) {
+            UserError error = new UserError(
+                    ((Validator.InvalidValueException) t).getHtmlMessage(),
+                    ContentMode.XHTML, ErrorLevel.ERROR);
+            for (Validator.InvalidValueException nestedException : ((Validator.InvalidValueException) t)
+                    .getCauses()) {
+                error.addCause(getErrorMessageForException(nestedException));
+            }
+            return error;
+        } else if (t instanceof Buffered.SourceException) {
+            // no message, only the causes to be painted
+            UserError error = new UserError(null);
+            // in practice, this was always ERROR in Vaadin 6 unless tweaked in
+            // custom exceptions implementing ErrorMessage
+            error.setErrorLevel(ErrorLevel.ERROR);
+            // causes
+            for (Throwable nestedException : ((Buffered.SourceException) t)
+                    .getCauses()) {
+                error.addCause(getErrorMessageForException(nestedException));
+            }
+            return error;
+        } else {
+            return new SystemError(t);
+        }
+    }
+
+    /* Documented in superclass */
+    @Override
+    public String toString() {
+        return getMessage();
+    }
+
+}
index efe29196d86a385f400c34e12068c8af2e50cf39..b82b622f545e1f4d4f00c3e8f2888517a1032f19 100644 (file)
@@ -4,15 +4,8 @@
 
 package com.vaadin.terminal;
 
-import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Iterator;
-import java.util.List;
-
-import com.vaadin.terminal.gwt.client.communication.SharedState;
-import com.vaadin.terminal.gwt.server.ClientMethodInvocation;
 
 /**
  * Class for combining multiple error messages together.
@@ -23,17 +16,7 @@ import com.vaadin.terminal.gwt.server.ClientMethodInvocation;
  * @since 3.0
  */
 @SuppressWarnings("serial")
-public class CompositeErrorMessage implements ErrorMessage, Serializable {
-
-    /**
-     * Array of all the errors.
-     */
-    private final List<ErrorMessage> errors;
-
-    /**
-     * Level of the error.
-     */
-    private ErrorLevel level;
+public class CompositeErrorMessage extends AbstractErrorMessage {
 
     /**
      * Constructor for CompositeErrorMessage.
@@ -43,14 +26,14 @@ public class CompositeErrorMessage implements ErrorMessage, Serializable {
      *            ignored, but at least one message is required.
      */
     public CompositeErrorMessage(ErrorMessage[] errorMessages) {
-        errors = new ArrayList<ErrorMessage>(errorMessages.length);
-        level = ErrorLevel.INFORMATION;
+        super(null);
+        setErrorLevel(ErrorLevel.INFORMATION);
 
         for (int i = 0; i < errorMessages.length; i++) {
             addErrorMessage(errorMessages[i]);
         }
 
-        if (errors.size() == 0) {
+        if (getCauses().size() == 0) {
             throw new IllegalArgumentException(
                     "Composite error message must have at least one error");
         }
@@ -66,29 +49,20 @@ public class CompositeErrorMessage implements ErrorMessage, Serializable {
      */
     public CompositeErrorMessage(
             Collection<? extends ErrorMessage> errorMessages) {
-        errors = new ArrayList<ErrorMessage>(errorMessages.size());
-        level = ErrorLevel.INFORMATION;
+        super(null);
+        setErrorLevel(ErrorLevel.INFORMATION);
 
         for (final Iterator<? extends ErrorMessage> i = errorMessages
                 .iterator(); i.hasNext();) {
             addErrorMessage(i.next());
         }
 
-        if (errors.size() == 0) {
+        if (getCauses().size() == 0) {
             throw new IllegalArgumentException(
                     "Composite error message must have at least one error");
         }
     }
 
-    /**
-     * The error level is the largest error level in
-     * 
-     * @see com.vaadin.terminal.ErrorMessage#getErrorLevel()
-     */
-    public final ErrorLevel getErrorLevel() {
-        return level;
-    }
-
     /**
      * Adds a error message into this composite message. Updates the level
      * field.
@@ -97,10 +71,10 @@ public class CompositeErrorMessage implements ErrorMessage, Serializable {
      *            the error message to be added. Duplicate errors are ignored.
      */
     private void addErrorMessage(ErrorMessage error) {
-        if (error != null && !errors.contains(error)) {
-            errors.add(error);
-            if (error.getErrorLevel().intValue() > level.intValue()) {
-                level = error.getErrorLevel();
+        if (error != null && !getCauses().contains(error)) {
+            addCause(error);
+            if (error.getErrorLevel().intValue() > getErrorLevel().intValue()) {
+                setErrorLevel(error.getErrorLevel());
             }
         }
     }
@@ -111,53 +85,7 @@ public class CompositeErrorMessage implements ErrorMessage, Serializable {
      * @return the error iterator.
      */
     public Iterator<ErrorMessage> iterator() {
-        return errors.iterator();
-    }
-
-    /**
-     * @see com.vaadin.terminal.Paintable#paint(com.vaadin.terminal.PaintTarget)
-     */
-    public void paint(PaintTarget target) throws PaintException {
-
-        if (errors.size() == 1) {
-            (errors.iterator().next()).paint(target);
-        } else {
-            target.startTag("error");
-            target.addAttribute("level", level.getText());
-
-            // Paint all the exceptions
-            for (final Iterator<ErrorMessage> i = errors.iterator(); i
-                    .hasNext();) {
-                i.next().paint(target);
-            }
-
-            target.endTag("error");
-        }
-    }
-
-    public SharedState getState() {
-        // TODO implement: move relevant parts from paint() to getState()
-        return null;
-    }
-
-    public List<ClientMethodInvocation> retrievePendingRpcCalls() {
-        return Collections.emptyList();
-    }
-
-    /* Documented in super interface */
-    public void addListener(RepaintRequestListener listener) {
-    }
-
-    /* Documented in super interface */
-    public void removeListener(RepaintRequestListener listener) {
-    }
-
-    /* Documented in super interface */
-    public void requestRepaint() {
-    }
-
-    /* Documented in super interface */
-    public void requestRepaintRequests() {
+        return getCauses().iterator();
     }
 
     /**
@@ -169,7 +97,8 @@ public class CompositeErrorMessage implements ErrorMessage, Serializable {
     public String toString() {
         String retval = "[";
         int pos = 0;
-        for (final Iterator<ErrorMessage> i = errors.iterator(); i.hasNext();) {
+        for (final Iterator<ErrorMessage> i = getCauses().iterator(); i
+                .hasNext();) {
             if (pos > 0) {
                 retval += ",";
             }
@@ -180,13 +109,4 @@ public class CompositeErrorMessage implements ErrorMessage, Serializable {
 
         return retval;
     }
-
-    public String getDebugId() {
-        return null;
-    }
-
-    public void setDebugId(String id) {
-        throw new UnsupportedOperationException(
-                "Setting testing id for this Paintable is not implemented");
-    }
 }
index 5e55bfbcf65a6fb438935430bdcb648e3305b285..d0e8173883734d8322da4a7fe53cab39a435ea64 100644 (file)
@@ -15,7 +15,7 @@ import java.io.Serializable;
  * @VERSION@
  * @since 3.0
  */
-public interface ErrorMessage extends Paintable, Serializable {
+public interface ErrorMessage extends Serializable {
 
     public enum ErrorLevel {
         /**
@@ -111,31 +111,19 @@ public interface ErrorMessage extends Paintable, Serializable {
     public ErrorLevel getErrorLevel();
 
     /**
-     * Error messages are inmodifiable and thus listeners are not needed. This
-     * method should be implemented as empty.
+     * <p>
+     * Paints the error message into a UIDL stream. This method creates the UIDL
+     * sequence describing it and outputs it to the given UIDL stream.
+     * </p>
      * 
-     * @param listener
-     *            the listener to be added.
-     * @see com.vaadin.terminal.Paintable#addListener(Paintable.RepaintRequestListener)
+     * @param target
+     *            the target UIDL stream where the error should paint itself to.
+     * @throws PaintException
+     *             if the paint operation failed.
+     * @deprecated error messages should not be painted to UIDL but sent
+     *             differently
      */
-    public void addListener(RepaintRequestListener listener);
-
-    /**
-     * Error messages are inmodifiable and thus listeners are not needed. This
-     * method should be implemented as empty.
-     * 
-     * @param listener
-     *            the listener to be removed.
-     * @see com.vaadin.terminal.Paintable#removeListener(Paintable.RepaintRequestListener)
-     */
-    public void removeListener(RepaintRequestListener listener);
-
-    /**
-     * Error messages are inmodifiable and thus listeners are not needed. This
-     * method should be implemented as empty.
-     * 
-     * @see com.vaadin.terminal.Paintable#requestRepaint()
-     */
-    public void requestRepaint();
+    @Deprecated
+    public void paint(PaintTarget target) throws PaintException;
 
 }
index 462450422b7cead9cfd1d15b7866f84518f492aa..bae135ee6baefacffdcb350b68290d3e21afa6c5 100644 (file)
@@ -4,20 +4,12 @@
 
 package com.vaadin.terminal;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Collections;
-import java.util.List;
-
-import com.vaadin.terminal.gwt.client.communication.SharedState;
 import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
-import com.vaadin.terminal.gwt.server.ClientMethodInvocation;
 
 /**
- * <code>SystemError</code> is a runtime exception caused by error in system.
- * The system error can be shown to the user as it implements
- * <code>ErrorMessage</code> interface, but contains technical information such
- * as stack trace and exception.
+ * <code>SystemError</code> is an error message for a problem caused by error in
+ * system, not the user application code. The system error can contain technical
+ * information such as stack trace and exception.
  * 
  * SystemError does not support HTML in error messages or stack traces. If HTML
  * messages are required, use {@link UserError} or a custom implementation of
@@ -29,13 +21,7 @@ import com.vaadin.terminal.gwt.server.ClientMethodInvocation;
  * @since 3.0
  */
 @SuppressWarnings("serial")
-public class SystemError extends RuntimeException implements ErrorMessage {
-
-    /**
-     * The cause of the system error. The cause is stored separately as JDK 1.3
-     * does not support causes natively.
-     */
-    private Throwable cause = null;
+public class SystemError extends AbstractErrorMessage {
 
     /**
      * Constructor for SystemError with error message specified.
@@ -45,6 +31,9 @@ public class SystemError extends RuntimeException implements ErrorMessage {
      */
     public SystemError(String message) {
         super(message);
+        setErrorLevel(ErrorLevel.SYSTEMERROR);
+        setMode(ContentMode.XHTML);
+        setMessage(getHtmlMessage());
     }
 
     /**
@@ -56,8 +45,8 @@ public class SystemError extends RuntimeException implements ErrorMessage {
      *            the throwable causing the system error.
      */
     public SystemError(String message, Throwable cause) {
-        super(message);
-        this.cause = cause;
+        this(message);
+        addCause(AbstractErrorMessage.getErrorMessageForException(cause));
     }
 
     /**
@@ -67,40 +56,7 @@ public class SystemError extends RuntimeException implements ErrorMessage {
      *            the throwable causing the system error.
      */
     public SystemError(Throwable cause) {
-        this.cause = cause;
-    }
-
-    /**
-     * @see com.vaadin.terminal.ErrorMessage#getErrorLevel()
-     */
-    public final ErrorLevel getErrorLevel() {
-        return ErrorLevel.SYSTEMERROR;
-    }
-
-    /**
-     * @see com.vaadin.terminal.Paintable#paint(com.vaadin.terminal.PaintTarget)
-     */
-    public void paint(PaintTarget target) throws PaintException {
-
-        target.startTag("error");
-        target.addAttribute("level", ErrorLevel.SYSTEMERROR.getText());
-
-        String message = getHtmlMessage();
-
-        target.addXMLSection("div", message,
-                "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
-
-        target.endTag("error");
-
-    }
-
-    public SharedState getState() {
-        // TODO implement: move relevant parts from paint() to getState()
-        return null;
-    }
-
-    public List<ClientMethodInvocation> retrievePendingRpcCalls() {
-        return Collections.emptyList();
+        this(null, cause);
     }
 
     /**
@@ -109,61 +65,18 @@ public class SystemError extends RuntimeException implements ErrorMessage {
      * Note that this API may change in future versions.
      */
     protected String getHtmlMessage() {
+        // TODO wrapping div with namespace? See the old code:
+        // target.addXMLSection("div", message,
+        // "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
+
         StringBuilder sb = new StringBuilder();
-        final String message = getLocalizedMessage();
-        if (message != null) {
+        if (getMessage() != null) {
             sb.append("<h2>");
-            sb.append(AbstractApplicationServlet.safeEscapeForHtml(message));
+            sb.append(AbstractApplicationServlet
+                    .safeEscapeForHtml(getMessage()));
             sb.append("</h2>");
         }
-
-        // Paint the exception
-        if (cause != null) {
-            sb.append("<h3>Exception</h3>");
-            final StringWriter buffer = new StringWriter();
-            cause.printStackTrace(new PrintWriter(buffer));
-            sb.append("<pre>");
-            sb.append(AbstractApplicationServlet.safeEscapeForHtml(buffer
-                    .toString()));
-            sb.append("</pre>");
-        }
         return sb.toString();
     }
 
-    /**
-     * Gets cause for the error.
-     * 
-     * @return the cause.
-     * @see java.lang.Throwable#getCause()
-     */
-    @Override
-    public Throwable getCause() {
-        return cause;
-    }
-
-    /* Documented in super interface */
-    public void addListener(RepaintRequestListener listener) {
-    }
-
-    /* Documented in super interface */
-    public void removeListener(RepaintRequestListener listener) {
-    }
-
-    /* Documented in super interface */
-    public void requestRepaint() {
-    }
-
-    /* Documented in super interface */
-    public void requestRepaintRequests() {
-    }
-
-    public String getDebugId() {
-        return null;
-    }
-
-    public void setDebugId(String id) {
-        throw new UnsupportedOperationException(
-                "Setting testing id for this Paintable is not implemented");
-    }
-
 }
index 15473e47e1298b81aea738f3c905b6eaa8f91123..baaf331fa00c2fa78fae1e0da70f113785277320 100644 (file)
@@ -4,13 +4,6 @@
 
 package com.vaadin.terminal;
 
-import java.util.Collections;
-import java.util.List;
-
-import com.vaadin.terminal.gwt.client.communication.SharedState;
-import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
-import com.vaadin.terminal.gwt.server.ClientMethodInvocation;
-
 /**
  * <code>UserError</code> is a controlled error occurred in application. User
  * errors are occur in normal usage of the application and guide the user.
@@ -21,27 +14,7 @@ import com.vaadin.terminal.gwt.server.ClientMethodInvocation;
  * @since 3.0
  */
 @SuppressWarnings("serial")
-public class UserError implements ErrorMessage {
-
-    public enum ContentMode {
-        /**
-         * Content mode, where the error contains only plain text.
-         */
-        TEXT,
-        /**
-         * Content mode, where the error contains preformatted text.
-         */
-        PREFORMATTED,
-        /**
-         * Formatted content mode, where the contents is XML restricted to the
-         * UIDL 1.0 formatting markups.
-         */
-        UIDL,
-        /**
-         * Content mode, where the error contains XHTML.
-         */
-        XHTML;
-    }
+public class UserError extends AbstractErrorMessage {
 
     /**
      * @deprecated from 7.0, use {@link ContentMode#TEXT} instead Â  Â 
@@ -55,33 +28,12 @@ public class UserError implements ErrorMessage {
     @Deprecated
     public static final ContentMode CONTENT_PREFORMATTED = ContentMode.PREFORMATTED;
 
-    /**
-     * @deprecated from 7.0, use {@link ContentMode#UIDL} instead Â  Â 
-     */
-    @Deprecated
-    public static final ContentMode CONTENT_UIDL = ContentMode.UIDL;
-
     /**
      * @deprecated from 7.0, use {@link ContentMode#XHTML} instead Â  Â 
      */
     @Deprecated
     public static final ContentMode CONTENT_XHTML = ContentMode.XHTML;
 
-    /**
-     * Content mode.
-     */
-    private ContentMode mode = ContentMode.TEXT;
-
-    /**
-     * Message in content mode.
-     */
-    private final String msg;
-
-    /**
-     * Error level.
-     */
-    private ErrorLevel level = ErrorLevel.ERROR;
-
     /**
      * Creates a textual error message of level ERROR.
      * 
@@ -89,91 +41,20 @@ public class UserError implements ErrorMessage {
      *            the text of the error message.
      */
     public UserError(String textErrorMessage) {
-        msg = textErrorMessage;
+        super(textErrorMessage);
     }
 
     public UserError(String message, ContentMode contentMode,
             ErrorLevel errorLevel) {
+        super(message);
         if (contentMode == null) {
             contentMode = ContentMode.TEXT;
         }
         if (errorLevel == null) {
             errorLevel = ErrorLevel.ERROR;
         }
-        msg = message;
-        mode = contentMode;
-        level = errorLevel;
-    }
-
-    /* Documented in interface */
-    public ErrorLevel getErrorLevel() {
-        return level;
-    }
-
-    /* Documented in interface */
-    public void addListener(RepaintRequestListener listener) {
-    }
-
-    /* Documented in interface */
-    public void removeListener(RepaintRequestListener listener) {
-    }
-
-    /* Documented in interface */
-    public void requestRepaint() {
-    }
-
-    /* Documented in interface */
-    public void paint(PaintTarget target) throws PaintException {
-
-        target.startTag("error");
-        target.addAttribute("level", level.getText());
-
-        // Paint the message
-        switch (mode) {
-        case TEXT:
-            target.addText(AbstractApplicationServlet.safeEscapeForHtml(msg));
-            break;
-        case UIDL:
-            target.addUIDL(msg);
-            break;
-        case PREFORMATTED:
-            target.addText("<pre>"
-                    + AbstractApplicationServlet.safeEscapeForHtml(msg)
-                    + "</pre>");
-            break;
-        case XHTML:
-            target.addText(msg);
-            break;
-        }
-        target.endTag("error");
-    }
-
-    public SharedState getState() {
-        // TODO implement: move relevant parts from paint() to getState()
-        return null;
-    }
-
-    public List<ClientMethodInvocation> retrievePendingRpcCalls() {
-        return Collections.emptyList();
-    }
-
-    /* Documented in interface */
-    public void requestRepaintRequests() {
-    }
-
-    /* Documented in superclass */
-    @Override
-    public String toString() {
-        return msg;
-    }
-
-    public String getDebugId() {
-        return null;
-    }
-
-    public void setDebugId(String id) {
-        throw new UnsupportedOperationException(
-                "Setting testing id for this Paintable is not implemented");
+        setMode(contentMode);
+        setErrorLevel(errorLevel);
     }
 
 }
index 900c8b0680ca3605fa6da3b3d8445254f30a4598..40ade4199887e3f061a03f539e9b1e5e953adde2 100644 (file)
@@ -32,12 +32,12 @@ public class VCaption extends HTML {
 
     private int maxWidth = -1;
 
-    protected static final String ATTRIBUTE_ICON = "icon";
+    protected static final String ATTRIBUTE_ICON = AbstractComponentConnector.ATTRIBUTE_ICON;
     protected static final String ATTRIBUTE_CAPTION = "caption";
     protected static final String ATTRIBUTE_DESCRIPTION = "description";
-    protected static final String ATTRIBUTE_REQUIRED = "required";
-    protected static final String ATTRIBUTE_ERROR = "error";
-    protected static final String ATTRIBUTE_HIDEERRORS = "hideErrors";
+    protected static final String ATTRIBUTE_REQUIRED = AbstractComponentConnector.ATTRIBUTE_REQUIRED;
+    protected static final String ATTRIBUTE_ERROR = AbstractComponentConnector.ATTRIBUTE_ERROR;
+    protected static final String ATTRIBUTE_HIDEERRORS = AbstractComponentConnector.ATTRIBUTE_HIDEERRORS;
 
     private enum InsertPosition {
         ICON, CAPTION, REQUIRED, ERROR
index 903047171a9d8129046dbb1a71ea90a322367840..61807acbbfc1668a240a9f8b1c8b73c894edc15b 100644 (file)
@@ -74,7 +74,7 @@ public class ButtonConnector extends AbstractComponentConnector {
         getWidget().disableOnClick = getState().isDisableOnClick();
 
         // handle error
-        if (uidl.hasAttribute("error")) {
+        if (uidl.hasAttribute(ATTRIBUTE_ERROR)) {
             if (getWidget().errorIndicatorElement == null) {
                 getWidget().errorIndicatorElement = DOM.createSpan();
                 getWidget().errorIndicatorElement
index d842104fabf0b236bfdb68b83095783fa48ca7e1..751afa67e10e137d63fd77772bc723b886f76de2 100644 (file)
@@ -36,7 +36,7 @@ public class CheckBoxConnector extends AbstractFieldConnector {
         getWidget().blurHandlerRegistration = EventHelper.updateBlurHandler(
                 this, client, getWidget().blurHandlerRegistration);
 
-        if (uidl.hasAttribute("error")) {
+        if (uidl.hasAttribute(ATTRIBUTE_ERROR)) {
             if (getWidget().errorIndicatorElement == null) {
                 getWidget().errorIndicatorElement = DOM.createSpan();
                 getWidget().errorIndicatorElement.setInnerHTML("&nbsp;");
index ff3950f37dfd91322d2790928eb73ba6fd96ab13..a5b46b71909c84672027df843c3dce38668323c8 100644 (file)
@@ -64,7 +64,7 @@ public class FormConnector extends AbstractComponentContainerConnector
             getWidget().removeStyleDependentName("nocaption");
         }
 
-        if (uidl.hasAttribute("error")) {
+        if (uidl.hasAttribute(ATTRIBUTE_ERROR)) {
             final UIDL errorUidl = uidl.getErrors();
             getWidget().errorMessage.updateFromUIDL(errorUidl);
             getWidget().errorMessage.setVisible(true);
index 21172becff4776e894a0cd2145d53b19895b7e7e..28af9f6e52dbe60bbe15621b14883e0e685623a1 100644 (file)
@@ -60,7 +60,7 @@ public class LinkConnector extends AbstractComponentConnector {
         getWidget().captionElement.setInnerText(getState().getCaption());
 
         // handle error
-        if (uidl.hasAttribute("error")) {
+        if (uidl.hasAttribute(ATTRIBUTE_ERROR)) {
             if (getWidget().errorIndicatorElement == null) {
                 getWidget().errorIndicatorElement = DOM.createDiv();
                 DOM.setElementProperty(getWidget().errorIndicatorElement,
index 135fb4f676578c435693958ccd05d88ff2f8773c..834e08bf48c6ad4c9cf9cd9d3ffc97f5abf9bbd6 100644 (file)
@@ -51,7 +51,7 @@ public class NativeButtonConnector extends AbstractComponentConnector {
         getWidget().setText(getState().getCaption());
 
         // handle error
-        if (uidl.hasAttribute("error")) {
+        if (uidl.hasAttribute(ATTRIBUTE_ERROR)) {
             if (getWidget().errorIndicatorElement == null) {
                 getWidget().errorIndicatorElement = DOM.createSpan();
                 getWidget().errorIndicatorElement
index 26ddb84920e126a89f20e3af29b3239ccb414783..17f6f4785c08b87d75115ae3c09deab5945a234f 100644 (file)
@@ -351,7 +351,7 @@ public class VFormLayout extends SimplePanel {
 
         public void updateFromUIDL(UIDL uidl, ComponentConnector component) {
             owner = component;
-            if (uidl.hasAttribute("error")
+            if (uidl.hasAttribute(AbstractComponentConnector.ATTRIBUTE_ERROR)
                     && !uidl.getBooleanAttribute(AbstractComponentConnector.ATTRIBUTE_HIDEERRORS)) {
                 if (errorIndicatorElement == null) {
                     errorIndicatorElement = DOM.createDiv();
index b9552493ded2bf22a5e47596e3c1c60d3162f7d1..712799be2aad27145f96862ffd351382ad38e942 100644 (file)
@@ -115,7 +115,7 @@ public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner,
     }
 
     void handleError(UIDL uidl) {
-        if (uidl.hasAttribute("error")) {
+        if (uidl.hasAttribute(AbstractComponentConnector.ATTRIBUTE_ERROR)) {
             if (errorIndicatorElement == null) {
                 errorIndicatorElement = DOM.createSpan();
                 DOM.setElementProperty(errorIndicatorElement, "className",
index 2807cde33db9315438ab7bb83fc8c8025539c090..ffec6da3c54a1a8a40808abf01e33c63312514f0 100644 (file)
@@ -34,6 +34,7 @@ import com.vaadin.terminal.StreamVariable;
 import com.vaadin.terminal.ThemeResource;
 import com.vaadin.terminal.VariableOwner;
 import com.vaadin.terminal.gwt.client.Connector;
+import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector;
 import com.vaadin.ui.Alignment;
 import com.vaadin.ui.ClientWidget;
 import com.vaadin.ui.CustomLayout;
@@ -161,7 +162,7 @@ public class JsonPaintTarget implements PaintTarget {
 
         tag = new JsonTag(tagName);
 
-        if ("error".equals(tagName)) {
+        if (AbstractComponentConnector.ATTRIBUTE_ERROR.equals(tagName)) {
             errorsOpen++;
         }
 
@@ -204,10 +205,13 @@ public class JsonPaintTarget implements PaintTarget {
             }
 
             // simple hack which writes error uidl structure into attribute
-            if ("error".equals(lastTag)) {
+            if (AbstractComponentConnector.ATTRIBUTE_ERROR.equals(lastTag)) {
                 if (errorsOpen == 1) {
-                    parent.addAttribute("\"error\":[\"error\",{}"
-                            + tag.getData() + "]");
+                    parent.addAttribute("\""
+                            + AbstractComponentConnector.ATTRIBUTE_ERROR
+                            + "\":[\""
+                            + AbstractComponentConnector.ATTRIBUTE_ERROR
+                            + "\",{}" + tag.getData() + "]");
                 } else {
                     // sub error
                     parent.addData(tag.getJSON());
index 82d3d2af196ab5b1cd6ba31c0a3b16054d624698..742d39d83543ff378c01703d2f377ee47379008d 100644 (file)
@@ -26,6 +26,7 @@ import com.vaadin.data.util.converter.ConverterFactory;
 import com.vaadin.event.Action;
 import com.vaadin.event.ShortcutAction;
 import com.vaadin.event.ShortcutListener;
+import com.vaadin.terminal.AbstractErrorMessage;
 import com.vaadin.terminal.CompositeErrorMessage;
 import com.vaadin.terminal.ErrorMessage;
 import com.vaadin.terminal.PaintException;
@@ -1125,7 +1126,7 @@ public abstract class AbstractField<T> extends AbstractComponent implements
          * the requiredError string. For these fields the exclamation mark will
          * be hidden but the error must still be sent to the client.
          */
-        ErrorMessage validationError = null;
+        Validator.InvalidValueException validationError = null;
         if (isValidationVisible()) {
             try {
                 validate();
@@ -1146,8 +1147,13 @@ public abstract class AbstractField<T> extends AbstractComponent implements
         }
 
         // Throw combination of the error types
-        return new CompositeErrorMessage(new ErrorMessage[] { superError,
-                validationError, getCurrentBufferedSourceException() });
+        return new CompositeErrorMessage(
+                new ErrorMessage[] {
+                        superError,
+                        AbstractErrorMessage
+                                .getErrorMessageForException(validationError),
+                        AbstractErrorMessage
+                                .getErrorMessageForException(getCurrentBufferedSourceException()) });
 
     }
 
index 1abfefbc582f186c15f79fbbe6c81a42b1714945..a66c8e723bf959dc395ad7f284fc32125c92f9a3 100644 (file)
@@ -24,10 +24,12 @@ import com.vaadin.event.Action;
 import com.vaadin.event.Action.Handler;
 import com.vaadin.event.Action.ShortcutNotifier;
 import com.vaadin.event.ActionManager;
+import com.vaadin.terminal.AbstractErrorMessage;
 import com.vaadin.terminal.CompositeErrorMessage;
 import com.vaadin.terminal.ErrorMessage;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.UserError;
 import com.vaadin.terminal.gwt.client.ui.FormConnector;
 
 /**
@@ -242,15 +244,13 @@ public class Form extends AbstractField<Object> implements Item.Editor,
                     if (validationError != null) {
                         // Show caption as error for fields with empty errors
                         if ("".equals(validationError.toString())) {
-                            validationError = new Validator.InvalidValueException(
-                                    field.getCaption());
+                            validationError = new UserError(field.getCaption());
                         }
                         break;
                     } else if (f instanceof Field && !((Field<?>) f).isValid()) {
                         // Something is wrong with the field, but no proper
                         // error is given. Generate one.
-                        validationError = new Validator.InvalidValueException(
-                                field.getCaption());
+                        validationError = new UserError(field.getCaption());
                         break;
                     }
                 }
@@ -264,9 +264,12 @@ public class Form extends AbstractField<Object> implements Item.Editor,
         }
 
         // Throw combination of the error types
-        return new CompositeErrorMessage(new ErrorMessage[] {
-                getComponentError(), validationError,
-                currentBufferedSourceException });
+        return new CompositeErrorMessage(
+                new ErrorMessage[] {
+                        getComponentError(),
+                        validationError,
+                        AbstractErrorMessage
+                                .getErrorMessageForException(currentBufferedSourceException) });
     }
 
     /**
index a961b4842654900d04bbe1c46a41ec2ff5f904a5..2c981432c8755a16423cbc5447f87bfec6f9e0d0 100644 (file)
@@ -1,6 +1,7 @@
 package com.vaadin.tests.components.checkbox;
 
 import com.vaadin.data.Validator.InvalidValueException;
+import com.vaadin.terminal.AbstractErrorMessage;
 import com.vaadin.tests.components.TestBase;
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
@@ -34,12 +35,14 @@ public class CheckBoxNullValue extends TestBase {
                 try {
                     checkbox.validate();
                 } catch (InvalidValueException e) {
-                    checkbox.setComponentError(e);
+                    checkbox.setComponentError(AbstractErrorMessage
+                            .getErrorMessageForException(e));
                 }
                 try {
                     requiredCheckbox.validate();
                 } catch (InvalidValueException e) {
-                    requiredCheckbox.setComponentError(e);
+                    requiredCheckbox.setComponentError(AbstractErrorMessage
+                            .getErrorMessageForException(e));
                 }
                 valueLabel.setValue("Checkbox: " + checkbox.getValue()
                         + "; Required checkbox: " + requiredCheckbox.getValue());
index 987152f5298dcab5780397bfba4b760edc992803..1fe33d62cafeb7343fb14571941e9c19fb4f9e7c 100644 (file)
@@ -3,6 +3,7 @@ package com.vaadin.tests.layouts;
 import com.vaadin.data.Item;
 import com.vaadin.data.Validator;
 import com.vaadin.data.util.BeanItem;
+import com.vaadin.terminal.AbstractErrorMessage;
 import com.vaadin.tests.components.TestBase;
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
@@ -95,7 +96,9 @@ public class GridLayoutCaptions extends TestBase {
                     "Ipsum lipsum laarum lop... ");
 
             for (Object propIDs : getItemDataSource().getItemPropertyIds()) {
-                ((TextField) getField(propIDs)).setComponentError(ive);
+                ((TextField) getField(propIDs))
+                        .setComponentError(AbstractErrorMessage
+                                .getErrorMessageForException(ive));
 
             }