Author: ivaynberg
Date: Sat Oct 14 13:01:09 2006
New Revision: 464003

URL: http://svn.apache.org/viewvc?view=rev&rev=464003
Log:
made feedback more flexible by allowing Serializable as message object instead 
of only strings - also feedback message has a factory method for generating 
components to display errors instead of always using Lable

Added:
    
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/ValidationErrorFeedback.java
    
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/FeedbackPanel.html
    
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/FeedbackPanel.java
Modified:
    incubator/wicket/trunk/wicket/src/main/java/wicket/Component.java
    incubator/wicket/trunk/wicket/src/main/java/wicket/Session.java
    
incubator/wicket/trunk/wicket/src/main/java/wicket/feedback/FeedbackMessage.java
    
incubator/wicket/trunk/wicket/src/main/java/wicket/feedback/FeedbackMessages.java
    
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/FormComponent.java
    
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/validation/AbstractFormValidator.java
    
incubator/wicket/trunk/wicket/src/main/java/wicket/util/tester/WicketTester.java
    
incubator/wicket/trunk/wicket/src/main/java/wicket/validation/ValidationError.java
    
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/html/form/ValidatorPropertiesTest.java
    
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_4/FormTesterTest.java

Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/Component.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/Component.java?view=diff&rev=464003&r1=464002&r2=464003
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/Component.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/Component.java Sat Oct 
14 13:01:09 2006
@@ -810,7 +810,7 @@
         * @param message
         *            The feedback message
         */
-       public final void debug(final String message)
+       public final void debug(final Serializable message)
        {
                getPage().getFeedbackMessages().debug(this, message);
        }
@@ -839,7 +839,7 @@
         * @param message
         *            The feedback message
         */
-       public final void error(final String message)
+       public final void error(final Serializable message)
        {
                getPage().getFeedbackMessages().error(this, message);
        }
@@ -850,7 +850,7 @@
         * @param message
         *            The feedback message
         */
-       public final void fatal(final String message)
+       public final void fatal(final Serializable message)
        {
                getPage().getFeedbackMessages().fatal(this, message);
        }
@@ -1374,7 +1374,7 @@
         * @param message
         *            The feedback message
         */
-       public final void info(final String message)
+       public final void info(final Serializable message)
        {
                getPage().getFeedbackMessages().info(this, message);
        }
@@ -2456,7 +2456,7 @@
         * @param message
         *            The feedback message
         */
-       public final void warn(final String message)
+       public final void warn(final Serializable message)
        {
                getPage().getFeedbackMessages().warn(this, message);
        }

Modified: incubator/wicket/trunk/wicket/src/main/java/wicket/Session.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/Session.java?view=diff&rev=464003&r1=464002&r2=464003
==============================================================================
--- incubator/wicket/trunk/wicket/src/main/java/wicket/Session.java (original)
+++ incubator/wicket/trunk/wicket/src/main/java/wicket/Session.java Sat Oct 14 
13:01:09 2006
@@ -166,9 +166,10 @@
        private String style;
 
        /** feedback messages */
-       private FeedbackMessages feedbackMessages = new FeedbackMessages(new 
CopyOnWriteArrayList<FeedbackMessage>());
+       private FeedbackMessages feedbackMessages = new FeedbackMessages(
+                       new CopyOnWriteArrayList<FeedbackMessage>());
 
-       private transient Map<PageMap,Thread> pageMapsUsedInRequest;
+       private transient Map<PageMap, Thread> pageMapsUsedInRequest;
 
        /** cached id because you can't access the id after session unbound */
        private String id = null;
@@ -443,8 +444,7 @@
         * @return The page based on the first path component (the page id), or 
null
         *         if the requested version of the page cannot be found.
         */
