Project

General

Profile

1 155 jones
/**
2 203 jones
 *  '$RCSfile$'
3
 *    Purpose: A Class that searches a relational DB for elements and
4
 *             attributes that have free text matches a query string,
5
 *             or structured query matches to a path specified node in the
6
 *             XML hierarchy.  It returns a result set consisting of the
7
 *             document ID for each document that satisfies the query
8
 *  Copyright: 2000 Regents of the University of California and the
9
 *             National Center for Ecological Analysis and Synthesis
10
 *    Authors: Matt Jones
11 155 jones
 *
12 203 jones
 *   '$Author$'
13
 *     '$Date$'
14
 * '$Revision$'
15 155 jones
 */
16
17
package edu.ucsb.nceas.metacat;
18
19
import java.io.*;
20
import java.net.URL;
21
import java.net.MalformedURLException;
22
import java.sql.*;
23
import java.util.Stack;
24
import java.util.Hashtable;
25
import java.util.Enumeration;
26
27
/**
28 172 jones
 * A Class that searches a relational DB for elements and
29
 * attributes that have free text matches a query string,
30
 * or structured query matches to a path specified node in the
31
 * XML hierarchy.  It returns a result set consisting of the
32
 * document ID for each document that satisfies the query
33 155 jones
 */
34
public class DBQuery {
35
36
  private Connection	conn = null;
37 172 jones
  private String	parserName = null;
38 155 jones
39
  /**
40
   * the main routine used to test the DBQuery utility.
41 184 jones
   * <p>
42
   * Usage: java DBQuery <xmlfile>
43 155 jones
   *
44 170 jones
   * @param xmlfile the filename of the xml file containing the query
45 155 jones
   */
46
  static public void main(String[] args) {
47
48 184 jones
     if (args.length < 1)
49 155 jones
     {
50
        System.err.println("Wrong number of arguments!!!");
51 184 jones
        System.err.println("USAGE: java DBQuery <xmlfile>");
52 155 jones
        return;
53
     } else {
54
        try {
55
56 170 jones
          String xmlfile  = args[0];
57 155 jones
58
          // Open a connection to the database
59 184 jones
          MetaCatUtil   util = new MetaCatUtil();
60
          Connection dbconn = util.openDBConnection();
61 172 jones
62 170 jones
          // Execute the query
63 184 jones
          DBQuery queryobj = new DBQuery(dbconn, util.getOption("saxparser"));
64 170 jones
          FileReader xml = new FileReader(new File(xmlfile));
65 155 jones
          Hashtable nodelist = null;
66 181 jones
          nodelist = queryobj.findDocuments(xml);
67 155 jones
68 172 jones
          // Print the reulting document listing
69 155 jones
          StringBuffer result = new StringBuffer();
70
          String document = null;
71 170 jones
          String docid = null;
72 155 jones
          result.append("<?xml version=\"1.0\"?>\n");
73
          result.append("<resultset>\n");
74 170 jones
          result.append("  <query>" + xmlfile + "</query>\n");
75 155 jones
          Enumeration doclist = nodelist.keys();
76
          while (doclist.hasMoreElements()) {
77 170 jones
            docid = (String)doclist.nextElement();
78 155 jones
            document = (String)nodelist.get(docid);
79
            result.append("  <document>\n    " + document +
80
                          "\n  </document>\n");
81
          }
82
          result.append("</resultset>\n");
83
84
          System.out.println(result);
85
86
        } catch (Exception e) {
87
          System.err.println("EXCEPTION HANDLING REQUIRED");
88
          System.err.println(e.getMessage());
89
          e.printStackTrace(System.err);
90
        }
91
     }
92
  }
93
94
  /**
95
   * construct an instance of the DBQuery class
96
   *
97
   * <p>Generally, one would call the findDocuments() routine after creating
98
   * an instance to specify the search query</p>
99
   *
100
   * @param conn the JDBC connection that we use for the query
101 172 jones
   * @param parserName the fully qualified name of a Java class implementing
102 185 jones
   *                   the org.xml.sax.XMLReader interface
103 155 jones
   */
104 172 jones
  public DBQuery( Connection conn, String parserName )
105 155 jones
                  throws IOException,
106
                         SQLException,
107 172 jones
                         ClassNotFoundException {
108 155 jones
    this.conn = conn;
109 172 jones
    this.parserName = parserName;
110 155 jones
  }
111
112
  /**
113
   * routine to search the elements and attributes looking to match query
114
   *
115 178 jones
   * @param xmlquery the xml serialization of the query (@see pathquery.dtd)
116 155 jones
   */
117 178 jones
  public Hashtable findDocuments(Reader xmlquery) {
118 155 jones
      Hashtable	 docListResult = new Hashtable();
119
      PreparedStatement pstmt;
120 170 jones
      String docid = null;
121 155 jones
      String docname = null;
122
      String doctype = null;
123
      String doctitle = null;
124
      StringBuffer document = null;
125
126
      try {
127 172 jones
        // Get the XML query and covert it into a SQL statment
128 178 jones
        QuerySpecification qspec = new QuerySpecification(xmlquery,
129 172 jones
                                   parserName);
130 180 jones
        //System.out.println(qspec.printSQL());
131 172 jones
        pstmt = conn.prepareStatement( qspec.printSQL() );
132 155 jones
133 172 jones
        // Execute the SQL query using the JDBC connection
134 155 jones
        pstmt.execute();
135
        ResultSet rs = pstmt.getResultSet();
136
        boolean tableHasRows = rs.next();
137
        while (tableHasRows) {
138 170 jones
          docid = rs.getString(1);
139 155 jones
          docname = rs.getString(2);
140
          doctype = rs.getString(3);
141
          doctitle = rs.getString(4);
142
143
          document = new StringBuffer();
144
          document.append("<docid>").append(docid).append("</docid>");
145
          if (docname != null) {
146
            document.append("<docname>" + docname + "</docname>");
147
          }
148
          if (doctype != null) {
149
            document.append("<doctype>" + doctype + "</doctype>");
150
          }
151
          if (doctitle != null) {
152
            document.append("<doctitle>" + doctitle + "</doctitle>");
153
          }
154
155
          // Store the document id and the root node id
156 170 jones
          docListResult.put(docid,(String)document.toString());
157 155 jones
158
          // Advance to the next record in the cursor
159
          tableHasRows = rs.next();
160
        }
161
        pstmt.close();
162
      } catch (SQLException e) {
163 180 jones
        System.err.println("Error getting id: " + e.getMessage());
164 170 jones
      } catch (IOException ioe) {
165
        System.err.println("Error printing qspec:");
166
        System.err.println(ioe.getMessage());
167 155 jones
      }
168
    return docListResult;
169
  }
170 181 jones
171
  /**
172
   * format a simple free-text value query as an XML document that conforms
173
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
174
   * structured query engine
175
   *
176
   * @param value the text string to search for in the xml catalog
177
   * @param doctype the type of documents to include in the result set -- use
178
   *        "any" or "ANY" for unfiltered result sets
179
   */
180
   public static String createQuery(String value, String doctype) {
181
     StringBuffer xmlquery = new StringBuffer();
182
     xmlquery.append("<?xml version=\"1.0\"?>\n");
183 185 jones
     //xmlquery.append("<!DOCTYPE pathquery PUBLIC ");
184
     //xmlquery.append("\"-//NCEAS//pathquery-1.0//EN\" ");
185
     //xmlquery.append("\"http://24.237.19.164/xmltodb/lib/pathquery.dtd\" >");
186 181 jones
     xmlquery.append("<pathquery version=\"1.0\">");
187
     xmlquery.append("<meta_file_id>Unspecified</meta_file_id>");
188
     xmlquery.append("<querytitle>Unspecified</querytitle>");
189
190
     if (!doctype.equals("any") && !doctype.equals("ANY")) {
191
       xmlquery.append("<returndoctype>");
192
       xmlquery.append(doctype).append("</returndoctype>");
193
     }
194
195
     xmlquery.append("<querygroup operator=\"UNION\">");
196
     xmlquery.append("<queryterm casesensitive=\"false\" ");
197
     xmlquery.append("searchmode=\"contains\">");
198
     xmlquery.append("<value>").append(value).append("</value>");
199
     xmlquery.append("</queryterm>");
200
     xmlquery.append("</querygroup>");
201
     xmlquery.append("</pathquery>");
202
203
204
     return (xmlquery.toString());
205
   }
206
207
  /**
208
   * format a simple free-text value query as an XML document that conforms
209
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
210
   * structured query engine
211
   *
212
   * @param value the text string to search for in the xml catalog
213
   */
214
   public static String createQuery(String value) {
215
     return createQuery(value, "any");
216
   }
217 155 jones
}
218 203 jones
219
/**
220
 * '$Log$
221
 * 'Revision 1.8.2.2  2000/06/25 23:38:16  jones
222
 * 'Added RCSfile keyword
223
 * '
224
 * 'Revision 1.8.2.1  2000/06/25 23:34:17  jones
225
 * 'Changed documentation formatting, added log entries at bottom of source files
226
 * ''
227
 */