/**
* Copyright 2008-2016 Qualogy Solutions B.V.
*
* 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 com.qualogy.qafe.gwt.client.component;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.event.dom.client.HandlesAllKeyEvents;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.user.client.ui.TextBox;
import com.qualogy.qafe.gwt.client.vo.ui.TextFieldGVO;
public class QTextField extends TextBox implements HasData, HasDataChangeHandlers, HasEditable, HasRequiredValidationMessage {
public static final String EMPTY_VALUE = "";
public static final int ASCII_SPECIAL_CHARS_THRESHOLD = 40;
public static final String RESTRICTION_REGEXP_TYPE_INTEGER_VALUE= "^[-]?[0-9]+$";
public static final String RESTRICTION_REGEXP_TYPE_SIGNED_INTEGER_VALUE="[0-9]+$";
public static final String RESTRICTION_REGEXP_TYPE_DOUBLE_VALUE= "^[-]?[0-9]*[\\.]?[0-9]*$";
public static final String RESTRICTION_REGEXP_TYPE_CHARACTERS_VALUE="^[a-zA-Z]+$";
public static final String RESTRICTION_REGEXP_TYPE_EMAIL_VALUE="[0-9a-zA-Z-,\\._@]*";
private String oldValue = EMPTY_VALUE;
private List<DataChangeHandler> dataChangeHandlers = new ArrayList<DataChangeHandler>();
private String keyRestrictionRegExp = null;
private String requiredValidationMessage;
private String requiredValidationTitle;
public QTextField(TextFieldGVO gvo) {
init(gvo);
registerKeyEvents();
}
private void init(TextFieldGVO gvo) {
if (TextFieldGVO.TYPE_CHARACTERS.equals(gvo.getType())){
keyRestrictionRegExp = RESTRICTION_REGEXP_TYPE_CHARACTERS_VALUE;
} else if (TextFieldGVO.TYPE_DOUBLE.equals(gvo.getType())){
keyRestrictionRegExp = RESTRICTION_REGEXP_TYPE_DOUBLE_VALUE;
} else if (TextFieldGVO.TYPE_EMAIL.equals(gvo.getType())){
keyRestrictionRegExp = RESTRICTION_REGEXP_TYPE_EMAIL_VALUE;
} else if (TextFieldGVO.TYPE_INTEGER.equals(gvo.getType())){
keyRestrictionRegExp = RESTRICTION_REGEXP_TYPE_INTEGER_VALUE;
} else if (TextFieldGVO.TYPE_SIGNED_INTEGER.equals(gvo.getType())){
keyRestrictionRegExp = RESTRICTION_REGEXP_TYPE_SIGNED_INTEGER_VALUE;
}
}
public Object getData() {
return getText();
}
public void setData(Object data, String action, Object mapping) {
String text = (String)data;
setText(text);
}
public void setText(String text) {
rememberValue();
super.setText(validateType(text));
handleDataChange();
}
private String validateType(String text) {
String textToSet = text;
String specifiedType = "";
if(text !=null && text.length() > 0 && keyRestrictionRegExp != null){
try{
if(keyRestrictionRegExp.equals(RESTRICTION_REGEXP_TYPE_INTEGER_VALUE)) {
specifiedType = "int";
double doubleValue = Double.parseDouble(text);
textToSet = (int)doubleValue + "";
} else if(keyRestrictionRegExp.equals(RESTRICTION_REGEXP_TYPE_DOUBLE_VALUE)) {
specifiedType = "double";
double doubleValue = Double.parseDouble(text);
textToSet = doubleValue + "";
} else if(keyRestrictionRegExp.equals(RESTRICTION_REGEXP_TYPE_EMAIL_VALUE)) {
specifiedType = "email";
if(text.matches(RESTRICTION_REGEXP_TYPE_EMAIL_VALUE)){
textToSet = text;
} else {
throw new RuntimeException();
}
}
} catch(Exception e){
throw new RuntimeException("Mismatch in datatype. Setting invalid data - \""+ text +"\" to a text field with type = \"" + specifiedType + "\"");
}
}
return textToSet;
}
private void registerKeyEvents() {
HandlesAllKeyEvents keyEvents = new HandlesAllKeyEvents() {
public void onKeyDown(KeyDownEvent event) {
// TODO Auto-generated method stub
}
public void onKeyUp(KeyUpEvent event) {
handleDataChange();
}
public void onKeyPress(KeyPressEvent event) {
handleKeyRestriction(event, event.getCharCode());
}
};
keyEvents.addKeyHandlersTo((com.google.gwt.event.dom.client.HasAllKeyHandlers)this);
}
private boolean isSpecialKeyPressed(KeyPressEvent event) {
if (event.isAnyModifierKeyDown()) {
return true;
}
return (event.getCharCode() < ASCII_SPECIAL_CHARS_THRESHOLD);
}
private void handleKeyRestriction(KeyPressEvent event, char keyPress) {
if (isSpecialKeyPressed(event)) {
return;
}
String newValue = constructNewValue(keyPress);
if ((newValue != null) && (keyRestrictionRegExp != null)) {
if (!isNegativeOnlyValueAllowed(newValue) && newValue.replaceFirst(keyRestrictionRegExp, "").length() > 0) {
event.preventDefault();
}
}
}
private String constructNewValue(char keyPress) {
String previousValue = getText();
String newValue = "";
int cursorPos = getCursorPos();
newValue = previousValue.substring(0, cursorPos) + keyPress + previousValue.substring(cursorPos + getSelectionLength(), previousValue.length());
return newValue;
}
private boolean isNegativeOnlyValueAllowed(String newValue) {
return (("-".equals(newValue)) && (keyRestrictionRegExp.equals(RESTRICTION_REGEXP_TYPE_INTEGER_VALUE) || keyRestrictionRegExp.equals(RESTRICTION_REGEXP_TYPE_DOUBLE_VALUE)));
}
private void handleDataChange() {
if (isDataChanged()) {
doDataChange();
}
}
private boolean isDataChanged() {
String newValue = getText();
return !getRememberedValue().equals(newValue);
}
private void rememberValue() {
oldValue = getText();
}
private String getRememberedValue() {
return oldValue;
}
private void doDataChange() {
fireDataChange(getRememberedValue(), getText());
rememberValue();
}
private void fireDataChange(String oldValue, String newValue) {
for (int i=0; i<dataChangeHandlers.size(); i++) {
DataChangeHandler handler = dataChangeHandlers.get(i);
handler.onDataChange(this, oldValue, newValue);
}
}
public void addDataChangeHandler(DataChangeHandler handler) {
if (handler != null) {
dataChangeHandlers.add(handler);
}
}
public boolean removeDataChangeHandler(DataChangeHandler handler) {
return dataChangeHandlers.remove(handler);
}
public boolean isEditable() {
return !isReadOnly();
}
public void setEditable(boolean editable) {
setReadOnly(!editable);
}
public String getRequiredValidationMessage() {
return requiredValidationMessage;
}
public String getRequiredValidationTitle() {
return requiredValidationTitle;
}
public void setRequiredValidationMessage(String message) {
this.requiredValidationMessage = message;
}
public void setRequiredValidationTitle(String title) {
this.requiredValidationTitle = title;
}
}