001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 */
019
020package org.apache.isis.core.progmodel.facets.object.mask;
021
022import java.util.ArrayList;
023import java.util.List;
024import java.util.regex.Pattern;
025
026public class MaskEvaluator {
027
028    interface Converter {
029        void convert(String str, StringBuilder buf);
030    }
031
032    static class RegExConverter implements Converter {
033        private final String mask;
034        private final String regex;
035
036        public RegExConverter(final String mask, final String regex) {
037            this.mask = mask;
038            this.regex = regex;
039        }
040
041        public String getMask() {
042            return mask;
043        }
044
045        public String getRegex() {
046            return regex;
047        }
048
049        @Override
050        public void convert(final String str, final StringBuilder buf) {
051            final String convert = str.replace(mask, regex);
052            if (!convert.equals(str)) {
053                buf.append(convert);
054            }
055        }
056    }
057
058    @SuppressWarnings("serial")
059    private static List<Converter> converters = new ArrayList<Converter>() {
060        {
061            add("#", "[0-9]");
062            // add(".", "[\\" +
063            // DecimalFormatSymbols.getInstance().getDecimalSeparator()+"]");
064            // add(",",
065            // "["+DecimalFormatSymbols.getInstance().getGroupingSeparator()+"]");
066            add("&", "[A-Za-z]");
067            add("?", "[A-Za-z]");
068            add("A", "[A-Za-z0-9]");
069            add("a", "[ A-Za-z0-9]");
070            add("9", "[ 0-9]");
071            add("U", "[A-Z]");
072            add("L", "[a-z]");
073
074            add(new Converter() {
075                @Override
076                public void convert(final String str, final StringBuilder buf) {
077                    if (buf.length() == 0) {
078                        buf.append(str);
079                    }
080                }
081            });
082        }
083
084        public void add(final String mask, final String regex) {
085            add(new RegExConverter(mask, regex));
086        }
087    };
088
089    private final Pattern pattern;
090
091    public MaskEvaluator(final String mask) {
092        final StringBuilder buf = new StringBuilder();
093        for (int i = 0; i < mask.length(); i++) {
094            final String charAt = "" + mask.charAt(i);
095            for (final Converter converter : converters) {
096                converter.convert(charAt, buf);
097            }
098        }
099        pattern = Pattern.compile(buf.toString());
100    }
101
102    public boolean evaluate(final String str) {
103        return pattern.matcher(str).matches();
104    }
105
106}