1 // 2 // SearchParser.java 3 // CocoDonkey 4 // $Id: SearchParser.java,v 1.2 2002/08/21 21:48:44 fortun Exp $ 5 // 6 // Created by Fred Bonzoun on Sun Jul 21 2002. 7 // Copyright (c) 2002 Bonzoun. All rights reserved. 8 // 9 // This library is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU Lesser General Public License as published 11 // by the Free Software Foundation; either version 2.1 of the License, or 12 // (at your option) any later version. 13 // 14 // This library is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU Lesser General Public License for more details. 18 // 19 // You should have received a copy of the GNU Lesser General Public License 20 // along with this program; if not, write to the Free Software 21 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 // 23 24 package net.bonzoun.cocodonkey; 25 26 import java.util; 27 28 public class SearchParser extends StringParser { 29 30 private HashMap leftHandSides = new HashMap(); 31 private int leftToBeDone; 32 private int searchNumber; 33 34 public SearchParser(String s) { 35 super(s); 36 leftToBeDone = getLastInt(0); 37 getNextChar(); 38 searchNumber = getNextIntUntil("]", -1); 39 getNextChar(); 40 parse(); 41 //System.out.println("##" + s + "##"); 42 //System.out.println("## [" + searchNumber + "] " + toStringExtended() + " {" + leftToBeDone + "} ##"); 43 } 44 45 public int searchNumber() { 46 return searchNumber; 47 } 48 49 public int leftToBeDone() { 50 return leftToBeDone; 51 } 52 53 public boolean isExtended() { 54 if (leftHandSides.size()==0) 55 return false; 56 return leftHandSides.size()>1 || !leftHandSides.containsKey(""); 57 } 58 59 /** Returns the value for the given option, "" if the option is not set **/ 60 public String stringFor(String key) { 61 List l = (List)leftHandSides.get(key.toLowerCase()); 62 if (l!=null) { 63 StringBuffer out = new StringBuffer(); 64 Iterator datas = l.iterator(); 65 boolean isFirst = true; 66 while(datas.hasNext()) { 67 BinOperator op = (BinOperator)datas.next(); 68 if (isFirst) 69 isFirst = false; 70 else 71 out.insert(0, ' '); 72 out.insert(0, op.rightHandSide); 73 } 74 return out.toString(); 75 } else { 76 return ""; 77 } 78 } 79 80 public String stringFor(String key, String sop) { 81 List l = (List)leftHandSides.get(key.toLowerCase()); 82 if (l!=null) { 83 Iterator datas = l.iterator(); 84 while(datas.hasNext()) { 85 BinOperator op = (BinOperator)datas.next(); 86 if (op.op.equals(sop)) 87 return op.rightHandSide; 88 } 89 } 90 return ""; 91 } 92 93 public String toString() { 94 return stringFor(""); 95 } 96 97 public String toStringExtended() { 98 StringBuffer out = new StringBuffer(); 99 out.append(stringFor("")); 100 // We parse all the keys 101 boolean isFirst = true; 102 Iterator keys = leftHandSides.keySet().iterator(); 103 while(keys.hasNext()) { 104 String lhs = (String)keys.next(); 105 String rhs = stringFor(lhs); 106 if (lhs.length()>0 && rhs!=null && rhs.length()>0) { 107 if (isFirst) { 108 isFirst = false; 109 out.append(" ("); 110 } else { 111 out.append(", "); 112 } 113 out.append(lhs); 114 out.append(" =\""); 115 out.append(rhs); 116 out.append('\"'); 117 } 118 } 119 if (!isFirst) 120 out.append(")"); 121 return out.toString(); 122 } 123 124 /** Parses a search definition step, ie xxx AND xxx **/ 125 protected void parse() { 126 // We get one data 127 parseNextData(); 128 // We test for the end of the stream 129 if (testNextChar()==')') { 130 // One level less of parentheses. We must return 131 getNextChar(); 132 return; 133 } 134 // We test for the operator 135 String s = getNextString(); 136 if (s.equals("AND")) { 137 // More data to get 138 parse(); 139 } else { 140 // No more data, or unknown form of data 141 } 142 } 143 144 /** Parses a search data step, ie CONTAINS[xxx] or [xxx]CONTAINS[xxx] or [xxx]xx999 **/ 145 protected void parseNextData() { 146 char c = testNextChar(); 147 if (c=='(') { 148 // One more level of parentheses. Will return at the corresponding closing parentheses 149 getNextChar(); 150 parse(); 151 return; 152 } 153 // We get the Left hand side 154 String lhs; 155 if (c=='[') { 156 // We have to parse a String data 157 getNextChar(); 158 lhs = getNextStringUntil("]"); 159 getNextChar(); 160 } else { 161 // We have no lhs 162 lhs = ""; 163 } 164 // We get the operator and the Right Hand Side 165 String op, rhs = null; 166 if ("<>!=".indexOf(testNextChar())>=0) { 167 // Compare with a number 168 op = getNextStringUntil(INTEGER); 169 if (testNextChar()!=0) 170 rhs = getNextStringUntil(")" + WHITESPACE); 171 } else { 172 // CONTAINS a String 173 op = getNextStringUntil("["); 174 if (getNextChar()=='[') { 175 rhs = getNextStringUntil("]"); 176 getNextChar(); 177 } 178 } 179 if (rhs!=null) 180 addOperator(new BinOperator(lhs, op, rhs)); 181 } 182 183 protected void addOperator(BinOperator binOp) { 184 String key = binOp.leftHandSide.toLowerCase(); 185 List l = (List)leftHandSides.get(key); 186 if (l==null) { 187 // We must create a new Vector 188 l = new ArrayList(); 189 leftHandSides.put(key, l); 190 } 191 l.add(binOp); 192 } 193 194 public class BinOperator { 195 protected String op; 196 protected String rightHandSide; 197 protected String leftHandSide; 198 199 protected BinOperator(String lhs, String op, String rhs) { 200 this.op = op; 201 this.rightHandSide = rhs; 202 this.leftHandSide = lhs; 203 } 204 } 205 } 206 207 // $Log: SearchParser.java,v $ 208 // Revision 1.2 2002/08/21 21:48:44 fortun 209 // NUMBER becomes INTEGER 210 // 211 // Revision 1.1 2002/07/21 18:40:00 fortun 212 // *** empty log message *** 213 //