001: package bdd.search.query;
002:
003: import bdd.search.EnginePrefs;
004: import java.io.File;
005: import java.io.IOException;
006: import java.io.InputStream;
007: import java.io.OutputStream;
008: import java.io.FileInputStream;
009: import java.io.DataInputStream;
010: import java.io.DataOutputStream;
011: import java.util.StringTokenizer;
012: import java.util.Enumeration;
013: import java.util.Vector;
014: import java.util.Hashtable;
015:
016: /** Written by Tim Macinta 1997 <br>
017: * Distributed under the GNU Public License
018: * (a copy of which is enclosed with the source). <br>
019: * <br>
020: * This class searches the database for the given query.
021: */
022: public class DBQuery {
023: String query;
024: EnginePrefs prefs;
025:
026: public DBQuery(String query, EnginePrefs prefs) {
027: this .query = query;
028: this .prefs = prefs;
029: }
030:
031: public void dumpResults(OutputStream stream) throws IOException {
032:
033: // create a DataOutputStream
034:
035: DataOutputStream out;
036: if (stream instanceof DataOutputStream) {
037: out = (DataOutputStream) stream;
038: } else {
039: out = new DataOutputStream(stream);
040: }
041:
042: // determine results of query
043:
044: StringTokenizer st = new StringTokenizer(makeAlphaNumeric(query
045: .toLowerCase()), " ");
046: Vector results = new Vector(10, 20);
047: while (st.hasMoreTokens()) {
048: try {
049: addResultsToVector(st.nextToken(), results);
050: } catch (IOException e) {
051: }
052: }
053:
054: // handle the case where no results are found
055:
056: File f;
057: if (results.size() < 1) {
058: f = prefs.getNotFoundFile();
059: if (f.exists()) {
060: pipe(new FileInputStream(f), stream);
061: }
062: return;
063: }
064:
065: // output header file
066:
067: f = prefs.getHeaderFile();
068: if (f.exists()) {
069: pipe(new FileInputStream(f), stream);
070: }
071:
072: // output query results
073:
074: Enumeration en = results.elements();
075: int si = results.size();
076: if (si == 1) {
077: out.writeBytes("<pre>\n<bold>There was 1 result:\n\n");
078: } else {
079: out.writeBytes("<pre>\n<bold>There were " + si
080: + " results:\n\n");
081: }
082: while (en.hasMoreElements()) {
083: out.writeBytes(" " + ((String) en.nextElement())
084: + "<br>\n");
085: }
086: out.writeBytes("</pre>\n");
087:
088: // output footer file
089:
090: f = prefs.getFooterFile();
091: if (f.exists()) {
092: pipe(new FileInputStream(f), stream);
093: }
094:
095: }
096:
097: /** Returns a copy of "word" where all non-alphanumeric characters are
098: * converted to spaces (ascii 32).
099: */
100: String makeAlphaNumeric(String word) {
101: char[] w = word.toCharArray();
102: for (int i = w.length - 1; i >= 0; i--) {
103: if (!Character.isLetterOrDigit(w[i]))
104: w[i] = ' ';
105: }
106: return new String(w);
107: }
108:
109: /** Searches for the word contained in the database and adds a hyperlinked
110: * String describing each match to the Vector "v" with the most relevant
111: * matches being added first.
112: */
113: void addResultsToVector(String the_query, Vector v)
114: throws IOException {
115: DataInputStream in = new DataInputStream(new FileInputStream(
116: prefs.getMainIndex()));
117: in.skip(in.readLong() - 8);
118:
119: // find the word
120:
121: String word = in.readLine();
122: while (word != null && word.compareTo(the_query) < 0) {
123: while (in.readInt() != 0)
124: in.read();
125: word = in.readLine();
126: }
127: if (word != null && word.equals(the_query)) {
128:
129: // word found
130:
131: Vector scores = new Vector(5, 10);
132: Vector numbers = new Vector(5, 10);
133: Hashtable num = new Hashtable(8);
134: Integer i = new Integer(in.readInt());
135: while (i.intValue() != 0) {
136: numbers.addElement(i);
137: num.put(i, i);
138: scores
139: .addElement(new Integer(
140: ((int) in.read()) & 0xff));
141: i = new Integer(in.readInt());
142: }
143:
144: // load URL descriptions
145:
146: in.close();
147: in = new DataInputStream(new FileInputStream(prefs
148: .getMainIndex()));
149: in.readLong();
150: int targ = in.readInt();
151: for (int i2 = 1; i2 <= targ; i2++) {
152: i = new Integer(i2);
153: if (num.get(i) != null) {
154: num.put(i, in.readLine().trim());
155: } else {
156: in.readLine();
157: }
158: }
159:
160: // add URL descriptions to "v" in proper order
161:
162: Enumeration en1 = scores.elements();
163: Enumeration en2 = numbers.elements();
164: int i3;
165: String result;
166: String url;
167: while (en1.hasMoreElements()) {
168:
169: // convert score from 0-255 to 0-100
170:
171: i3 = ((Integer) en1.nextElement()).intValue();
172: i3 = (i3 * 100) / 255;
173: if (i3 > 99) {
174: result = "";
175: } else if (i3 > 9) {
176: result = " ";
177: } else {
178: result = " ";
179: }
180: url = (String) (num.get(en2.nextElement()));
181: result = result + i3 + " - <a href=\"" + url + "\">"
182: + url + "</a>";
183: v.addElement(result);
184: }
185: }
186: in.close();
187: }
188:
189: /** This is the method that is called when this class is invoked from the
190: * command line. If this method is called, the first argument (arg[0])
191: * is used as a new query and the results are piped to standard output.
192: * This could be used as a means for providing a cgi interface to the
193: * search database, although it isn't as efficient as running the
194: * custom web server that was built for this since running this via
195: * cgi requires starting a new copy of the Java Virtual Machine each
196: * time it is run.
197: */
198: public static void main(String arg[]) {
199: try {
200: String query;
201: if (arg.length < 1) {
202: query = "";
203: } else {
204: query = arg[0];
205: }
206: DBQuery dbq = new DBQuery(query, new EnginePrefs());
207: dbq.dumpResults(System.out);
208: } catch (Exception e) {
209: e.printStackTrace();
210: }
211: }
212:
213: /** Pipes "in" to "out" until "in" is exhausted then closes "in". */
214: void pipe(InputStream in, OutputStream out) throws IOException {
215: byte[] b = new byte[512];
216: int x = in.read(b, 0, b.length);
217: while (x > 0) {
218: out.write(b, 0, x);
219: x = in.read(b, 0, b.length);
220: }
221: in.close();
222: }
223:
224: }
|