ru.codeinside.gses.vaadin.MaskedTextField.java Source code

Java tutorial

Introduction

Here is the source code for ru.codeinside.gses.vaadin.MaskedTextField.java

Source

/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * Copyright (c) 2013, MPL CodeInside http://codeinside.ru
 */

package ru.codeinside.gses.vaadin;

import com.vaadin.data.Property;
import com.vaadin.data.Validator;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.ui.ClientWidget;
import com.vaadin.ui.TextField;
import ru.codeinside.gses.vaadin.client.VMaskedTextField;

/**
 * ? null ,  ? ? ?  "".
 *  ? ? ??,    ?  .
 */
@ClientWidget(VMaskedTextField.class)
public class MaskedTextField extends TextField {
    private static final long serialVersionUID = -5168618178262041249L;
    private String mask;
    private MaskValidator maskValidator;

    private void init() {
        setNullSettingAllowed(true);
        setNullRepresentation("");
    }

    public MaskedTextField() {
        init();
    }

    public MaskedTextField(String caption) {
        setCaption(caption);
        init();
    }

    public MaskedTextField(String caption, String mask) {
        setCaption(caption);
        setMask(mask);
        init();
    }

    public MaskedTextField(Property dataSource) {
        super(dataSource);
        init();
    }

    public MaskedTextField(String caption, Property dataSource) {
        super(caption, dataSource);
        init();
    }

    public String getMask() {
        return mask;
    }

    /**
     * ?? ? ???   .
     */
    @Override
    public void setValue(Object newValue) throws ReadOnlyException, ConversionException {
        //Logger.getAnonymousLogger().info("update: " + (newValue == null ? "NULL" : newValue.toString()));
        String str = newValue == null ? null : newValue.toString();
        if (str != null && str.isEmpty()) {
            str = null;
        }
        super.setValue(str);
    }

    public void setMask(String mask) {
        this.mask = mask;
        if (maskValidator != null) {
            removeValidator(maskValidator);
            maskValidator = null;
        }
        if (mask != null) {
            maskValidator = new MaskValidator(mask);
            addValidator(maskValidator);
            setMaxLength(maskValidator.getLength());
        }
        requestRepaint();
    }

    @Override
    public void paintContent(PaintTarget target) throws PaintException {
        target.addAttribute("mask", mask);
        super.paintContent(target);
    }

    final static class MaskValidator implements Validator {

        final static String CFG = "#UL?A*~H";

        final String maskCfg;
        final String maskSym;

        MaskValidator(final String mask) {
            final StringBuilder cfgBuilder = new StringBuilder();
            final StringBuilder symBuilder = new StringBuilder();
            if (mask != null) {
                final int length = mask.length();
                final int last = length - 1;
                for (int i = 0; i < length; i++) {
                    final char c = mask.charAt(i);
                    if (CFG.indexOf(c) >= 0) {
                        cfgBuilder.append(c);
                        symBuilder.append('_');
                    } else {
                        cfgBuilder.append(' ');
                        if (c != '\'' || i == last) {
                            symBuilder.append(c);
                        } else {
                            i++;
                            symBuilder.append(mask.charAt(i));
                        }
                    }
                }
            }
            this.maskCfg = cfgBuilder.toString();
            this.maskSym = symBuilder.toString();
        }

        public int getLength() {
            return maskCfg.length();
        }

        @Override
        public void validate(Object value) throws InvalidValueException {
            if (!isValid(value)) {
                throw new InvalidValueException("   ?!");
            }
        }

        @Override
        public boolean isValid(final Object value) {
            return value instanceof String && maskIsValid((String) value);
        }

        private boolean maskIsValid(final String value) {
            if (maskCfg.length() != value.length()) {
                return false;
            }

            final int length = value.length();
            for (int i = 0; i < length; i++) {
                final char c = value.charAt(i);
                switch (maskCfg.charAt(i)) {
                case ' ':
                    if (c != maskSym.charAt(i)) {
                        return false;
                    }
                    break;

                case '#':
                    if (!Character.isDigit(c)) {
                        return false;
                    }
                    break;

                case 'U':
                    if (!Character.isUpperCase(c)) {
                        return false;
                    }
                    break;

                case 'L':
                    if (!Character.isLowerCase(c)) {
                        return false;
                    }
                    break;

                case '?':
                    if (!Character.isLetter(c)) {
                        return false;
                    }
                    break;

                case 'A':
                    if (!Character.isLetterOrDigit(c)) {
                        return false;
                    }
                    break;

                case '*':
                    break;

                case '~':
                    if (c != '-' && c != '+') {
                        return false;
                    }
                    break;

                case 'H':
                    if (!Character.isDigit(c) && !('A' <= c && c <= 'F')) {
                        return false;
                    }
                    break;

                default:
                    return false;
                }
            }
            return true;
        }
    }
}