jodd.servlet.form.FormProcessorVisitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jodd-servlet Show documentation
Show all versions of jodd-servlet Show documentation
Jodd Servlet is set of web tools, including the nice tag library, wrappers and some filters.
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package jodd.servlet.form;
import jodd.lagarto.Tag;
import jodd.lagarto.TagType;
import jodd.lagarto.visitor.TagWriter;
import jodd.mutable.MutableInteger;
import jodd.util.CharSequenceUtil;
import jodd.util.StringUtil;
import java.util.HashMap;
import java.util.Map;
/**
* Form processor. Invokes {@link jodd.servlet.form.FormFieldResolver} on form fields.
*/
public class FormProcessorVisitor extends TagWriter {
private static final String INPUT = "input";
private static final String SELECT = "select";
private static final String OPTION = "option";
private static final String TEXTAREA = "textarea";
private static final String TYPE = "type";
private static final String VALUE = "value";
private static final String NAME = "name";
private static final String TEXT = "text";
private static final String HIDDEN = "hidden";
private static final String IMAGE = "image";
private static final String PASSWORD = "password";
private static final String CHECKBOX = "checkbox";
private static final String TRUE = "true";
private static final String CHECKED = "checked";
private static final String RADIO = "radio";
private static final String SELECTED = "selected";
private final FormFieldResolver resolver;
public FormProcessorVisitor(final Appendable appendable, final FormFieldResolver resolver) {
super(appendable);
this.resolver = resolver;
}
@Override
public void tag(final Tag tag) {
if (tag.getType().isStartingTag()) {
if (CharSequenceUtil.equalsToLowercase(tag.getName(), INPUT)) {
processInputStartTag(tag);
super.tag(tag);
return;
}
if (inSelect && CharSequenceUtil.equalsToLowercase(tag.getName(), OPTION)) {
processOptionOpenTag(tag);
super.tag(tag);
return;
}
}
if (tag.getType() == TagType.START) {
if (CharSequenceUtil.equalsToLowercase(tag.getName(), TEXTAREA)) {
processTextareaStartTag(tag);
}
else if (CharSequenceUtil.equalsToLowercase(tag.getName(), SELECT)) {
processSelectOpenTag(tag);
}
}
else if (tag.getType() == TagType.END) {
if (inTextArea && CharSequenceUtil.equalsToLowercase(tag.getName(), TEXTAREA)) {
processTextareaEndTag();
}
else if (inSelect && CharSequenceUtil.equalsToLowercase(tag.getName(), SELECT)) {
processSelectEndTag();
}
}
super.tag(tag);
}
@Override
public void text(final CharSequence text) {
if (inTextArea) {
return;
}
super.text(text);
}
// ---------------------------------------------------------------- input
private void processInputStartTag(final Tag tag) {
// INPUT
final CharSequence tagType = tag.getAttributeValue(TYPE);
if (tagType == null) {
return;
}
final CharSequence nameSequence = tag.getAttributeValue(NAME);
if (nameSequence == null) {
return;
}
final String name = nameSequence.toString();
final Object valueObject = resolver.value(name);
if (valueObject == null) {
return;
}
final String tagTypeName = tagType.toString().toLowerCase();
if (
tagTypeName.equals(TEXT) ||
tagTypeName.equals(HIDDEN) ||
tagTypeName.equals(IMAGE) ||
tagTypeName.equals(PASSWORD)) {
final String value = valueToString(name, valueObject);
if (value == null) {
return;
}
tag.setAttribute(VALUE, value);
}
else if (tagTypeName.equals(CHECKBOX)) {
CharSequence tagValue = tag.getAttributeValue(VALUE);
if (tagValue == null) {
tagValue = TRUE;
}
tagValue = tagValue.toString();
if (valueObject.getClass().isArray()) {
// checkbox group
final String[] vs = StringUtil.toStringArray(valueObject);
for (final String vsk : vs) {
if ((vsk != null) && (vsk.contentEquals(tagValue))) {
tag.setAttribute(CHECKED, null);
}
}
} else if (tagValue.equals(valueObject.toString())) {
tag.setAttribute(CHECKED, null);
}
}
else if (tagType.equals(RADIO)) {
CharSequence tagValue = tag.getAttributeValue(VALUE);
if (tagValue != null) {
tagValue = tagValue.toString();
if (tagValue.equals(valueObject.toString())) {
tag.setAttribute(CHECKED, null);
}
}
}
}
// ---------------------------------------------------------------- convert values to string
protected Map valueNameIndexes;
/**
* Converts value to a string.
*/
protected String valueToString(final String name, final Object valueObject) {
if (!valueObject.getClass().isArray()) {
return valueObject.toString();
}
// array
final String[] array = (String[]) valueObject;
if (valueNameIndexes == null) {
valueNameIndexes = new HashMap<>();
}
MutableInteger index = valueNameIndexes.get(name);
if (index == null) {
index = new MutableInteger(0);
valueNameIndexes.put(name, index);
}
if (index.value >= array.length) {
return null;
}
final String result = array[index.value];
index.value++;
return result;
}
// ---------------------------------------------------------------- select
private boolean inSelect;
private String currentSelectName;
private void processSelectOpenTag(final Tag tag) {
final CharSequence name = tag.getAttributeValue(NAME);
if (name == null) {
return;
}
currentSelectName = name.toString();
inSelect = true;
}
private void processSelectEndTag() {
inSelect = false;
currentSelectName = null;
}
private void processOptionOpenTag(final Tag tag) {
CharSequence tagValue = tag.getAttributeValue(VALUE);
if (tagValue == null) {
return;
}
final Object vals = resolver.value(currentSelectName);
if (vals == null) {
return;
}
tagValue = tagValue.toString();
if (vals.getClass().isArray()) {
final String[] vs = StringUtil.toStringArray(vals);
for (final String vsk : vs) {
if ((vsk != null) && (vsk.contentEquals(tagValue))) {
tag.setAttribute(SELECTED, null);
}
}
} else {
final String value = StringUtil.toString(vals);
if (value.contentEquals(tagValue)) {
tag.setAttribute(SELECTED, null);
}
}
}
// ---------------------------------------------------------------- textarea
private String textAreaValue;
private boolean inTextArea;
private void processTextareaStartTag(final Tag tag) {
inTextArea = true;
final CharSequence name = tag.getAttributeValue(NAME);
if (name == null) {
return;
}
final Object valueObject = resolver.value(name.toString());
if (valueObject != null) {
textAreaValue = valueObject.toString();
}
}
private void processTextareaEndTag() {
inTextArea = false;
if (textAreaValue == null) {
return;
}
super.text(textAreaValue);
textAreaValue = null;
}
}