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.getCollectionFactory;
016    
017    import java.util.Locale;
018    import java.util.Map;
019    
020    import net.sf.oval.ConstraintTarget;
021    import net.sf.oval.Validator;
022    import net.sf.oval.configuration.annotation.AbstractAnnotationCheck;
023    import net.sf.oval.context.OValContext;
024    
025    /**
026     * @author Sebastian Thomschke
027     */
028    public class HasSubstringCheck extends AbstractAnnotationCheck<HasSubstring>
029    {
030            private static final long serialVersionUID = 1L;
031    
032            private boolean ignoreCase;
033    
034            private String substring;
035            private transient String substringLowerCase;
036    
037            /**
038             * {@inheritDoc}
039             */
040            @Override
041            public void configure(final HasSubstring constraintAnnotation)
042            {
043                    super.configure(constraintAnnotation);
044                    setIgnoreCase(constraintAnnotation.ignoreCase());
045                    setSubstring(constraintAnnotation.value());
046            }
047    
048            /**
049             * {@inheritDoc}
050             */
051            @Override
052            protected Map<String, String> createMessageVariables()
053            {
054                    final Map<String, String> messageVariables = getCollectionFactory().createMap(2);
055                    messageVariables.put("ignoreCase", Boolean.toString(ignoreCase));
056                    messageVariables.put("substring", substring);
057                    return messageVariables;
058            }
059    
060            /**
061             * {@inheritDoc}
062             */
063            @Override
064            protected ConstraintTarget[] getAppliesToDefault()
065            {
066                    return new ConstraintTarget[]{ConstraintTarget.VALUES};
067            }
068    
069            /**
070             * @return the substring
071             */
072            public String getSubstring()
073            {
074                    return substring;
075            }
076    
077            private String getSubstringLowerCase()
078            {
079                    if (substringLowerCase == null && substring != null)
080                            substringLowerCase = substring.toLowerCase(Locale.getDefault());
081                    return substringLowerCase;
082            }
083    
084            /**
085             * @return the ignoreCase
086             */
087            public boolean isIgnoreCase()
088            {
089                    return ignoreCase;
090            }
091    
092            /**
093             * {@inheritDoc}
094             */
095            public boolean isSatisfied(final Object validatedObject, final Object valueToValidate, final OValContext context,
096                            final Validator validator)
097            {
098                    if (valueToValidate == null) return true;
099    
100                    if (ignoreCase)
101                            return valueToValidate.toString().toLowerCase(Locale.getDefault()).indexOf(getSubstringLowerCase()) > -1;
102    
103                    return valueToValidate.toString().indexOf(substring) > -1;
104            }
105    
106            /**
107             * @param ignoreCase the ignoreCase to set
108             */
109            public void setIgnoreCase(final boolean ignoreCase)
110            {
111                    this.ignoreCase = ignoreCase;
112                    requireMessageVariablesRecreation();
113            }
114    
115            /**
116             * @param substring the substring to set
117             */
118            public void setSubstring(final String substring)
119            {
120                    this.substring = substring;
121                    requireMessageVariablesRecreation();
122            }
123    }