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: higgins $'
13
 *     '$Date: 2000-07-26 13:40:41 -0700 (Wed, 26 Jul 2000) $'
14
 * '$Revision: 296 $'
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
  // following line removed by Dan Higgins to avoid insertion of query XML inside returned XML doc
75
  //        result.append("  <query>" + xmlfile + "</query>\n");
76
          Enumeration doclist = nodelist.keys(); 
77
          while (doclist.hasMoreElements()) {
78
            docid = (String)doclist.nextElement();
79
            document = (String)nodelist.get(docid);
80
            result.append("  <document>\n    " + document + 
81
                          "\n  </document>\n");
82
          }
83
          result.append("</resultset>\n");
84

    
85
          System.out.println(result);
86

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

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

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

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

    
156
          // Store the document id and the root node id
157
          docListResult.put(docid,(String)document.toString());
158

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

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

    
191
     if (!doctype.equals("any") && !doctype.equals("ANY")) {
192
       xmlquery.append("<returndoctype>");
193
       xmlquery.append(doctype).append("</returndoctype>");
194
     }
195

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

    
204
     
205
     return (xmlquery.toString());
206
   }
207

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

    
220
/**
221
 * '$Log$
222
 * 'Revision 1.9  2000/06/26 10:35:04  jones
223
 * 'Merged in substantial changes to DBWriter and associated classes and to
224
 * 'the MetaCatServlet in order to accomodate the new UPDATE and DELETE
225
 * 'functions.  The command line tools and the parameters for the
226
 * 'servlet have changed substantially.
227
 * '
228
 * 'Revision 1.8.2.2  2000/06/25 23:38:16  jones
229
 * 'Added RCSfile keyword
230
 * '
231
 * 'Revision 1.8.2.1  2000/06/25 23:34:17  jones
232
 * 'Changed documentation formatting, added log entries at bottom of source files
233
 * ''
234
 */
(9-9/25)