001    /**
002     *
003     * Copyright 2003-2006 The Apache Software Foundation
004     *
005     *  Licensed under the Apache License, Version 2.0 (the "License");
006     *  you may not use this file except in compliance with the License.
007     *  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package javax.mail.search;
019    
020    /**
021     * A Term that provides matching criteria for Strings.
022     *
023     * @version $Rev: 421852 $ $Date: 2006-07-14 03:02:19 -0700 (Fri, 14 Jul 2006) $
024     */
025    public abstract class StringTerm extends SearchTerm {
026        /**
027         * If true, case should be ignored during matching.
028         */
029        protected boolean ignoreCase;
030    
031        /**
032         * The pattern associated with this term.
033         */
034        protected String pattern;
035    
036        /**
037         * Constructor specifying a pattern.
038         * Defaults to case insensitive matching.
039         * @param pattern the pattern for this term
040         */
041        protected StringTerm(String pattern) {
042            this(pattern, true);
043        }
044    
045        /**
046         * Constructor specifying pattern and case sensitivity.
047         * @param pattern the pattern for this term
048         * @param ignoreCase if true, case should be ignored during matching
049         */
050        protected StringTerm(String pattern, boolean ignoreCase) {
051            this.pattern = pattern;
052            this.ignoreCase = ignoreCase;
053        }
054    
055        /**
056         * Return the pattern associated with this term.
057         * @return the pattern associated with this term
058         */
059        public String getPattern() {
060            return pattern;
061        }
062    
063        /**
064         * Indicate if case should be ignored when matching.
065         * @return if true, case should be ignored during matching
066         */
067        public boolean getIgnoreCase() {
068            return ignoreCase;
069        }
070    
071        /**
072         * Determine if the pattern associated with this term is a substring of the
073         * supplied String. If ignoreCase is true then case will be ignored.
074         *
075         * @param match the String to compare to
076         * @return true if this patter is a substring of the supplied String
077         */
078        protected boolean match(String match) {
079            match: for (int length = match.length() - pattern.length(); length > 0; length--) {
080                for (int i = 0; i < pattern.length(); i++) {
081                    char c1 = match.charAt(length + i);
082                    char c2 = match.charAt(i);
083                    if (c1 == c2) {
084                        continue;
085                    }
086                    if (ignoreCase) {
087                        if (Character.toLowerCase(c1) == Character.toLowerCase(c2)) {
088                            continue;
089                        }
090                        if (Character.toUpperCase(c1) == Character.toUpperCase(c2)) {
091                            continue;
092                        }
093                    }
094                    continue match;
095                }
096                return true;
097            }
098            return false;
099        }
100    
101        public boolean equals(Object other) {
102            return super.equals(other)
103                    && ((StringTerm) other).pattern.equals(pattern)
104                    && ((StringTerm) other).ignoreCase == ignoreCase;
105        }
106    
107        public int hashCode() {
108            return super.hashCode() + pattern.hashCode() + (ignoreCase ? 32 : 79);
109        }
110    }