Project

General

Profile

1
/**
2
 *      Name: DBQuery.java
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
 *   Version: '$Id: DBQuery.java 184 2000-06-21 02:57:19Z jones $'
13
 */
14

    
15
package edu.ucsb.nceas.metacat;
16

    
17
import java.io.*;
18
import java.net.URL;
19
import java.net.MalformedURLException;
20
import java.sql.*;
21
import java.util.Stack;
22
import java.util.Hashtable;
23
import java.util.Enumeration;
24

    
25
/** 
26
 * A Class that searches a relational DB for elements and 
27
 * attributes that have free text matches a query string,
28
 * or structured query matches to a path specified node in the 
29
 * XML hierarchy.  It returns a result set consisting of the 
30
 * document ID for each document that satisfies the query
31
 */
32
public class DBQuery {
33

    
34
  private Connection	conn = null;
35
  private String	parserName = null;
36

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

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

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

    
66
          // Print the reulting document listing
67
          StringBuffer result = new StringBuffer();
68
          String document = null;
69
          String docid = null;
70
          result.append("<?xml version=\"1.0\"?>\n");
71
          result.append("<resultset>\n");
72
          result.append("  <query>" + xmlfile + "</query>\n");
73
          Enumeration doclist = nodelist.keys(); 
74
          while (doclist.hasMoreElements()) {
75
            docid = (String)doclist.nextElement();
76
            document = (String)nodelist.get(docid);
77
            result.append("  <document>\n    " + document + 
78
                          "\n  </document>\n");
79
          }
80
          result.append("</resultset>\n");
81

    
82
          System.out.println(result);
83

    
84
        } catch (Exception e) {
85
          System.err.println("EXCEPTION HANDLING REQUIRED");
86
          System.err.println(e.getMessage());
87
          e.printStackTrace(System.err);
88
        }
89
     }
90
  }
91
  
92
  /**
93
   * construct an instance of the DBQuery class 
94
   *
95
   * <p>Generally, one would call the findDocuments() routine after creating 
96
   * an instance to specify the search query</p>
97
   *
98
   * @param conn the JDBC connection that we use for the query
99
   * @param parserName the fully qualified name of a Java class implementing
100
   *                   the org.xml.sax.Parser interface
101
   */
102
  public DBQuery( Connection conn, String parserName ) 
103
                  throws IOException, 
104
                         SQLException, 
105
                         ClassNotFoundException {
106
    this.conn = conn;
107
    this.parserName = parserName;
108
  }
109
  
110
  /** 
111
   * routine to search the elements and attributes looking to match query
112
   *
113
   * @param xmlquery the xml serialization of the query (@see pathquery.dtd)
114
   */
115
  public Hashtable findDocuments(Reader xmlquery) {
116
      Hashtable	 docListResult = new Hashtable();
117
      PreparedStatement pstmt;
118
      String docid = null;
119
      String docname = null;
120
      String doctype = null;
121
      String doctitle = null;
122
      StringBuffer document = null; 
123

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

    
131
        // Execute the SQL query using the JDBC connection
132
        pstmt.execute();
133
        ResultSet rs = pstmt.getResultSet();
134
        boolean tableHasRows = rs.next();
135
        while (tableHasRows) {
136
          docid = rs.getString(1);
137
          docname = rs.getString(2);
138
          doctype = rs.getString(3);
139
          doctitle = rs.getString(4);
140

    
141
          document = new StringBuffer();
142
          document.append("<docid>").append(docid).append("</docid>");
143
          if (docname != null) {
144
            document.append("<docname>" + docname + "</docname>");
145
          }
146
          if (doctype != null) {
147
            document.append("<doctype>" + doctype + "</doctype>");
148
          }
149
          if (doctitle != null) {
150
            document.append("<doctitle>" + doctitle + "</doctitle>");
151
          }
152

    
153
          // Store the document id and the root node id
154
          docListResult.put(docid,(String)document.toString());
155

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

    
169
  /**
170
   * format a simple free-text value query as an XML document that conforms
171
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
172
   * structured query engine
173
   *
174
   * @param value the text string to search for in the xml catalog
175
   * @param doctype the type of documents to include in the result set -- use
176
   *        "any" or "ANY" for unfiltered result sets
177
   */
178
   public static String createQuery(String value, String doctype) {
179
     StringBuffer xmlquery = new StringBuffer();
180
     xmlquery.append("<?xml version=\"1.0\"?>\n");
181
     xmlquery.append("<!DOCTYPE pathquery PUBLIC ");
182
     xmlquery.append("\"-//NCEAS//pathquery-1.0//EN\" ");
183
     xmlquery.append("\"http://24.237.19.164/xmltodb/lib/pathquery.dtd\" >");
184
     xmlquery.append("<pathquery version=\"1.0\">");
185
     xmlquery.append("<meta_file_id>Unspecified</meta_file_id>");
186
     xmlquery.append("<querytitle>Unspecified</querytitle>");
187

    
188
     if (!doctype.equals("any") && !doctype.equals("ANY")) {
189
       xmlquery.append("<returndoctype>");
190
       xmlquery.append(doctype).append("</returndoctype>");
191
     }
192

    
193
     xmlquery.append("<querygroup operator=\"UNION\">");
194
     xmlquery.append("<queryterm casesensitive=\"false\" ");
195
     xmlquery.append("searchmode=\"contains\">");
196
     xmlquery.append("<value>").append(value).append("</value>");
197
     xmlquery.append("</queryterm>");
198
     xmlquery.append("</querygroup>");
199
     xmlquery.append("</pathquery>");
200

    
201
     
202
     return (xmlquery.toString());
203
   }
204

    
205
  /**
206
   * format a simple free-text value query as an XML document that conforms
207
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
208
   * structured query engine
209
   *
210
   * @param value the text string to search for in the xml catalog
211
   */
212
   public static String createQuery(String value) {
213
     return createQuery(value, "any");
214
   }
215
}
(5-5/20)