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    
020    package org.apache.isis.core.progmodel.facets.object.mask;
021    
022    import java.util.ArrayList;
023    import java.util.List;
024    import java.util.regex.Pattern;
025    
026    public 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(".", "[\\" + DecimalFormatSymbols.getInstance().getDecimalSeparator()+"]");
063                // add(",", "["+DecimalFormatSymbols.getInstance().getGroupingSeparator()+"]");
064                add("&", "[A-Za-z]");
065                add("?", "[A-Za-z]");
066                add("A", "[A-Za-z0-9]");
067                add("a", "[ A-Za-z0-9]");
068                add("9", "[ 0-9]");
069                add("U", "[A-Z]");
070                add("L", "[a-z]");
071    
072                add(new Converter() {
073                    @Override
074                    public void convert(final String str, final StringBuilder buf) {
075                        if (buf.length() == 0) {
076                            buf.append(str);
077                        }
078                    }
079                });
080            }
081    
082            public void add(final String mask, final String regex) {
083                add(new RegExConverter(mask, regex));
084            }
085        };
086    
087        private final Pattern pattern;
088    
089        public MaskEvaluator(final String mask) {
090            final StringBuilder buf = new StringBuilder();
091            for (int i = 0; i < mask.length(); i++) {
092                final String charAt = "" + mask.charAt(i);
093                for (final Converter converter : converters) {
094                    converter.convert(charAt, buf);
095                }
096            }
097            pattern = Pattern.compile(buf.toString());
098        }
099    
100        public boolean evaluate(final String str) {
101            return pattern.matcher(str).matches();
102        }
103    
104    }