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 //