001/**
002The contents of this file are subject to the Mozilla Public License Version 1.1 
003(the "License"); you may not use this file except in compliance with the License. 
004You may obtain a copy of the License at http://www.mozilla.org/MPL/ 
005Software distributed under the License is distributed on an "AS IS" basis, 
006WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 
007specific language governing rights and limitations under the License. 
008
009The Original Code is "PredicatePrimitiveTypeRule.java".  Description: 
010"PrimitiveTypeRule that validates using predicates" 
011
012The Initial Developer of the Original Code is University Health Network. Copyright (C) 
0132012.  All Rights Reserved. 
014
015Contributor(s): ______________________________________. 
016
017Alternatively, the contents of this file may be used under the terms of the 
018GNU General Public License (the "GPL"), in which case the provisions of the GPL are 
019applicable instead of those above.  If you wish to allow use of your version of this 
020file only under the terms of the GPL and not to allow others to use your version 
021of this file under the MPL, indicate your decision by deleting  the provisions above 
022and replace  them with the notice and other provisions required by the GPL License.  
023If you do not delete the provisions above, a recipient may use your version of 
024this file under either the MPL or the GPL. 
025 */
026package ca.uhn.hl7v2.validation.builder;
027
028import java.util.regex.Pattern;
029
030import ca.uhn.hl7v2.validation.ValidationException;
031import ca.uhn.hl7v2.validation.impl.AbstractPrimitiveTypeRule;
032
033/**
034 * Abstract base class for PrimitiveTypeRules that validate using predicates
035 * 
036 * @author Christian Ohr
037 */
038@SuppressWarnings("serial")
039public class PredicatePrimitiveTypeRule extends AbstractPrimitiveTypeRule implements
040                PredicateRuleSupport<String> {
041 
042    private static final Pattern LEADING_WHITESPACE = Pattern.compile("^\\s+");
043    private static final Pattern TRAILING_WHITESPACE = Pattern.compile("\\s+$");
044
045    
046    public enum Trimmer {
047
048        LEFT {
049            @Override public String trim(String source) { return trimPattern(LEADING_WHITESPACE, source); }            
050        },
051        RIGHT {
052            @Override public String trim(String source) { return trimPattern(TRAILING_WHITESPACE, source); }            
053        },                
054        NONE {
055            @Override public String trim(String source) { return source; }            
056        },
057        ALL {
058            @Override public String trim(String source) { return source == null ? null : source.trim(); }                        
059        };
060
061        /**
062         * Trims a string
063         * @param source the string to be trimmed
064         * @return the trimmed string
065         */
066        public abstract String trim(String source);
067        
068        protected String trimPattern(Pattern pattern, String source) {
069            if (source == null || pattern == null) 
070                return source;
071            return pattern.matcher(source).replaceAll("");
072        }
073    }
074
075        private Predicate predicate;
076        private Trimmer trimmer;
077
078    /**
079     * Creates a new primitive rule without trimming
080     * @param predicate predicate to be used
081     */
082        public PredicatePrimitiveTypeRule(Predicate predicate) {
083                this(predicate, Trimmer.NONE);
084        }
085
086    /**
087     * Creates a new primitive rule
088     * @param predicate predicate to be used
089     * @param trimmer trimming behavior
090     */
091        public PredicatePrimitiveTypeRule(Predicate predicate, Trimmer trimmer) {
092                this.predicate = predicate;
093                this.trimmer = trimmer;
094        setDescription("Primitive value '%s' requires to be " + predicate.getDescription());
095        }
096
097        public Predicate getPredicate() {
098                return predicate;
099        }
100
101        public String correct(String value) {
102            return trimmer.trim(value);
103        }
104
105        public boolean test(String value) {
106                try {
107                        return getPredicate().evaluate(value);
108                } catch (ValidationException e) {
109                        return false;
110                }
111        }
112
113        public ValidationException[] apply(String value) {
114                try {
115                        return result(getPredicate().evaluate(correct(value)), value);
116                } catch (ValidationException e) {
117                        return failed(e);
118                }
119        }
120
121        @Override
122        public String toString() {
123                return getDescription();
124        }
125
126}