/*
* 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.forms.view;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import de.odysseus.calyxo.base.conf.ConfigException;
import de.odysseus.calyxo.forms.Form;
import de.odysseus.calyxo.forms.FormData;
import de.odysseus.calyxo.forms.FormInput;
import de.odysseus.calyxo.forms.FormInputResult;
import de.odysseus.calyxo.forms.FormResult;
import de.odysseus.calyxo.forms.FormsSupport;
/**
* Form context.
* Serves input values and css styles for nested components.
*
* @author Christoph Beck
*/
public class FormContext {
private static final String DEFAULT_ASSERT_STYLE = "background-color: orange;";
private static final String DEFAULT_ERROR_STYLE = "background-color: red;";
public static final String NOT_AVAILABLE = new String();
public static final String[] NOT_AVAILABLE_ARRAY = new String[]{};
private final Form form;
private final FormResult result;
private final FormData data;
private final HttpServletRequest request;
private final FormComponentStyles styles;
private HashMap componentData;
/**
* Constructor.
* @param request underlying request
* @param action module-relative action path
* @param styles default component styles
* @param create lazy form data creation
*/
public FormContext(
HttpServletRequest request,
String action,
FormComponentStyles styles,
boolean create) throws Exception {
super();
FormsSupport support = FormsSupport.getInstance(request);
form = support.getForm(request, action);
if (form == null) {
throw new ConfigException("Cannot find form for action'" + action + "'!");
}
result = support.getFormResult(request, action);
if (result == null) {
data = support.getFormData(request, action, create);
} else {
data = null;
}
this.request = request;
this.styles = styles;
}
/**
* Answer true if the specified component corresponds to an array input
* and has no index set (eg. a multiple selection).
*/
public boolean isMultiple(FormComponent component) {
return form.getFormInput(component.getName()).isArray() && component.getIndex() < 0;
}
/**
* Check if the specified component corresponds to an input in this form.
*/
public void check(FormComponent component) throws ConfigException {
FormInput input = form.getFormInput(component.getName());
if (input == null) {
throw new ConfigException("Input '" + component.getName() + "' does not exist!");
}
if (!input.isArray() && component.getIndex() >= 0) {
throw new ConfigException("Input '" + component.getName() + "' is not an array, but has an index!");
}
}
/**
* Get value for specified component.
*/
public String getInputValue(FormComponent component) throws Exception {
FormInput input = form.getFormInput(component.getName());
if (input.isArray()) {
int index = component.getIndex();
if (index < 0) {
throw new ConfigException("Input '" + component.getName() + "' has no index");
}
if (result != null) {
FormInputResult inputResult = result.getFormInputResult(component.getName());
if (index >= inputResult.getSize()) {
return NOT_AVAILABLE;
}
return inputResult.format(request, index);
} else if (data != null) {
return input.format(request, data, index, NOT_AVAILABLE);
}
} else {
if (result != null) {
return (String)result.getFormInputResult(component.getName()).format(request);
} else if (data != null) {
return (String)input.format(request, data);
}
}
return NOT_AVAILABLE;
}
/**
* Get value array for specified component.
*/
public String[] getInputValues(FormComponent component) throws Exception {
FormInput input = form.getFormInput(component.getName());
if (!input.isArray()) {
throw new ConfigException("Input '" + component.getName() + "' is not an array");
}
if (result != null) {
return (String[])result.getFormInputResult(component.getName()).format(request);
} else if (data != null) {
return (String[])input.format(request, data);
} else {
return NOT_AVAILABLE_ARRAY;
}
}
/**
* Answer true iff the specified component is involved in a failed assertion..
*/
private boolean isAssertionFailed(FormComponent component) {
return result != null && result.isAssertionFailed(component.getName());
}
/**
* Answer true iff the specified component is valid.
*/
private boolean isValidOrRelaxed(FormComponent component) {
if (result != null) {
FormInputResult inputResult = result.getFormInputResult(component.getName());
if (inputResult.isRelaxed()) {
return true;
}
int index = component.getIndex();
return index < 0 ? inputResult.isValid() : inputResult.isValid(index);
}
return true;
}
/**
* Get CSS class attribute for the specified component
*/
public String getClass(FormComponent component) {
String result = null;
if (!isValidOrRelaxed(component)) {
result = component.getErrorClass();
if (result == null) {
result = styles.getErrorClass();
}
} else if (isAssertionFailed(component)) {
result = component.getAssertClass();
if (result == null) {
result = styles.getAssertClass();
if (result == null) {
result = component.getErrorClass();
if (result == null) {
result = styles.getErrorClass();
}
}
}
}
return result;
}
/**
* Get CSS style attribute for the specified component
*/
public String getStyle(FormComponent component) {
String result = null;
if (!isValidOrRelaxed(component)) {
result = component.getErrorStyle();
if (result == null) {
result = styles.getErrorStyle();
if (result == null) {
if (component.getErrorClass() == null && styles.getErrorClass() == null) {
result = DEFAULT_ERROR_STYLE;
}
}
}
} else if (isAssertionFailed(component)) {
result = component.getAssertStyle();
if (result == null) {
result = styles.getAssertStyle();
if (result == null) {
if (component.getAssertClass() == null && styles.getAssertClass() == null) {
result = component.getErrorStyle();
if (result == null) {
result = styles.getErrorStyle();
if (result == null) {
if (component.getErrorClass() == null && styles.getErrorClass() == null) {
result = DEFAULT_ASSERT_STYLE;
}
}
}
}
}
}
}
return result;
}
/**
* Store component data
*/
public void putComponentData(FormComponent component, Object value) {
if (componentData == null) {
componentData = new HashMap(8);
}
componentData.put(component.getName() + component.getIndex(), value);
}
/**
* Get component data
*/
public Object getComponentData(FormComponent component) {
if (componentData == null) {
return null;
}
return componentData.get(component.getName() + component.getIndex());
}
}