-       public final Page getPage(final String pageMapName, final String path,
-                       final int versionNumber)
+       public final Page getPage(final String pageMapName, final String path, 
final int versionNumber)
        {
                if (log.isDebugEnabled())
                {
@@ -452,37 +452,42 @@
                }
 
                // Get page map by name, creating the default page map 
automatically
-               PageMap pageMap = pageMapForName(pageMapName, 
Objects.equal(PageMap.DEFAULT_NAME,pageMapName));
+               PageMap pageMap = pageMapForName(pageMapName, 
Objects.equal(PageMap.DEFAULT_NAME,
+                               pageMapName));
                if (pageMap != null)
                {
-                       synchronized(pageMapsUsedInRequest)
+                       synchronized (pageMapsUsedInRequest)
                        {
                                long startTime = System.currentTimeMillis();
-                               
+
                                if (pageMapsUsedInRequest == null)
                                {
                                        pageMapsUsedInRequest = new 
HashMap<PageMap, Thread>(3);
                                }
-                               
+
                                // Get page entry for id and version
                                Thread t = pageMapsUsedInRequest.get(pageMap);
                                while (t != null && t != Thread.currentThread())
                                {
                                        try
                                        {
-                                               
pageMapsUsedInRequest.wait(20000); // wait 20 seconds max.
+                                               
pageMapsUsedInRequest.wait(20000); // wait 20 seconds
+                                                                               
                                        // max.
                                        }
                                        catch (InterruptedException ex)
                                        {
                                                throw new 
WicketRuntimeException(ex);
                                        }
                                        t = pageMapsUsedInRequest.get(pageMap);
-                                       if (t != null && t != 
Thread.currentThread() && (startTime + 20000) < System.currentTimeMillis())
+                                       if (t != null && t != 
Thread.currentThread()
+                                                       && (startTime + 20000) 
< System.currentTimeMillis())
                                        {
-                                               // if it is still not the right 
thread.. 
-                                               // This must be a wicket bug or 
some other (dead)lock in the code.
-                                               throw new 
WicketRuntimeException("After 20s the Pagemap " + pageMapName + 
-                                                               " is still 
locked by: " + t + ", giving up trying to get the page for path: " + path);
+                                               // if it is still not the right 
thread..
+                                               // This must be a wicket bug or 
some other (dead)lock in
+                                               // the code.
+                                               throw new 
WicketRuntimeException("After 20s the Pagemap " + pageMapName
+                                                               + " is still 
locked by: " + t
+                                                               + ", giving up 
trying to get the page for path: " + path);
                                        }
                                }
                                pageMapsUsedInRequest.put(pageMap, 
Thread.currentThread());
@@ -790,14 +795,13 @@
                }
        }
 
-
        /**
         * Registers an informational feedback message for this session
         * 
         * @param message
         *            The feedback message
         */
-       public final void info(final String message)
+       public final void info(final Serializable message)
        {
                addFeedbackMessage(message, FeedbackMessage.INFO);
        }
@@ -808,7 +812,7 @@
         * @param message
         *            The feedback message
         */
-       public final void warn(final String message)
+       public final void warn(final Serializable message)
        {
                addFeedbackMessage(message, FeedbackMessage.WARNING);
        }
@@ -819,7 +823,7 @@
         * @param message
         *            The feedback message
         */
-       public final void error(final String message)
+       public final void error(final Serializable message)
        {
                addFeedbackMessage(message, FeedbackMessage.ERROR);
        }
@@ -863,7 +867,7 @@
         * @param level
         * 
         */
-       private void addFeedbackMessage(String message, int level)
+       private void addFeedbackMessage(Serializable message, int level)
        {
                getFeedbackMessages().add(null, message, level);
                dirty();
@@ -1061,8 +1065,9 @@
        {
                int size = feedbackMessages.size();
                feedbackMessages.clearRendered();
-               // mark the session as dirty when the feedback messages have 
been altered.
-               if(size != feedbackMessages.size())
+               // mark the session as dirty when the feedback messages have 
been
+               // altered.
+               if (size != feedbackMessages.size())
                {
                        dirty();
                }
@@ -1087,16 +1092,17 @@
         */
        final void requestDetached()
        {
-               if(pageMapsUsedInRequest != null)
+               if (pageMapsUsedInRequest != null)
                {
-                       synchronized(pageMapsUsedInRequest)
+                       synchronized (pageMapsUsedInRequest)
                        {
                                Thread t = Thread.currentThread();
-                               Iterator<Map.Entry<PageMap,Thread>> it = 
pageMapsUsedInRequest.entrySet().iterator();
-                               while(it.hasNext())
+                               Iterator<Map.Entry<PageMap, Thread>> it = 
pageMapsUsedInRequest.entrySet()
+                                               .iterator();
+                               while (it.hasNext())
                                {
                                        Entry<PageMap, Thread> entry = 
it.next();
-                                       if(entry.getValue() == t)
+                                       if (entry.getValue() == t)
                                        {
                                                it.remove();
                                        }
@@ -1105,7 +1111,7 @@
                        }
                }
        }
-       
+
        /**
         * @param map
         *            The page map to add to dirty objects list

Modified: 
incubator/wicket/trunk/wicket/src/main/java/wicket/feedback/FeedbackMessage.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/feedback/FeedbackMessage.java?view=diff&rev=464003&r1=464002&r2=464003
==============================================================================
--- 
incubator/wicket/trunk/wicket/src/main/java/wicket/feedback/FeedbackMessage.java
 (original)
+++ 
incubator/wicket/trunk/wicket/src/main/java/wicket/feedback/FeedbackMessage.java
 Sat Oct 14 13:01:09 2006
@@ -66,7 +66,7 @@
        private final int level;
 
        /** The actual message. */
-       private final String message;
+       private final Serializable message;
 
        /** The reporting component. */
        private final Component reporter;
@@ -84,7 +84,7 @@
         * @param level
         *            The level of the message
         */
-       public FeedbackMessage(final Component reporter, final String message, 
final int level)
+       public FeedbackMessage(final Component reporter, final Serializable 
message, final int level)
        {
                this.reporter = reporter;
                this.message = message;
@@ -138,7 +138,7 @@
         * 
         * @return the message.
         */
-       public final String getMessage()
+       public final Serializable getMessage()
        {
                return message;
        }

Modified: 
incubator/wicket/trunk/wicket/src/main/java/wicket/feedback/FeedbackMessages.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/feedback/FeedbackMessages.java?view=diff&rev=464003&r1=464002&r2=464003
==============================================================================
--- 
incubator/wicket/trunk/wicket/src/main/java/wicket/feedback/FeedbackMessages.java
 (original)
+++ 
incubator/wicket/trunk/wicket/src/main/java/wicket/feedback/FeedbackMessages.java
 Sat Oct 14 13:01:09 2006
@@ -59,20 +59,21 @@
        }
 
        /**
-        * Call this constructor if you want to replace the internal
-        * store with another implemention then the default (ArrayList). 
-        * This could be a [EMAIL PROTECTED] CopyOnWriteArrayList} if this 
feedbackmessages 
-        * instance is used by multiply threads.
+        * Call this constructor if you want to replace the internal store with
+        * another implemention then the default (ArrayList). This could be a
+        * [EMAIL PROTECTED] CopyOnWriteArrayList} if this feedbackmessages 
instance is used by
+        * multiply threads.
         * 
-        * @param messagesList 
+        * @param messagesList
         * 
         */
        public FeedbackMessages(List<FeedbackMessage> messagesList)
        {
-               if(messagesList == null) throw new 
IllegalArgumentException("messages list can't be null");
+               if (messagesList == null)
+                       throw new IllegalArgumentException("messages list can't 
be null");
                messages = messagesList;
        }
-       
+
        /**
         * Clears any existing messages
         */
@@ -115,7 +116,7 @@
         * @param message
         *            the actual message
         */
-       public final void debug(Component reporter, String message)
+       public final void debug(Component reporter, Serializable message)
        {
                add(new FeedbackMessage(reporter, message, 
FeedbackMessage.DEBUG));
        }
@@ -128,7 +129,7 @@
         * @param message
         *            the actual message
         */
-       public final void error(Component reporter, String message)
+       public final void error(Component reporter, Serializable message)
        {
                add(new FeedbackMessage(reporter, message, 
FeedbackMessage.ERROR));
        }
@@ -141,7 +142,7 @@
         * @param message
         *            the actual message
         */
-       public final void fatal(Component reporter, String message)
+       public final void fatal(Component reporter, Serializable message)
        {
                add(new FeedbackMessage(reporter, message, 
FeedbackMessage.FATAL));
        }
@@ -207,7 +208,7 @@
         * @param message
         *            The actual message
         */
-       public final void info(Component reporter, String message)
+       public final void info(Component reporter, Serializable message)
        {
                add(new FeedbackMessage(reporter, message, 
FeedbackMessage.INFO));
        }
@@ -286,7 +287,7 @@
         * @param message
         *            the actual message
         */
-       public final void warn(Component reporter, String message)
+       public final void warn(Component reporter, Serializable message)
        {
                add(new FeedbackMessage(reporter, message, 
FeedbackMessage.WARNING));
        }
@@ -298,7 +299,7 @@
         * @param message
         * @param level
         */
-       public final void add(Component reporter, String message, int level)
+       public final void add(Component reporter, Serializable message, int 
level)
        {
                add(new FeedbackMessage(reporter, message, level));
        }

Modified: 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/FormComponent.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/FormComponent.java?view=diff&rev=464003&r1=464002&r2=464003
==============================================================================
--- 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/FormComponent.java
 (original)
+++ 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/FormComponent.java
 Sat Oct 14 13:01:09 2006
@@ -97,7 +97,9 @@
  * @author Johan Compagner
  * @author Igor Vaynberg (ivaynberg)
  */
-public abstract class FormComponent<T> extends WebMarkupContainer<T> 
implements IFormProcessingListener
+public abstract class FormComponent<T> extends WebMarkupContainer<T>
+               implements
+                       IFormProcessingListener
 {
        private static final long serialVersionUID = 1L;
 
@@ -124,7 +126,7 @@
        }
 
        /**
-        * Visitor for traversing form components 
+        * Visitor for traversing form components
         */
        public static abstract class AbstractVisitor implements IVisitor
        {
@@ -133,8 +135,9 @@
                 */
                public Object formComponent(IFormProcessingListener component)
                {
-                       if (component instanceof FormComponent) {
-                               onFormComponent((FormComponent) component);
+                       if (component instanceof FormComponent)
+                       {
+                               onFormComponent((FormComponent)component);
                        }
                        return Component.IVisitor.CONTINUE_TRAVERSAL;
                }
@@ -608,7 +611,7 @@
        {
                if (!checkRequired())
                {
-                       error(new 
ValidationError().addMessageKey("RequiredValidator"));
+                       error((IValidationError)new 
ValidationError().addMessageKey("RequiredValidator"));
                }
        }
 
@@ -649,7 +652,7 @@
                                        error.setVar("format", 
((SimpleDateFormat)format).toLocalizedPattern());
                                }
 
-                               error(error);
+                               error((IValidationError)error);
 
                        }
                }
@@ -680,7 +683,7 @@
                                        error.setVar("format", 
((SimpleDateFormat)format).toLocalizedPattern());
                                }
 
-                               error(error);
+                               error((IValidationError)error);
                        }
                }
        }
@@ -838,12 +841,12 @@
        protected void onComponentTag(final ComponentTag tag)
        {
                tag.put("name", getInputName());
-               
+
                if (!isEnabled() || !isEnableAllowed())
                {
                        tag.put("disabled", "disabled");
                }
-               
+
                super.onComponentTag(tag);
        }
 
@@ -1064,7 +1067,12 @@
        }
 
        /**
-        * Reports a validation error against this form component
+        * Reports a validation error against this form component.
+        * 
+        * The actual error is reported by creating a
+        * [EMAIL PROTECTED] ValidationErrorFeedback} object that holds both 
the validation
+        * error and the generated error message - so a custom feedback panel 
can
+        * have access to both.
         * 
         * @param error
         *            validation error
@@ -1081,14 +1089,13 @@
                if (message == null)
                {
                        // XXX maybe make message source remember tried 
resource keys so a
-                       // more specific error message can be created
-                       error("Could not locate error message for error: " + 
error.toString());
-               }
-               else
-               {
-                       error(message);
+                       // more detailederror message can be created - like 
show which keys
+                       // were tried
+                       message = "Could not locate error message for error: " 
+ error.toString();
                }
 
+               error(new ValidationErrorFeedback(error, message));
+
        }
 
        /**
@@ -1273,6 +1280,6 @@
         */
        public boolean processChildren()
        {
-           return true;
+               return true;
        }
 }

