Project

General

Profile

1
/**
2
 *  '$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
 *
12
 *   '$Author: jones $'
13
 *     '$Date: 2000-06-26 03:35:05 -0700 (Mon, 26 Jun 2000) $'
14
 * '$Revision: 203 $'
15
 */
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
 * 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
 */
34
public class DBQuery {
35

    
36
  private Connection	conn = null;
37
  private String	parserName = null;
38

    
39
  /**
40
   * the main routine used to test the DBQuery utility.
41
   * <p>
42
   * Usage: java DBQuery <xmlfile>
43
   *
44
   * @param xmlfile the filename of the xml file containing the query
45
   */
46
  static public void main(String[] args) {
47
     
48
     if (args.length < 1)
49
     {
50
        System.err.println("Wrong number of arguments!!!");
51
        System.err.println("USAGE: java DBQuery <xmlfile>");
52
        return;
53
     } else {
54
        try {
55
                    
56
          String xmlfile  = args[0];
57

    
58
          // Open a connection to the database
59
          MetaCatUtil   util = new MetaCatUtil();
60
          Connection dbconn = util.openDBConnection();
61

    
62
          // Execute the query
63
          DBQuery queryobj = new DBQuery(dbconn, util.getOption("saxparser"));
64
          FileReader xml = new FileReader(new File(xmlfile));
65
          Hashtable nodelist = null;
66
          nodelist = queryobj.findDocuments(xml);
67

    
68
          // Print the reulting document listing
69
          StringBuffer result = new StringBuffer();
70
          String document = null;
71
          String docid = null;
72
          result.append("<?xml version=\"1.0\"?>\n");
73
          result.append("<resultset>\n");
74
          result.append("  <query>" + xmlfile + "</query>\n");
75
          Enumeration doclist = nodelist.keys(); 
76
          while (doclist.hasMoreElements()) {
77
            docid = (String)doclist.nextElement();
78
            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
   * @param parserName the fully qualified name of a Java class implementing
102
   *                   the org.xml.sax.XMLReader interface
103
   */
104
  public DBQuery( Connection conn, String parserName ) 
105
                  throws IOException, 
106
                         SQLException, 
107
                         ClassNotFoundException {
108
    this.conn = conn;
109
    this.parserName = parserName;
110
  }
111
  
112
  /** 
113
   * routine to search the elements and attributes looking to match query
114
   *
115
   * @param xmlquery the xml serialization of the query (@see pathquery.dtd)
116
   */
117
  public Hashtable findDocuments(Reader xmlquery) {
118
      Hashtable	 docListResult = new Hashtable();
119
      PreparedStatement pstmt;
120
      String docid = null;
121
      String docname = null;
122
      String doctype = null;
123
      String doctitle = null;
124
      StringBuffer document = null; 
125

    
126
      try {
127
        // Get the XML query and covert it into a SQL statment
128
        QuerySpecification qspec = new QuerySpecification(xmlquery, 
129
                                   parserName);
130
        //System.out.println(qspec.printSQL());
131
        pstmt = conn.prepareStatement( qspec.printSQL() );
132

    
133
        // Execute the SQL query using the JDBC connection
134
        pstmt.execute();
135
        ResultSet rs = pstmt.getResultSet();
136
        boolean tableHasRows = rs.next();
137
        while (tableHasRows) {
138
          docid = rs.getString(1);
139
          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
          docListResult.put(docid,(String)document.toString());
157

    
158
          // Advance to the next record in the cursor
159
          tableHasRows = rs.next();
160
        }
161
        pstmt.close();
162
      } catch (SQLException e) {
163
        System.err.println("Error getting id: " + e.getMessage());
164
      } catch (IOException ioe) {
165
        System.err.println("Error printing qspec:");
166
        System.err.println(ioe.getMessage());
167
      }
168
    return docListResult;
169
  }
170

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

    
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
 */
(6-6/19)