001    /*******************************************************************************
002     * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian
003     * Thomschke.
004     * 
005     * All Rights Reserved. This program and the accompanying materials
006     * are made available under the terms of the Eclipse Public License v1.0
007     * which accompanies this distribution, and is available at
008     * http://www.eclipse.org/legal/epl-v10.html
009     * 
010     * Contributors:
011     *     Sebastian Thomschke - initial implementation.
012     *******************************************************************************/
013    package net.sf.oval.constraint;
014    
015    import static net.sf.oval.Validator.*;
016    
017    import java.util.Collection;
018    import java.util.List;
019    import java.util.Map;
020    import java.util.regex.Pattern;
021    
022    import net.sf.oval.ConstraintTarget;
023    import net.sf.oval.Validator;
024    import net.sf.oval.configuration.annotation.AbstractAnnotationCheck;
025    import net.sf.oval.context.OValContext;
026    import net.sf.oval.internal.util.ArrayUtils;
027    
028    /**
029     * @author Sebastian Thomschke
030     */
031    public class MatchPatternCheck extends AbstractAnnotationCheck<MatchPattern>
032    {
033            private static final long serialVersionUID = 1L;
034    
035            private final List<Pattern> patterns = getCollectionFactory().createList(2);
036            private boolean matchAll = true;
037    
038            /**
039             * {@inheritDoc}
040             */
041            @Override
042            public void configure(final MatchPattern constraintAnnotation)
043            {
044                    super.configure(constraintAnnotation);
045    
046                    setMatchAll(constraintAnnotation.matchAll());
047    
048                    synchronized (patterns)
049                    {
050                            patterns.clear();
051                            final String[] stringPatterns = constraintAnnotation.pattern();
052                            final int[] f = constraintAnnotation.flags();
053                            for (int i = 0, l = stringPatterns.length; i < l; i++)
054                            {
055                                    final int flag = f.length > i ? f[i] : 0;
056                                    final Pattern p = Pattern.compile(stringPatterns[i], flag);
057                                    patterns.add(p);
058                            }
059                            requireMessageVariablesRecreation();
060                    }
061            }
062    
063            /**
064             * {@inheritDoc}
065             */
066            @Override
067            protected Map<String, String> createMessageVariables()
068            {
069                    final Map<String, String> messageVariables = getCollectionFactory().createMap(2);
070                    messageVariables.put("pattern", patterns.size() == 1 ? patterns.get(0).toString() : patterns.toString());
071                    return messageVariables;
072            }
073    
074            /**
075             * {@inheritDoc}
076             */
077            @Override
078            protected ConstraintTarget[] getAppliesToDefault()
079            {
080                    return new ConstraintTarget[]{ConstraintTarget.VALUES};
081            }
082    
083            /**
084             * @return the pattern
085             */
086            public Pattern[] getPatterns()
087            {
088                    synchronized (patterns)
089                    {
090                            return patterns.toArray(new Pattern[patterns.size()]);
091                    }
092            }
093    
094            /**
095             * @return the matchAll
096             */
097            public boolean isMatchAll()
098            {
099                    return matchAll;
100            }
101    
102            /**
103             * {@inheritDoc}
104             */
105            public boolean isSatisfied(final Object validatedObject, final Object valueToValidate, final OValContext context,
106                            final Validator validator)
107            {
108                    if (valueToValidate == null) return true;
109    
110                    for (final Pattern p : patterns)
111                    {
112                            final boolean matches = p.matcher(valueToValidate.toString()).matches();
113    
114                            if (matches)
115                            {
116                                    if (!matchAll) return true;
117                            }
118                            else if (matchAll) return false;
119                    }
120                    return matchAll ? true : false;
121            }
122    
123            /**
124             * @param matchAll the matchAll to set
125             */
126            public void setMatchAll(final boolean matchAll)
127            {
128                    this.matchAll = matchAll;
129                    requireMessageVariablesRecreation();
130            }
131    
132            /**
133             * @param pattern the pattern to set
134             */
135            public void setPattern(final Pattern pattern)
136            {
137                    synchronized (patterns)
138                    {
139                            patterns.clear();
140                            patterns.add(pattern);
141                    }
142                    requireMessageVariablesRecreation();
143            }
144    
145            /**
146             * @param pattern the pattern to set
147             */
148            public void setPattern(final String pattern, final int flags)
149            {
150                    synchronized (patterns)
151                    {
152                            patterns.clear();
153                            patterns.add(Pattern.compile(pattern, flags));
154                    }
155                    requireMessageVariablesRecreation();
156            }
157    
158            /**
159             * @param patterns the patterns to set
160             */
161            public void setPatterns(final Collection<Pattern> patterns)
162            {
163                    synchronized (this.patterns)
164                    {
165                            this.patterns.clear();
166                            this.patterns.addAll(patterns);
167                    }
168                    requireMessageVariablesRecreation();
169            }
170    
171            /**
172             * @param patterns the patterns to set
173             */
174            public void setPatterns(final Pattern... patterns)
175            {
176                    synchronized (this.patterns)
177                    {
178                            this.patterns.clear();
179                            ArrayUtils.addAll(this.patterns, patterns);
180                    }
181                    requireMessageVariablesRecreation();
182            }
183    }