Added: 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/ValidationErrorFeedback.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/ValidationErrorFeedback.java?view=auto&rev=464003
==============================================================================
--- 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/ValidationErrorFeedback.java
 (added)
+++ 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/ValidationErrorFeedback.java
 Sat Oct 14 13:01:09 2006
@@ -0,0 +1,103 @@
+/*
+ * $Id: org.eclipse.jdt.ui.prefs 5004 2006-03-17 20:47:08 -0800 (Fri, 17 Mar 
2006) eelco12 $
+ * $Revision: 5004 $
+ * $Date: 2006-03-17 20:47:08 -0800 (Fri, 17 Mar 2006) $
+ * 
+ * 
==============================================================================
+ * Licensed 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 wicket.markup.html.form;
+
+import java.io.Serializable;
+
+import wicket.Component;
+import wicket.validation.IMessageSource;
+import wicket.validation.IValidationError;
+
+/**
+ * This class is the parameter to [EMAIL PROTECTED] 
Component#error(Serializable)} instead
+ * of the generated error string itself (when
+ * [EMAIL PROTECTED] FormComponent#error(IValidationError)} is called). The 
advantage is
+ * that a custom feedback panel would still have access to the underlying
+ * [EMAIL PROTECTED] IValidationError} that generated the error message - 
providing much
+ * more context.
+ * 
+ * @author Igor Vaynberg (ivaynberg)
+ */
+public class ValidationErrorFeedback implements Serializable
+{
+       private static final long serialVersionUID = 1L;
+
+       /** error object */
+       private final IValidationError error;
+
+       /** error message */
+       private final String message;
+
+       /**
+        * Construct.
+        * 
+        * @param error
+        * @param message
+        */
+       public ValidationErrorFeedback(final IValidationError error, final 
String message)
+       {
+               if (error == null)
+               {
+                       throw new IllegalArgumentException("Argument [[error]] 
cannot be null");
+               }
+               this.error = error;
+               this.message = message;
+       }
+
+       /**
+        * Gets serialVersionUID.
+        * 
+        * @return serialVersionUID
+        */
+       public static long getSerialVersionUID()
+       {
+               return serialVersionUID;
+       }
+
+       /**
+        * Gets error.
+        * 
+        * @return error
+        */
+       public IValidationError getError()
+       {
+               return error;
+       }
+
+       /**
+        * Gets message.
+        * 
+        * @return message
+        */
+       public String getMessage()
+       {
+               return message;
+       }
+
+       /**
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public String toString()
+       {
+               return message;
+       }
+
+
+}

Modified: 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/validation/AbstractFormValidator.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/validation/AbstractFormValidator.java?view=diff&rev=464003&r1=464002&r2=464003
==============================================================================
--- 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/validation/AbstractFormValidator.java
 (original)
+++ 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/form/validation/AbstractFormValidator.java
 Sat Oct 14 13:01:09 2006
@@ -25,6 +25,7 @@
 import wicket.markup.html.form.FormComponent;
 import wicket.model.IModel;
 import wicket.util.lang.Classes;
+import wicket.validation.IValidationError;
 import wicket.validation.ValidationError;
 
 /**
@@ -140,7 +141,7 @@
                }
 
                error.setVars(vars);
-               fc.error(error);
+               fc.error((IValidationError)error);
        }
 
        /**

Added: 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/FeedbackPanel.html
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/FeedbackPanel.html?view=auto&rev=464003
==============================================================================
--- 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/FeedbackPanel.html
 (added)
+++ 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/FeedbackPanel.html
 Sat Oct 14 13:01:09 2006
@@ -0,0 +1,11 @@
+asdasdasd<html xmlns:wicket>
+<body>
+<wicket:panel>
+  <ul wicket:id="feedbackul">
+    <li wicket:id="messages" class="errorlevel">
+      <span wicket:id="message" class="errorlevel">A message</span>
+    </li>
+  </ul>
+</wicket:panel>
+</body>
+</html>

Added: 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/FeedbackPanel.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/FeedbackPanel.java?view=auto&rev=464003
==============================================================================
--- 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/FeedbackPanel.java
 (added)
+++ 
incubator/wicket/trunk/wicket/src/main/java/wicket/markup/html/panel/FeedbackPanel.java
 Sat Oct 14 13:01:09 2006
@@ -0,0 +1,318 @@
+/*
+ * $Id: FeedbackPanel.java 5844 2006-05-24 20:53:56 +0000 (Wed, 24 May 2006)
+ * joco01 $ $Revision: 461067 $ $Date: 2006-05-24 20:53:56 +0000 (Wed, 24 May
+ * 2006) $
+ * 
+ * 
==============================================================================
+ * Licensed 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 wicket.markup.html.panel;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import wicket.AttributeModifier;
+import wicket.Component;
+import wicket.MarkupContainer;
+import wicket.feedback.FeedbackMessage;
+import wicket.feedback.FeedbackMessagesModel;
+import wicket.feedback.IFeedback;
+import wicket.feedback.IFeedbackMessageFilter;
+import wicket.markup.html.WebMarkupContainer;
+import wicket.markup.html.basic.Label;
+import wicket.markup.html.list.ListItem;
+import wicket.markup.html.list.ListView;
+import wicket.model.IModel;
+import wicket.model.Model;
+
+/**
+ * A panel that displays [EMAIL PROTECTED] wicket.feedback.FeedbackMessage}s 
in a list
+ * view. The maximum number of messages to show can be set with
+ * setMaxMessages().
+ * 
+ * @see wicket.feedback.FeedbackMessage
+ * @see wicket.feedback.FeedbackMessages
+ * @author Jonathan Locke
+ * @author Eelco Hillenius
+ */
+public class FeedbackPanel extends Panel implements IFeedback
+{
+       private static final long serialVersionUID = 1L;
+
+       /** Message view */
+       private final MessageListView messageListView;
+
+       /**
+        * List for messages.
+        */
+       private final class MessageListView extends ListView<FeedbackMessage>
+       {
+               private static final long serialVersionUID = 1L;
+
+               /**
+                * @see wicket.Component#Component(MarkupContainer,String)
+                */
+               public MessageListView(MarkupContainer parent, final String id)
+               {
+                       super(parent, id);
+                       setModel(newFeedbackMessagesModel());
+               }
+
+               /**
+                * @see 
wicket.markup.html.list.ListView#populateItem(wicket.markup.html.list.ListItem)
+                */
+               @Override
+               protected void populateItem(final ListItem listItem)
+               {
+                       final FeedbackMessage message = 
(FeedbackMessage)listItem.getModelObject();
+                       message.markRendered();
+                       final IModel<String> replacementModel = new 
Model<String>()
+                       {
+                               private static final long serialVersionUID = 1L;
+
+                               /**
+                                * Returns feedbackPanel + the message level, eg
+                                * 'feedbackPanelERROR'. This is used as the 
class of the li /
+                                * span elements.
+                                * 
+                                * @see wicket.model.IModel#getObject()
+                                */
+                               @Override
+                               public String getObject()
+                               {
+                                       return getCSSClass(message);
+                               }
+                       };
+
+                       final Component label = 
newMessageDisplayComponent(listItem, "message", message);
+                       final AttributeModifier levelModifier = new 
AttributeModifier("class", replacementModel);
+                       label.add(levelModifier);
+                       listItem.add(levelModifier);
+               }
+       }
+
+       /**
+        * Generates a component that is used to display the message inside the
+        * feedback panel. This component must handle being attached to
+        * <code>span</code> tags.
+        * 
+        * By default a [EMAIL PROTECTED] Label} is used.
+        * 
+        * @param parent
+        *            component parent
+        * @param id
+        *            parent id
+        * @param message
+        *            feedback message
+        * @return component used to display the message
+        */
+       protected Component newMessageDisplayComponent(MarkupContainer parent, 
String id,
+                       FeedbackMessage message)
+       {
+               return new Label(parent, id, message.getMessage().toString());
+       }
+
+       /**
+        * @see wicket.Component#Component(MarkupContainer,String)
+        */
+       public FeedbackPanel(MarkupContainer parent, final String id)
+       {
+               this(parent, id, null);
+       }
+
+       /**
+        * @see wicket.Component#Component(MarkupContainer,String)
+        */
+       public FeedbackPanel(MarkupContainer parent, final String id, 
IFeedbackMessageFilter filter)
+       {
+               super(parent, id);
+               WebMarkupContainer messagesContainer = new 
WebMarkupContainer(this, "feedbackul")
+               {
+                       private static final long serialVersionUID = 1L;
+
+                       @Override
+                       public boolean isVisible()
+                       {
+                               return anyMessage();
+                       }
+               };
+               this.messageListView = new MessageListView(messagesContainer, 
"messages");
+               messageListView.setVersioned(false);
+
+               if (filter != null)
+               {
+                       setFilter(filter);
+               }
+       }
+
+
+       /**
+        * @return Model for feedback messages on which you can install filters 
and
+        *         other properties
+        */
+       public final FeedbackMessagesModel getFeedbackMessagesModel()
+       {
+               return (FeedbackMessagesModel)messageListView.getModel();
+       }
+
+       /**
+        * @return The current message filter
+        */
+       public final IFeedbackMessageFilter getFilter()
+       {
+               return getFeedbackMessagesModel().getFilter();
+       }
+
+       /**
+        * @return The current sorting comparator
+        */
+       public final Comparator getSortingComparator()
+       {
+               return getFeedbackMessagesModel().getSortingComparator();
+       }
+
+       /**
+        * @see wicket.Component#isVersioned()
+        */
+       @Override
+       public boolean isVersioned()
+       {
+               return false;
+       }
+
+       /**
+        * Sets a filter to use on the feedback messages model
+        * 
+        * @param filter
+        *            The message filter to install on the feedback messages 
model
+        */
+       public final void setFilter(IFeedbackMessageFilter filter)
+       {
+               getFeedbackMessagesModel().setFilter(filter);
+       }
+
+       /**
+        * @param maxMessages
+        *            The maximum number of feedback messages that this feedback
+        *            panel should show at one time
+        */
+       public final void setMaxMessages(int maxMessages)
+       {
+               this.messageListView.setViewSize(maxMessages);
+       }
+
+       /**
+        * Sets the comparator used for sorting the messages.
+        * 
+        * @param sortingComparator
+        *            comparator used for sorting the messages.
+        */
+       public final void setSortingComparator(Comparator<FeedbackMessage> 
sortingComparator)
+       {
+               
getFeedbackMessagesModel().setSortingComparator(sortingComparator);
+       }
+
+       /**
+        * @see wicket.feedback.IFeedback#updateFeedback()
+        */
+       public void updateFeedback()
+       {
+               // Force model to load
+               messageListView.getModelObject();
+       }
+
+       /**
+        * Search messages that this panel will render, and see if there is any
+        * message of level ERROR or up. This is a convenience method; same as
+        * calling 'anyMessage(FeedbackMessage.ERROR)'.
+        * 
+        * @return whether there is any message for this panel of level ERROR 
or up
+        */
+       public final boolean anyErrorMessage()
+       {
+               return anyMessage(FeedbackMessage.ERROR);
+       }
+
+       /**
+        * Search messages that this panel will render, and see if there is any
+        * message.
+        * 
+        * @return whether there is any message for this panel
+        */
+       public final boolean anyMessage()
+       {
+               return anyMessage(FeedbackMessage.UNDEFINED);
+       }
+
+       /**
+        * Search messages that this panel will render, and see if there is any
+        * message of the given level.
+        * 
+        * @param level
+        *            the level, see FeedbackMessage
+        * @return whether there is any message for this panel of the given 
level
+        */
+       public final boolean anyMessage(int level)
+       {
+               List msgs = getCurrentMessages();
+
+               for (Iterator i = msgs.iterator(); i.hasNext();)
+               {
+                       FeedbackMessage msg = (FeedbackMessage)i.next();
+                       if (msg.isLevel(level))
+                       {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * Gets the css class for the given message.
+        * 
+        * @param message
+        *            the message
+        * @return the css class; by default, this returns feedbackPanel + the
+        *         message level, eg 'feedbackPanelERROR', but you can override 
this
+        *         method to provide your own
+        */
+       protected String getCSSClass(final FeedbackMessage message)
+       {
+               return "feedbackPanel" + message.getLevelAsString();
+       }
+
+       /**
+        * Gets the currently collected messages for this panel.
+        * 
+        * @return the currently collected messages for this panel, possibly 
empty
+        */
+       protected final List<FeedbackMessage> getCurrentMessages()
+       {
+               final List<FeedbackMessage> messages = 
messageListView.getModelObject();
+               return Collections.unmodifiableList(messages);
+       }
+
+       /**
+        * Gets a new instance of FeedbackMessagesModel to use.
+        * 
+        * @return Instance of FeedbackMessagesModel to use
+        */
+       protected FeedbackMessagesModel newFeedbackMessagesModel()
+       {
+               return new FeedbackMessagesModel(getPage());
+       }
+
+}

Modified: 
incubator/wicket/trunk/wicket/src/main/java/wicket/util/tester/WicketTester.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/util/tester/WicketTester.java?view=diff&rev=464003&r1=464002&r2=464003
==============================================================================
--- 
incubator/wicket/trunk/wicket/src/main/java/wicket/util/tester/WicketTester.java
 (original)
+++ 
incubator/wicket/trunk/wicket/src/main/java/wicket/util/tester/WicketTester.java
 Sat Oct 14 13:01:09 2006
@@ -18,6 +18,7 @@
  */
 package wicket.util.tester;
 
+import java.io.Serializable;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
@@ -803,7 +804,7 @@
         */
        public void assertNoErrorMessage()
        {
-               List<String> messages = getMessages(FeedbackMessage.ERROR);
+               List<Serializable> messages = 
getMessages(FeedbackMessage.ERROR);
                Assert.assertTrue("expect no error message, but contains\n"
                                + WicketTesterHelper.asLined(messages), 
messages.isEmpty());
        }
@@ -813,7 +814,7 @@
         */
        public void assertNoInfoMessage()
        {
-               List<String> messages = getMessages(FeedbackMessage.INFO);
+               List<Serializable> messages = getMessages(FeedbackMessage.INFO);
                Assert.assertTrue("expect no info message, but contains\n"
                                + WicketTesterHelper.asLined(messages), 
messages.isEmpty());
        }
@@ -826,8 +827,13 @@
         */
        public void assertErrorMessages(String[] expectedErrorMessages)
        {
-               List<String> actualMessages = 
getMessages(FeedbackMessage.ERROR);
-               
WicketTesterHelper.assertEquals(Arrays.asList(expectedErrorMessages), 
actualMessages);
+               List<Serializable> actualMessages = 
getMessages(FeedbackMessage.ERROR);
+               List<String> msgs = new ArrayList<String>();
+               for (Serializable msg : actualMessages)
+               {
+                       msgs.add(msg.toString());
+               }
+               
WicketTesterHelper.assertEquals(Arrays.asList(expectedErrorMessages), msgs);
        }
 
        /**
@@ -838,7 +844,7 @@
         */
        public void assertInfoMessages(String[] expectedInfoMessages)
        {
-               List<String> actualMessages = getMessages(FeedbackMessage.INFO);
+               List<Serializable> actualMessages = 
getMessages(FeedbackMessage.INFO);
                
WicketTesterHelper.assertEquals(Arrays.asList(expectedInfoMessages), 
actualMessages);
        }
 
@@ -848,10 +854,10 @@
         * @param level
         *            level of feedback message, ex.
         *            <code>FeedbackMessage.DEBUG or FeedbackMessage.INFO.. 
etc</code>
-        * @return List list of messages (in String)
+        * @return List list of messages (in Serializable)
         * @see FeedbackMessage
         */
-       public List<String> getMessages(final int level)
+       public List<Serializable> getMessages(final int level)
        {
                FeedbackMessages feedbackMessages = 
getLastRenderedPage().getFeedbackMessages();
                List allMessages = feedbackMessages.messages(new 
IFeedbackMessageFilter()
@@ -863,7 +869,7 @@
                                return message.getLevel() == level;
                        }
                });
-               List<String> actualMessages = new ArrayList<String>();
+               List<Serializable> actualMessages = new 
ArrayList<Serializable>();
                for (Iterator iter = allMessages.iterator(); iter.hasNext();)
                {
                        
actualMessages.add(((FeedbackMessage)iter.next()).getMessage());
@@ -991,24 +997,24 @@
         * component by using:
         * 
         * <pre>
-        *      ...
-        *      component.add(new AjaxEventBehavior(ClientEvent.DBLCLICK) {
-        *          public void onEvent(AjaxRequestTarget) {
-        *              // Do something.
-        *          }
-        *      });
-        *      ...
+        *              ...
+        *              component.add(new 
AjaxEventBehavior(ClientEvent.DBLCLICK) {
+        *                  public void onEvent(AjaxRequestTarget) {
+        *                      // Do something.
+        *                  }
+        *              });
+        *              ...
         * </pre>
         * 
         * You can then test that the code inside onEvent actually does what 
it's
         * supposed to, using the WicketTester:
         * 
         * <pre>
-        *      ...
-        *      tester.executeAjaxEvent(component, ClientEvent.DBLCLICK);
-        *                
-        *      // Test that the code inside onEvent is correct.
-        *      ...
+        *              ...
+        *              tester.executeAjaxEvent(component, 
ClientEvent.DBLCLICK);
+        *                        
+        *              // Test that the code inside onEvent is correct.
+        *              ...
         * </pre>
         * 
         * PLEASE NOTE! This method doesn't actually insert the component in the

Modified: 
incubator/wicket/trunk/wicket/src/main/java/wicket/validation/ValidationError.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/main/java/wicket/validation/ValidationError.java?view=diff&rev=464003&r1=464002&r2=464003
==============================================================================
--- 
incubator/wicket/trunk/wicket/src/main/java/wicket/validation/ValidationError.java
 (original)
+++ 
incubator/wicket/trunk/wicket/src/main/java/wicket/validation/ValidationError.java
 Sat Oct 14 13:01:09 2006
@@ -18,6 +18,7 @@
  */
 package wicket.validation;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -40,8 +41,10 @@
  * 
  * @author ivaynberg
  */
-public final class ValidationError implements IValidationError
+public class ValidationError implements IValidationError, Serializable
 {
+       private static final long serialVersionUID = 1L;
+
        // XXX 2.0: optimization - keys can be null by default until a key is 
added
        /** List of message keys to try against the [EMAIL PROTECTED] 
IMessageSource} */
        private List<String> keys = new ArrayList<String>(1);
@@ -110,7 +113,7 @@
         * 
         * @return map of variables for this error
         */
-       public Map<String, Object> getVars()
+       public final Map<String, Object> getVars()
        {
                if (vars == null)
                {
@@ -126,7 +129,7 @@
         *            variable map
         * @return this for chaining
         */
-       public ValidationError setVars(Map<String, Object> vars)
+       public final ValidationError setVars(Map<String, Object> vars)
        {
                if (vars == null)
                {
@@ -140,7 +143,7 @@
         * @see 
wicket.validation.IValidationError#getErrorMessage(wicket.validation.IMessageSource)
         */
        @SuppressWarnings("unchecked")
-       public String getErrorMessage(IMessageSource messageSource)
+       public final String getErrorMessage(IMessageSource messageSource)
        {
                String errorMessage = null;
 
@@ -176,7 +179,7 @@
         * 
         * @return message
         */
-       public String getMessage()
+       public final String getMessage()
        {
                return message;
        }
@@ -190,7 +193,7 @@
         * 
         * @return this for chaining
         */
-       public ValidationError setMessage(String message)
+       public final ValidationError setMessage(String message)
        {
                if (message == null)
                {
@@ -200,6 +203,9 @@
                return this;
        }
 
+       /**
+        * @see java.lang.Object#toString()
+        */
        @Override
        public String toString()
        {

Modified: 
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/html/form/ValidatorPropertiesTest.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/test/java/wicket/markup/html/form/ValidatorPropertiesTest.java?view=diff&rev=464003&r1=464002&r2=464003
==============================================================================
--- 
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/html/form/ValidatorPropertiesTest.java
 (original)
+++ 
incubator/wicket/trunk/wicket/src/test/java/wicket/markup/html/form/ValidatorPropertiesTest.java
 Sat Oct 14 13:01:09 2006
@@ -66,28 +66,37 @@
                page.getText11().validateRequired();
                page.getText12().setInput("");
                page.getText12().validateRequired();
-               
-               String msg=page.getText1().getFeedbackMessage().getMessage();
 
-               assertEquals("text1label is required", 
page.getText1().getFeedbackMessage().getMessage());
-               assertEquals("text2 is required", 
page.getText2().getFeedbackMessage().getMessage());
-               assertEquals("ok: text3333 is missing", 
page.getText3().getFeedbackMessage().getMessage());
-               assertEquals("ok: Text4Label is missing", 
page.getText4().getFeedbackMessage().getMessage());
-               assertEquals("ok: text is missing", 
page.getText5().getFeedbackMessage().getMessage());
+               String msg = 
page.getText1().getFeedbackMessage().getMessage().toString();
+
+               assertEquals("text1label is required", 
page.getText1().getFeedbackMessage().getMessage()
+                               .toString());
+               assertEquals("text2 is required", 
page.getText2().getFeedbackMessage().getMessage()
+                               .toString());
+               assertEquals("ok: text3333 is missing", 
page.getText3().getFeedbackMessage().getMessage()
+                               .toString());
+               assertEquals("ok: Text4Label is missing", 
page.getText4().getFeedbackMessage().getMessage()
+                               .toString());
+               assertEquals("ok: text is missing", 
page.getText5().getFeedbackMessage().getMessage()
+                               .toString());
                assertEquals("Default message: text6 required", 
page.getText6().getFeedbackMessage()
-                               .getMessage());
+                               .getMessage().toString());
                assertEquals("input for text7-Label is missing", 
page.getText7().getFeedbackMessage()
-                               .getMessage());
+                               .getMessage().toString());
                assertEquals("Default message: text8-Label required", 
page.getText8().getFeedbackMessage()
-                               .getMessage());
-               assertEquals("found it in panel", 
page.getText9().getFeedbackMessage().getMessage());
-               assertEquals("found it in form", 
page.getText10().getFeedbackMessage().getMessage());
-               assertEquals("found it in page", 
page.getText11().getFeedbackMessage().getMessage());
-               assertEquals("found it in page", 
page.getText12().getFeedbackMessage().getMessage());
+                               .getMessage().toString());
+               assertEquals("found it in panel", 
page.getText9().getFeedbackMessage().getMessage()
+                               .toString());
+               assertEquals("found it in form", 
page.getText10().getFeedbackMessage().getMessage()
+                               .toString());
+               assertEquals("found it in page", 
page.getText11().getFeedbackMessage().getMessage()
+                               .toString());
+               assertEquals("found it in page", 
page.getText12().getFeedbackMessage().getMessage()
+                               .toString());
 
                // Test caching
                assertEquals("Default message: text8-Label required", 
page.getText8().getFeedbackMessage()
-                               .getMessage());
+                               .getMessage().toString());
        }
 
        /**

Modified: 
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_4/FormTesterTest.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_4/FormTesterTest.java?view=diff&rev=464003&r1=464002&r2=464003
==============================================================================
--- 
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_4/FormTesterTest.java
 (original)
+++ 
incubator/wicket/trunk/wicket/src/test/java/wicket/util/tester/apps_4/FormTesterTest.java
 Sat Oct 14 13:01:09 2006
@@ -65,6 +65,6 @@
                assertNull(page.getEmail());
                
assertTrue(page.getFeedbackMessages().hasMessageFor(page.get("form:email")));
                assertEquals("wrong email address pattern for email", 
page.getFeedbackMessages()
-                               
.messageForComponent(page.get("form:email")).getMessage());
+                               
.messageForComponent(page.get("form:email")).getMessage().toString());
        }
 }


Reply via email to