00001 /* 00002 * LikeFilter.hpp 00003 * 00004 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 00005 * 00006 * Oracle is a registered trademarks of Oracle Corporation and/or its 00007 * affiliates. 00008 * 00009 * This software is the confidential and proprietary information of Oracle 00010 * Corporation. You shall not disclose such confidential and proprietary 00011 * information and shall use it only in accordance with the terms of the 00012 * license agreement you entered into with Oracle. 00013 * 00014 * This notice may not be removed or altered. 00015 */ 00016 #ifndef COH_LIKE_FILTER_HPP 00017 #define COH_LIKE_FILTER_HPP 00018 00019 #include "coherence/lang.ns" 00020 00021 #include "coherence/io/pof/PofReader.hpp" 00022 #include "coherence/io/pof/PofWriter.hpp" 00023 #include "coherence/util/HashSet.hpp" 00024 #include "coherence/util/ValueExtractor.hpp" 00025 #include "coherence/util/filter/ComparisonFilter.hpp" 00026 #include "coherence/util/filter/IndexAwareFilter.hpp" 00027 00028 COH_OPEN_NAMESPACE3(coherence,util,filter) 00029 00030 using coherence::io::pof::PofReader; 00031 using coherence::io::pof::PofWriter; 00032 00033 00034 /** 00035 * Filter which compares the result of a method invocation with a value for 00036 * pattern match. A pattern can include regular characters and wildcard 00037 * characters '_' and '%'. 00038 * 00039 * During pattern matching, regular characters must exactly match the 00040 * characters in an evaluated string. Wildcard character '_' (underscore) can 00041 * be matched with any single character, and wildcard character '%' can be 00042 * matched with any string fragment of zero or more characters. 00043 * 00044 * @author djl 2008.07.24 00045 */ 00046 class COH_EXPORT LikeFilter 00047 : public class_spec<LikeFilter, 00048 extends<ComparisonFilter>, 00049 implements<IndexAwareFilter> > 00050 { 00051 friend class factory<LikeFilter>; 00052 00053 // ----- constructors --------------------------------------------------- 00054 00055 protected: 00056 /** 00057 * Default constructor (necessary for the PortableObject interface). 00058 */ 00059 LikeFilter(); 00060 00061 /** 00062 * Construct a LikeFilter for pattern match. 00063 * 00064 * @param vExtractor the ValueExtractor to use by this filter 00065 * @param vsPattern the string pattern to compare the result with 00066 * @param chEscape the escape character for escaping '%' and '_' 00067 * @param fIgnoreCase true to be case-insensitive 00068 */ 00069 LikeFilter(ValueExtractor::View vExtractor, String::View vsPattern, 00070 char16_t chEscape = (char16_t) 0, bool fIgnoreCase = false); 00071 00072 private: 00073 /** 00074 * Initialize this filter. 00075 * 00076 * @param chEscape the escape character for escaping '%' and '_' 00077 * @param fIgnoreCase true to be case-insensitive 00078 */ 00079 void init(char16_t chEscape, bool fIgnoreCase); 00080 00081 00082 // ----- ExtractorFilter interface -------------------------------------- 00083 00084 protected: 00085 /** 00086 * {@inheritDoc} 00087 */ 00088 virtual bool evaluateExtracted(Object::View vExtracted) const; 00089 00090 00091 // ----- IndexAwareFilter interface ------------------------------------- 00092 00093 public: 00094 /** 00095 * {@inheritDoc} 00096 */ 00097 virtual size32_t calculateEffectiveness(Map::View vMapIndexes, 00098 Set::View vSetKeys) const; 00099 00100 /** 00101 * {@inheritDoc} 00102 */ 00103 virtual Filter::View applyIndex(Map::View vMapIndexes, 00104 Set::Handle hSetKeys) const; 00105 00106 00107 // ----- PortableObject interface --------------------------------------- 00108 00109 public: 00110 /** 00111 * {@inheritDoc} 00112 */ 00113 virtual void readExternal(PofReader::Handle hIn); 00114 00115 /** 00116 * {@inheritDoc} 00117 */ 00118 virtual void writeExternal(PofWriter::Handle hOut) const; 00119 00120 00121 // ----- accessors ------------------------------------------------------ 00122 00123 public: 00124 /** 00125 * Obtain the filter's pattern string. 00126 * 00127 * @return the pattern string 00128 */ 00129 virtual String::View getPattern() const; 00130 00131 /** 00132 * Check whether or not the filter is case incensitive. 00133 * 00134 * @return true iff case insensitivity is specifically enabled 00135 */ 00136 virtual bool isIgnoreCase() const; 00137 00138 /** 00139 * Obtain the escape character that is used for escaping '%' and '_' 00140 * in the pattern or zero if there is no escape. 00141 * 00142 * @return the escape character 00143 */ 00144 virtual char16_t getEscapeChar() const; 00145 00146 /** 00147 * Display the execution plan that the LikeFilter has selected. 00148 * 00149 * @param out the ostream to display the plan on 00150 * 00151 */ 00152 virtual void showPlan(std::ostream &out) const; 00153 00154 00155 // ----- internal methods ----------------------------------------------- 00156 00157 protected: 00158 /** 00159 * Build a plan for processing the LIKE functionality. 00160 */ 00161 virtual void buildPlan(); 00162 00163 /** 00164 * Check the passed String value to see if it matches the pattern that 00165 * this filter was constructed with. 00166 * 00167 * @param vsValue the String value to match against this filter's 00168 * pattern 00169 * 00170 * @return true iff the passed String value is LIKE this filter's 00171 * pattern 00172 */ 00173 virtual bool isMatch(String::View vsValue) const; 00174 00175 00176 // ----- nested class: MatchStep ---------------------------------------- 00177 00178 private: 00179 /** 00180 * Handles one matching step for a literal or a 00181 * character-by-character (literal and/or '_' matching). 00182 */ 00183 class MatchStep 00184 : public class_spec<MatchStep> 00185 { 00186 friend class factory<MatchStep>; 00187 00188 // ----- constructor ---------------------------------------- 00189 00190 protected: 00191 /** 00192 * Construct a MatchStep object. 00193 * 00194 * @param vsMatch the string of characters to match 00195 * in this step 00196 * @param vBitset corresponding to each character, true 00197 * if any character is allowed ('_') 00198 * @param fIsIgnoreCase true if ignoring case 00199 */ 00200 MatchStep(String::View vsMatch, HashSet::View vBitset, 00201 bool fIsIgnoreCase); 00202 00203 // ----- matching methods ----------------------------------- 00204 00205 public: 00206 /** 00207 * Find the first index of this match step in the passed 00208 * character array starting at the passed offset and 00209 * within the specified number of characters. 00210 * 00211 * @param vach the array of characters within which 00212 * to find a match 00213 * @param ofBegin the starting offset in character 00214 * array<tt>ach</tt> to start looking 00215 * for a match 00216 * @param ofEnd the first offset in the character 00217 * array <tt>ach</tt> which is beyond 00218 * the region that this operation is 00219 * allowed to search through to find a 00220 * match 00221 * 00222 * @return the first index at which the match is made, 00223 * or Array<char>::npos if the match cannot be made in the 00224 * designated range of offsets 00225 */ 00226 virtual size32_t indexOf(Array<char>::View vach, 00227 size32_t ofBegin, size32_t ofEnd) const; 00228 00229 // ----- accessors ------------------------------------------ 00230 00231 public: 00232 /** 00233 * @return the match pattern as a String 00234 */ 00235 virtual String::View getString() const; 00236 00237 /** 00238 * @return the length of the match pattern 00239 */ 00240 virtual size32_t getLength() const; 00241 00242 /** 00243 * @return true if there are no wildcards ('_') in the match 00244 * pattern 00245 */ 00246 virtual bool isLiteral() const; 00247 00248 // ----- Object methods ------------------------------------- 00249 00250 public: 00251 void toStream(std::ostream &out) const; 00252 00253 // ----- data members --------------------------------------- 00254 00255 private: 00256 /** 00257 * The match pattern, as a String. 00258 */ 00259 FinalView<String> f_vsMatch; 00260 00261 /** 00262 * The match pattern, as an array of char values. If the 00263 * filter is case insensitive, then this is the uppercase form 00264 * of the char values. 00265 */ 00266 MemberView<Array<char> > m_vachMatch; 00267 /** 00268 * The match pattern for a case insensitive like filter, as an 00269 * array of lowercase char values. For case sensitive filters, 00270 * this is null. 00271 */ 00272 MemberView<Array<char> > m_vachLower; 00273 00274 /** 00275 * For each character, true if the character is a wildcard 00276 * ('_'), or null if there are no wildcards. 00277 */ 00278 MemberView<Array<bool> > m_vafAny; 00279 00280 /** 00281 * Number of leading wildcards. 00282 */ 00283 size32_t m_cchSkipFront; 00284 00285 /** 00286 * Number of trailing wildcards. 00287 */ 00288 size32_t m_cchSkipBack; 00289 00290 /** 00291 * True if there are any wildcards in the middle. 00292 */ 00293 bool m_fMiddleWilds; 00294 00295 /** 00296 * True if there we are ignoring case. 00297 */ 00298 bool m_fIsIgnoreCase; 00299 00300 // ----- friends ---------------------------------------- 00301 00302 friend class LikeFilter; 00303 }; 00304 00305 00306 // ----- data members --------------------------------------------------- 00307 00308 private: 00309 /** 00310 * The escape character for escaping '_' and '%' in the pattern. 00311 * The valu zero is reserved to mean "no escape". 00312 */ 00313 char16_t m_chEscape; 00314 00315 /** 00316 * The option to ignore case sensitivity. True means that the filter 00317 * will match ignoring case. 00318 */ 00319 bool m_fIgnoreCase; 00320 00321 /** 00322 * Optimization plan number. Zero means default iterative evalution is 00323 * necessary. 00324 */ 00325 int32_t m_nPlan; 00326 00327 /** 00328 * Used by single-character matching optimization plans. 00329 */ 00330 char m_chPart; 00331 00332 /** 00333 * Used by string-character matching optimization plans. 00334 */ 00335 MemberView<String> m_vsPart; 00336 00337 /** 00338 * The "front" matching step used by the iterative processing; null if 00339 * the pattern starts with '%'. 00340 */ 00341 MemberView<MatchStep> m_vStepFront; 00342 00343 /** 00344 * The "back" matching step used by the iterative processing; null if 00345 * the pattern ends with '%'. 00346 */ 00347 MemberView<MatchStep> m_vStepBack; 00348 00349 /** 00350 * For iterative plans with a NULL "back" matching step, is trailing 00351 * data permitted. 00352 */ 00353 bool m_fTrailingTextAllowed; 00354 00355 /** 00356 * The array of "middle" matching steps used by the iterative 00357 * processing; may be NULL if none. 00358 */ 00359 MemberView<ObjectArray> m_vaStepMiddle; 00360 00361 /** 00362 * The flag that indicates whether the pattern is ascii. This allows 00363 * the match to execute locally. 00364 */ 00365 bool m_fPatternIsASCII; 00366 }; 00367 00368 COH_CLOSE_NAMESPACE3 00369 00370 #endif // COH_LIKE_FILTER_HPP