Coverage Report - org.apache.ojb.broker.query.LikeCriteria
 
Classes in this File Line Coverage Branch Coverage Complexity
LikeCriteria
N/A
N/A
3.833
 
 1  
 package org.apache.ojb.broker.query;
 2  
 
 3  
 /* Copyright 2002-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 /**
 19  
  * Model a Like Criteria</br> 
 20  
  * Escape Processing by Paul R. Nase 
 21  
  * <p>
 22  
  * The pattern string is a simple pattern string using % or * as a wildcard.
 23  
  * So Ander* would match Anderson and Anderton. The _ or ? character is used to match a single occurence
 24  
  * of a character. The '\' is used to escape the wildcard characters so that we can search for
 25  
  * strings containing * and ?. 
 26  
  * <p>
 27  
  * To change the escape character use setEscapeCharacter. 
 28  
  * @see LikeCriteria#setEscapeCharacter(char)
 29  
  * 
 30  
  * @author <a href="mailto:jbraeuchi@gmx.ch">Jakob Braeuchi </a>
 31  
  * @author <a href="mailto:Nase.Paul@mayo.edu">Paul Nase </a>
 32  
  * @version $Id: LikeCriteria.java,v 1.1 2007-08-24 22:17:36 ewestfal Exp $
 33  
  */
 34  
 public class LikeCriteria extends ValueCriteria
 35  
 {
 36  
     /**
 37  
      * The Dfault-Character used for Escaping Wildcards
 38  
      */
 39  
     public static final char DEFAULT_ESCPAPE_CHARACTER = '\\';
 40  
 
 41  
     /**
 42  
      * The Character used for Escaping Wildcards
 43  
      */
 44  
     private static char escapeCharacter = DEFAULT_ESCPAPE_CHARACTER;
 45  
 
 46  
         /**
 47  
          * @param anAttribute
 48  
          * @param aValue
 49  
          * @param aClause
 50  
          * @param anAlias
 51  
          */
 52  
         public LikeCriteria(Object anAttribute, Object aValue, String aClause, String anAlias)
 53  
         {
 54  
                 super(anAttribute, generateSQLSearchPattern(aValue), aClause, anAlias);
 55  
         }
 56  
 
 57  
         /**
 58  
          * @param anAttribute
 59  
          * @param aValue
 60  
          * @param aClause
 61  
          * @param anAlias
 62  
          */
 63  
         public LikeCriteria(Object anAttribute, Object aValue, String aClause, UserAlias anAlias)
 64  
         {
 65  
                 super(anAttribute, generateSQLSearchPattern(aValue), aClause, anAlias);
 66  
         }
 67  
 
 68  
     /**
 69  
      * @see org.apache.ojb.broker.query.SelectionCriteria#bind(java.lang.Object)
 70  
      */
 71  
     public void bind(Object newValue)
 72  
     {
 73  
         super.bind(generateSQLSearchPattern(newValue));
 74  
     }
 75  
 
 76  
     /**
 77  
      * Generate a SQL search string from the pattern string passed. 
 78  
      * The pattern string is a simple pattern string using % or * as a wildcard. 
 79  
      * So Ander* would match Anderson and Anderton. The _ or ? character is used to match a single occurence
 80  
      * of a character. The escapeCharacter is used to escape the wildcard characters so that we can search for
 81  
      * strings containing * and ?. This method converts the criteria wildcard strings to SQL wildcards.
 82  
      * 
 83  
      * @param pattern a criteria search pattern containing optional wildcards
 84  
      * @return a SQL search pattern string with all escape codes processed.
 85  
      */
 86  
         private static String generateSQLSearchPattern(Object pattern)
 87  
         {
 88  
                 if (pattern == null)
 89  
                 {
 90  
                         return null;
 91  
                 }
 92  
                 else
 93  
                 {
 94  
                         StringBuffer sqlpattern = new StringBuffer();
 95  
                         char[] chars = pattern.toString().toCharArray();
 96  
 
 97  
                         for (int i = 0; i < chars.length; i++)
 98  
                         {
 99  
                                 if (chars[i] == escapeCharacter)
 100  
                                 {
 101  
                                         // for the escape character add the next char as is.
 102  
                                         // find the next non-escape character.
 103  
                                         int x = i + 1;
 104  
                                         for (;(x < chars.length); x++)
 105  
                                         {
 106  
                                                 if (chars[x] != escapeCharacter)
 107  
                                                 {
 108  
                                                         break;
 109  
                                                 }
 110  
                                         }
 111  
                                         boolean oddEscapes = (((x - i) % 2) > 0) ? true : false;
 112  
                                         if (oddEscapes)
 113  
                                         {
 114  
                                                 // only escape characters allowed are '%', '_', and '\'
 115  
                                                 // if the escaped character is a '\', then oddEscapes
 116  
                                                 // will be false.
 117  
                                                 // if the character following this last escape is not a
 118  
                                                 // '%' or an '_', eat this escape character.
 119  
                                                 if ((x < chars.length)
 120  
                                                         && ((chars[x] == '%') || (chars[x] == '_')))
 121  
                                                 {
 122  
                                                         // leave the escape character in, along with the following char
 123  
                                                         x++;
 124  
                                                 }
 125  
                                                 else
 126  
                                                 {
 127  
                                                         // remove the escape character, will cause problems in sql statement.
 128  
                                                         i++; // removing the first escape character.
 129  
                                                         if ((x < chars.length)
 130  
                                                                 && ((chars[x] == '*') || (chars[x] == '?')))
 131  
                                                         {
 132  
                                                                 // but if it is a '*' or a '?', we want to keep these
 133  
                                                                 // characters as is, they were 'escaped' out.
 134  
                                                                 x++; // include the first non-escape character.
 135  
                                                         }
 136  
                                                 }
 137  
                                         }
 138  
                                         if (i < chars.length)
 139  
                                         {
 140  
                                                 sqlpattern.append(chars, i, x - i);
 141  
                                         }
 142  
                                         i = x - 1; // set index to last character copied.
 143  
                                 }
 144  
                                 else if (chars[i] == '*')
 145  
                                 {
 146  
                                         sqlpattern.append("%");
 147  
                                 }
 148  
                                 else if (chars[i] == '?')
 149  
                                 {
 150  
                                         sqlpattern.append("_");
 151  
                                 }
 152  
                                 else
 153  
                                 {
 154  
                                         sqlpattern.append(chars[i]);
 155  
                                 }
 156  
                         }
 157  
                         return sqlpattern.toString();
 158  
                 }
 159  
         }
 160  
 
 161  
     /**
 162  
      * @return Returns the escapeCharacter.
 163  
      */
 164  
     public static char getEscapeCharacter()
 165  
     {
 166  
         return escapeCharacter;
 167  
     }
 168  
     
 169  
     /**
 170  
      * Global change of the escapeCharacter
 171  
      * @param escChar The escapeCharacter to set.
 172  
      */
 173  
     public static void setEscapeCharacter(char escChar)
 174  
     {
 175  
         escapeCharacter = escChar;
 176  
     }
 177  
     
 178  
 }