001 // Copyright 2011, 2012 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry5.kaptcha.components;
016
017 import org.apache.tapestry5.*;
018 import org.apache.tapestry5.annotations.Environmental;
019 import org.apache.tapestry5.annotations.Import;
020 import org.apache.tapestry5.annotations.Parameter;
021 import org.apache.tapestry5.annotations.SupportsInformalParameters;
022 import org.apache.tapestry5.corelib.base.AbstractField;
023 import org.apache.tapestry5.internal.TapestryInternalUtils;
024 import org.apache.tapestry5.ioc.Messages;
025 import org.apache.tapestry5.ioc.annotations.Inject;
026 import org.apache.tapestry5.kaptcha.KaptchaSymbolConstants;
027 import org.apache.tapestry5.services.FieldValidatorSource;
028 import org.apache.tapestry5.services.Request;
029
030 /**
031 * Field paired with a {@link KaptchaImage} to ensure that the user has provided
032 * the correct value.
033 *
034 * @since 5.3
035 * @tapestrydoc
036 */
037 @SupportsInformalParameters
038 @Import(stylesheet = "kaptcha.css")
039 public class KaptchaField extends AbstractField
040 {
041
042 /**
043 * The image output for this field. The image will display a distorted text
044 * string. The user must decode the distorted text and enter the same value.
045 */
046 @Parameter(required = true, defaultPrefix = BindingConstants.COMPONENT)
047 private KaptchaImage image;
048
049 /**
050 * Controls whether the field is rendered like a password field (false, the factory default)
051 * or like a normal text field (true).
052 *
053 * @see KaptchaSymbolConstants#KAPTCHA_DEFAULT_VISIBLE
054 * @since 5.3
055 */
056 @Parameter("symbol:" + KaptchaSymbolConstants.KAPTCHA_DEFAULT_VISIBLE)
057 private boolean visible;
058
059 @Inject
060 private Request request;
061
062 @Inject
063 private Messages messages;
064
065 @Inject
066 private ComponentResources resources;
067
068 @Environmental
069 private ValidationTracker validationTracker;
070
071 @Inject
072 private FieldValidatorSource fieldValidatorSource;
073
074 /**
075 * Always required.
076 */
077 @Override
078 public boolean isRequired()
079 {
080 return true;
081 }
082
083 @Override
084 protected void processSubmission(String controlName)
085 {
086 String userValue = request.getParameter(controlName);
087
088 validationTracker.recordInput(this, userValue);
089
090 if (TapestryInternalUtils.isEqual(image.getCaptchaText(), userValue))
091 return;
092
093 validationTracker.recordError(this, messages.get("tapestry-incorrect-captcha"));
094 }
095
096 @SuppressWarnings("rawtypes")
097 boolean beginRender(MarkupWriter writer)
098 {
099 writer.element("input",
100
101 "type", visible ? "text" : "password",
102
103 "id", getClientId(),
104
105 "name", getControlName(),
106
107 "value", visible ? validationTracker.getInput(this) : "");
108
109 resources.renderInformalParameters(writer);
110
111 FieldValidator fieldValidator = fieldValidatorSource.createValidator(this, "required", null);
112
113 fieldValidator.render(writer);
114
115 writer.end();
116
117 return false;
118 }
119 }