/*
* Copyright 2004, 2005, 2006 Odysseus Software GmbH
*
* 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 de.odysseus.calyxo.struts.forms;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import de.odysseus.calyxo.base.I18nSupport;
import de.odysseus.calyxo.base.Message;
import de.odysseus.calyxo.base.Messages;
import de.odysseus.calyxo.base.conf.ConfigException;
import de.odysseus.calyxo.forms.Form;
import de.odysseus.calyxo.forms.FormInputValues;
import de.odysseus.calyxo.forms.FormResult;
import de.odysseus.calyxo.forms.FormsSupport;
/**
* This class performs the form validation.
*
* @author Christoph Beck
*/
public class FormsDelegate implements Serializable {
private static final String FORMATTED_MESSAGE_KEY = "";
/**
* Transform a calyxo message into a struts action message.
* Calyxo messages and struts action messages differ in that
* calyxo messages may specify a bundle name.
* If the calyxo message specifies a bundle, this method will
* format the message and produce a struts action message
* with key <code>""</code> and the formatted message string
* as argument.
*
* @param request the request we're in
* @param locale the desired locale
* @param i18n 18n support instance
* @param message the message to be transformed
* @return a struts action message
*/
protected ActionMessage createActionMessage(
HttpServletRequest request,
Locale locale,
I18nSupport i18n,
Message message) {
ArrayList values = new ArrayList();
Iterator args = message.getArgs();
while (args.hasNext()) {
Message.Arg arg = (Message.Arg)args.next();
values.add(arg.getValue(locale, i18n));
}
if (message.getBundle() != null) {
String string = i18n.getMessage(
locale,
message.getBundle(),
message.getKey(),
values.toArray()
);
return new ActionMessage(FORMATTED_MESSAGE_KEY, string);
}
return new ActionMessage(message.getKey(), values.toArray());
}
protected ActionErrors doValidate(
ActionMapping mapping,
HttpServletRequest request,
FormInputValues inputs) throws Exception {
I18nSupport i18n = I18nSupport.getInstance(request);
Locale locale = i18n.getLocale(request);
FormsSupport support = FormsSupport.getInstance(request);
Form form = support.getForm(request, locale, mapping.getPath());
if (form == null) {
throw new ConfigException("No form for action '" + mapping.getPath() + "'");
}
ActionErrors errors = null;
// execute validation
FormResult result = form.validate(request, inputs);
if (!result.isValid()) { // collect error messages
errors = new ActionErrors();
Messages messages = result.getMessages();
Iterator names = messages.getKeys();
while (names.hasNext()) {
String name = (String)names.next();
if (name != Messages.GLOBAL_KEY) {
Message message = messages.getFirstMessage(name);
ActionMessage error =
createActionMessage(request, locale, i18n, message);
errors.add(name, error);
} else {
Iterator iter = messages.getGlobalMessages();
while (iter.hasNext()) {
Message message = (Message)iter.next();
ActionMessage error =
createActionMessage(request, locale, i18n, message);
errors.add(ActionMessages.GLOBAL_MESSAGE, error);
}
}
}
}
request.setAttribute(FormsSupport.FORM_RESULT_KEY, result);
return errors;
}
public ActionErrors handleException(Exception e) {
ActionErrors errors = new ActionErrors();
ActionMessage error =
new ActionMessage(FORMATTED_MESSAGE_KEY, e.getMessage());
errors.add(ActionMessages.GLOBAL_MESSAGE, error);
return errors;
}
/**
* Validate the properties that have been set for this HTTP request,
* and return an <code>ActionErrors</code> object that encapsulates any
* validation errors that have been found. If no errors are found,
* return <code>null</code> or an <code>ActionErrors</code> object with
* no recorded error messages.
* <p>
*
* @param mapping The mapping used to select this instance
* @param request The servlet request we are processing
*/
public ActionErrors validate(
ActionMapping mapping,
HttpServletRequest request,
FormInputValues inputs) {
try {
return doValidate(mapping, request, inputs);
} catch (Exception e) {
return handleException(e);
}
}
}