00001 /* 00002 * OpenMobileIS - a free Java(TM) Framework for mobile applications Java(TM) 00003 * Copyright (C) 2004-2005 Philippe Delrieu 00004 * All rights reserved. 00005 * Contact: openmobileis@e-care.fr 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00020 * USA 00021 * 00022 * Author : Philippe Delrieu 00023 * 00024 * Modifications : 00025 * 2004 Creation P.Delrieu 00026 * 2004 Modified by Romain Beaugrand 00027 * 00028 */ 00029 package org.openmobileis.database.fastobjectdb.db.query.soda; 00030 00031 import org.openmobileis.common.util.StringFormater; 00032 import org.openmobileis.common.util.collection.Array; 00033 00040 public final class SodaStringIndexComparator extends SodaIndexComparator { 00041 private Array comparatorList; 00042 private boolean isCaseSensitive = false; 00043 private boolean isDistinct; 00044 00045 class StringOperande { 00046 int comparator; 00047 String operande; 00048 int traversal; 00049 00050 StringOperande() { 00051 } 00052 } 00053 00057 public SodaStringIndexComparator(boolean caseSensitive) { 00058 super(); 00059 this.comparatorList = new Array(); 00060 this.isCaseSensitive = caseSensitive; 00061 } 00062 00063 public boolean setOperand(Object ope) { 00064 if (ope instanceof String) { 00065 StringOperande operand = new StringOperande(); 00066 operand.operande = (String)ope; 00067 if (!this.isCaseSensitive) { 00068 operand.operande = StringFormater.removeAccent(operand.operande).toUpperCase(); 00069 } 00070 comparatorList.add(operand); 00071 return true; 00072 } 00073 return false; 00074 } 00075 00076 public void mergeIndexComporator(SodaIndexComparator index) { 00077 SodaStringIndexComparator newindex = (SodaStringIndexComparator)index; 00078 comparatorList.add(newindex.comparatorList); 00079 } 00080 00081 public boolean addComparator(int comparator) { 00082 if (comparator == BaseConstraint.DISTINCT) { 00083 this.setDistinct(true); 00084 } 00085 StringOperande comp = (StringOperande) comparatorList.getLastAdded(); 00086 if (comp != null) { 00087 if (comp.comparator == BaseConstraint.COMPARATOR_NONE) { 00088 comp.comparator = comparator; 00089 comp.traversal = this.getTraversalWayWithComparator(comp.comparator); 00090 } else { 00091 //manage not or equals. 00092 if (comp.comparator == BaseConstraint.EQUALS) { 00093 if (comparator == BaseConstraint.SMALLER) { 00094 comp.comparator = BaseConstraint.EQUALSMALLER; 00095 } else if (comparator == BaseConstraint.GREATER) { 00096 comp.comparator = BaseConstraint.EQUALGREATER; 00097 } else if (comparator == BaseConstraint.NOT) { 00098 comp.comparator = BaseConstraint.NOT; 00099 } else if (comparator == BaseConstraint.EQUALS) { 00100 comp.comparator = BaseConstraint.EQUALS; 00101 } 00102 } else if (comp.comparator == BaseConstraint.NOT) { 00103 if (comparator == BaseConstraint.SMALLER) { 00104 comp.comparator = BaseConstraint.EQUALGREATER; 00105 } else if (comparator == BaseConstraint.GREATER) { 00106 comp.comparator = BaseConstraint.EQUALSMALLER; 00107 } else if (comparator == BaseConstraint.EQUALS) { 00108 comp.comparator = BaseConstraint.NOT; 00109 } else if (comparator == BaseConstraint.NOT) { 00110 comp.comparator = BaseConstraint.NOT; 00111 } 00112 } else if (comp.comparator == BaseConstraint.SMALLER) { 00113 if (comparator == BaseConstraint.NOT) { 00114 comp.comparator = BaseConstraint.EQUALGREATER; 00115 } else if (comparator == BaseConstraint.EQUALS) { 00116 comp.comparator = BaseConstraint.EQUALSMALLER; 00117 } else if (comparator == BaseConstraint.GREATER) { 00118 comp.comparator = BaseConstraint.EQUALS; 00119 } else if (comparator == BaseConstraint.SMALLER) { 00120 comp.comparator = BaseConstraint.SMALLER; 00121 } 00122 } else if (comp.comparator == BaseConstraint.GREATER) { 00123 if (comparator == BaseConstraint.NOT) { 00124 comp.comparator = BaseConstraint.EQUALSMALLER; 00125 } else if (comparator == BaseConstraint.EQUALS) { 00126 comp.comparator = BaseConstraint.EQUALGREATER; 00127 } else if (comparator == BaseConstraint.SMALLER) { 00128 comp.comparator = BaseConstraint.EQUALS; 00129 } else if (comparator == BaseConstraint.GREATER) { 00130 comp.comparator = BaseConstraint.GREATER; 00131 } 00132 } else { 00133 StringOperande operand = new StringOperande(); 00134 operand.operande = comp.operande; 00135 operand.comparator = comparator; 00136 operand.traversal = this.getTraversalWayWithComparator(operand.comparator); 00137 comparatorList.add(operand); 00138 } 00139 } 00140 return true; 00141 } 00142 //comparator with no operand 00143 return false; 00144 } 00145 00146 public int getSearchAlgo() { 00147 if (comparatorList.size() == 0) { 00148 return SodaIndexComparator.FULL_TRAVERSAL; 00149 } else { 00150 return ((StringOperande) comparatorList.get(0)).traversal; 00151 } 00152 } 00153 00158 public boolean isSelected(String searchString) { 00159 boolean ret = true; 00160 int size = comparatorList.size(); 00161 for (int i = 0; i < size && ret; i++) { 00162 ret = this.selectFisrtOperande((StringOperande) comparatorList.get(i), searchString); 00163 } 00164 return ret; 00165 } 00166 00171 public int compareTo(String searchString) { 00172 if (comparatorList.size() == 0) { 00173 return -1; //force all tree traversal. 00174 } else { 00175 return this.compareFisrtOperande((StringOperande) comparatorList.get(0), searchString); 00176 } 00177 } 00178 00179 private boolean selectFisrtOperande(StringOperande op, String key) { 00180 switch (op.comparator) { 00181 case BaseConstraint.EQUALS : 00182 int test = key.compareTo(op.operande); 00183 return (test==0) ; 00184 case BaseConstraint.NOT : 00185 test = key.compareTo(op.operande); 00186 return (test!=0) ; 00187 case BaseConstraint.SMALLER : 00188 test = key.compareTo(op.operande); 00189 return (test <0) ; 00190 case BaseConstraint.EQUALSMALLER : 00191 test = key.compareTo(op.operande); 00192 return (test <=0) ; 00193 case BaseConstraint.GREATER : 00194 test = key.compareTo(op.operande); 00195 return (test >0) ; 00196 case BaseConstraint.EQUALGREATER : 00197 test = key.compareTo(op.operande); 00198 return (test >=0) ; 00199 case BaseConstraint.LIKE : 00200 return key.startsWith(op.operande) ; 00201 case BaseConstraint.CONTAINS : 00202 return (key.indexOf(op.operande)!=-1) ; 00203 case BaseConstraint.DISTINCT : 00204 return true ; 00205 } 00206 return true; 00207 } 00208 00209 private int compareFisrtOperande(StringOperande op, String key) { 00210 switch (op.comparator) { 00211 case BaseConstraint.EQUALS : 00212 case BaseConstraint.SMALLER : 00213 case BaseConstraint.EQUALSMALLER : 00214 case BaseConstraint.LIKE : 00215 case BaseConstraint.NOT : 00216 return key.compareTo(op.operande) ; 00217 case BaseConstraint.EQUALGREATER : 00218 case BaseConstraint.GREATER : 00219 return -key.compareTo(op.operande) ; 00220 case BaseConstraint.CONTAINS : 00221 case BaseConstraint.DISTINCT : 00222 return -1 ; 00223 } 00224 return -1; 00225 } 00226 00227 public boolean isDistinct() { 00228 return isDistinct; 00229 } 00230 public void setDistinct(boolean isDistinct) { 00231 this.isDistinct = isDistinct; 00232 } 00233 }