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
|
* Release: @release@
|
12
|
*
|
13
|
* '$Author: berkley $'
|
14
|
* '$Date: 2000-09-26 15:06:52 -0700 (Tue, 26 Sep 2000) $'
|
15
|
* '$Revision: 465 $'
|
16
|
*/
|
17
|
|
18
|
package edu.ucsb.nceas.metacat;
|
19
|
|
20
|
import java.io.*;
|
21
|
import java.util.Vector;
|
22
|
import java.net.URL;
|
23
|
import java.net.MalformedURLException;
|
24
|
import java.sql.*;
|
25
|
import java.util.Stack;
|
26
|
import java.util.Hashtable;
|
27
|
import java.util.Enumeration;
|
28
|
|
29
|
/**
|
30
|
* A Class that searches a relational DB for elements and
|
31
|
* attributes that have free text matches a query string,
|
32
|
* or structured query matches to a path specified node in the
|
33
|
* XML hierarchy. It returns a result set consisting of the
|
34
|
* document ID for each document that satisfies the query
|
35
|
*/
|
36
|
public class DBQuery {
|
37
|
|
38
|
static final int ALL = 1;
|
39
|
static final int WRITE = 2;
|
40
|
static final int READ = 4;
|
41
|
|
42
|
private Connection conn = null;
|
43
|
private String parserName = null;
|
44
|
private MetaCatUtil util = new MetaCatUtil();
|
45
|
/**
|
46
|
* the main routine used to test the DBQuery utility.
|
47
|
* <p>
|
48
|
* Usage: java DBQuery <xmlfile>
|
49
|
*
|
50
|
* @param xmlfile the filename of the xml file containing the query
|
51
|
*/
|
52
|
static public void main(String[] args) {
|
53
|
|
54
|
if (args.length < 1)
|
55
|
{
|
56
|
System.err.println("Wrong number of arguments!!!");
|
57
|
System.err.println("USAGE: java DBQuery <xmlfile>");
|
58
|
return;
|
59
|
} else {
|
60
|
try {
|
61
|
|
62
|
String xmlfile = args[0];
|
63
|
|
64
|
// Open a connection to the database
|
65
|
MetaCatUtil util = new MetaCatUtil();
|
66
|
Connection dbconn = util.openDBConnection();
|
67
|
|
68
|
// Execute the query
|
69
|
DBQuery queryobj = new DBQuery(dbconn, util.getOption("saxparser"));
|
70
|
FileReader xml = new FileReader(new File(xmlfile));
|
71
|
Hashtable nodelist = null;
|
72
|
nodelist = queryobj.findDocuments(xml, null, null);
|
73
|
|
74
|
// Print the reulting document listing
|
75
|
StringBuffer result = new StringBuffer();
|
76
|
String document = null;
|
77
|
String docid = null;
|
78
|
result.append("<?xml version=\"1.0\"?>\n");
|
79
|
result.append("<resultset>\n");
|
80
|
// following line removed by Dan Higgins to avoid insertion of query XML inside returned XML doc
|
81
|
// result.append(" <query>" + xmlfile + "</query>\n");
|
82
|
Enumeration doclist = nodelist.keys();
|
83
|
while (doclist.hasMoreElements()) {
|
84
|
docid = (String)doclist.nextElement();
|
85
|
document = (String)nodelist.get(docid);
|
86
|
result.append(" <document>\n " + document +
|
87
|
"\n </document>\n");
|
88
|
}
|
89
|
result.append("</resultset>\n");
|
90
|
|
91
|
System.out.println(result);
|
92
|
|
93
|
} catch (Exception e) {
|
94
|
System.err.println("EXCEPTION HANDLING REQUIRED");
|
95
|
System.err.println(e.getMessage());
|
96
|
e.printStackTrace(System.err);
|
97
|
}
|
98
|
}
|
99
|
}
|
100
|
|
101
|
/**
|
102
|
* construct an instance of the DBQuery class
|
103
|
*
|
104
|
* <p>Generally, one would call the findDocuments() routine after creating
|
105
|
* an instance to specify the search query</p>
|
106
|
*
|
107
|
* @param conn the JDBC connection that we use for the query
|
108
|
* @param parserName the fully qualified name of a Java class implementing
|
109
|
* the org.xml.sax.XMLReader interface
|
110
|
*/
|
111
|
public DBQuery( Connection conn, String parserName )
|
112
|
throws IOException,
|
113
|
SQLException,
|
114
|
ClassNotFoundException {
|
115
|
this.conn = conn;
|
116
|
this.parserName = parserName;
|
117
|
}
|
118
|
|
119
|
public Hashtable findDocuments(Reader xmlquery, String user, String group)
|
120
|
{
|
121
|
return findDocuments(xmlquery, user, group, null);
|
122
|
}
|
123
|
|
124
|
/**
|
125
|
* routine to search the elements and attributes looking to match query
|
126
|
*
|
127
|
* @param xmlquery the xml serialization of the query (@see pathquery.dtd)
|
128
|
* @param user the username of the user
|
129
|
* @param group the group of the user
|
130
|
* @param returndoc an array of document types to backtrack against.
|
131
|
*/
|
132
|
public Hashtable findDocuments(Reader xmlquery, String user, String group,
|
133
|
String[] returndoc)
|
134
|
{
|
135
|
Hashtable docListResult = new Hashtable();
|
136
|
PreparedStatement pstmt;
|
137
|
String docid = null;
|
138
|
String docname = null;
|
139
|
String doctype = null;
|
140
|
String doctitle = null;
|
141
|
String createDate = null;
|
142
|
String updateDate = null;
|
143
|
String fieldname = null;
|
144
|
String fielddata = null;
|
145
|
String relation = null;
|
146
|
StringBuffer document = null;
|
147
|
Vector returndocVec = new Vector();
|
148
|
|
149
|
if(returndoc != null)
|
150
|
{//add the returndoc elements to a vector for easier manipulation
|
151
|
for(int i=0; i<returndoc.length; i++)
|
152
|
{
|
153
|
returndocVec.add(new String((String)returndoc[i]));
|
154
|
}
|
155
|
}
|
156
|
|
157
|
try {
|
158
|
// Get the XML query and covert it into a SQL statment
|
159
|
QuerySpecification qspec = new QuerySpecification(xmlquery,
|
160
|
parserName);
|
161
|
//System.out.println(qspec.printSQL());
|
162
|
pstmt = conn.prepareStatement( qspec.printSQL() );
|
163
|
|
164
|
// Execute the SQL query using the JDBC connection
|
165
|
pstmt.execute();
|
166
|
ResultSet rs = pstmt.getResultSet();
|
167
|
boolean tableHasRows = rs.next();
|
168
|
while (tableHasRows) {
|
169
|
docid = rs.getString(1);
|
170
|
if ( !hasReadPermission(conn, docid, user, group) ) {continue;}
|
171
|
docname = rs.getString(2);
|
172
|
doctype = rs.getString(3);
|
173
|
doctitle = rs.getString(4);
|
174
|
createDate = rs.getString(5);
|
175
|
updateDate = rs.getString(6);
|
176
|
|
177
|
if(returndocVec.size() != 0 && !returndocVec.contains(doctype))
|
178
|
{ //there are returndocs to match (backtracking can now be performed).
|
179
|
//System.out.println("olddoctype: " + doctype);
|
180
|
StringBuffer btBuf = new StringBuffer();
|
181
|
btBuf.append("select object from xml_relation where ");
|
182
|
btBuf.append("objdoctype in (");
|
183
|
//build the doctype list for the backtracking sql statement
|
184
|
for(int i=0; i<returndocVec.size(); i++)
|
185
|
{
|
186
|
btBuf.append("'").append((String)returndocVec.get(i)).append("'");
|
187
|
if(i != (returndocVec.size() - 1))
|
188
|
{
|
189
|
btBuf.append(", ");
|
190
|
}
|
191
|
}
|
192
|
btBuf.append(") ");
|
193
|
btBuf.append("and subject like '");
|
194
|
btBuf.append("metacat://docid#").append(docid).append("'");
|
195
|
pstmt = conn.prepareStatement(btBuf.toString());
|
196
|
pstmt.execute();
|
197
|
ResultSet btrs = pstmt.getResultSet();
|
198
|
boolean hasBtRows = btrs.next();
|
199
|
if(hasBtRows)
|
200
|
{ //there was a backtrackable document found
|
201
|
DocumentImpl xmldoc = null;
|
202
|
//System.out.println("document found is: " + btrs.getString(1));
|
203
|
metacatURL objURL = new metacatURL(btrs.getString(1));
|
204
|
try
|
205
|
{
|
206
|
xmldoc = new DocumentImpl(conn, objURL.getParam(0)[1]);
|
207
|
}
|
208
|
catch(Exception e)
|
209
|
{
|
210
|
System.out.println("Error getting document: " + e.getMessage());
|
211
|
}
|
212
|
|
213
|
docid = xmldoc.getDocID();
|
214
|
docname = xmldoc.getDocname();
|
215
|
doctype = xmldoc.getDoctype();
|
216
|
doctitle = xmldoc.getDocTitle();
|
217
|
createDate = xmldoc.getCreateDate();
|
218
|
updateDate = xmldoc.getUpdateDate();
|
219
|
//System.out.println("docname: " + docname + " doctype: " + doctype +
|
220
|
// " doctitle: " + doctitle + " createdate: " +
|
221
|
// createDate + " updatedate: " + updateDate);
|
222
|
}
|
223
|
btrs.close();
|
224
|
}
|
225
|
|
226
|
document = new StringBuffer();
|
227
|
//System.out.println("packagdoctype: " + util.getOption("packagedoctype"));
|
228
|
if(!doctype.equals(util.getOption("packagedoctype")))
|
229
|
{
|
230
|
document.append("<docid>").append(docid).append("</docid>");
|
231
|
if (docname != null) {
|
232
|
document.append("<docname>" + docname + "</docname>");
|
233
|
}
|
234
|
if (doctype != null) {
|
235
|
document.append("<doctype>" + doctype + "</doctype>");
|
236
|
}
|
237
|
if (doctitle != null) {
|
238
|
document.append("<doctitle>" + doctitle + "</doctitle>");
|
239
|
}
|
240
|
if(createDate != null) {
|
241
|
document.append("<createdate>" + createDate + "</createdate>");
|
242
|
}
|
243
|
if(updateDate != null) {
|
244
|
document.append("<updatedate>" + updateDate + "</updatedate>");
|
245
|
}
|
246
|
// Store the document id and the root node id
|
247
|
docListResult.put(docid,(String)document.toString());
|
248
|
}
|
249
|
|
250
|
// Advance to the next record in the cursor
|
251
|
tableHasRows = rs.next();
|
252
|
}
|
253
|
|
254
|
if(qspec.containsExtendedSQL())
|
255
|
{
|
256
|
Vector extendedFields = new Vector(qspec.getReturnFieldList());
|
257
|
Vector results = new Vector();
|
258
|
Enumeration keylist = docListResult.keys();
|
259
|
StringBuffer doclist = new StringBuffer();
|
260
|
while(keylist.hasMoreElements())
|
261
|
{
|
262
|
doclist.append("'");
|
263
|
doclist.append((String)keylist.nextElement());
|
264
|
doclist.append("',");
|
265
|
}
|
266
|
doclist.deleteCharAt(doclist.length()-1); //remove the last comma
|
267
|
pstmt = conn.prepareStatement(qspec.printExtendedSQL(
|
268
|
doclist.toString()));
|
269
|
pstmt.execute();
|
270
|
rs = pstmt.getResultSet();
|
271
|
tableHasRows = rs.next();
|
272
|
while(tableHasRows)
|
273
|
{
|
274
|
docid = rs.getString(1);
|
275
|
if ( !hasReadPermission(conn, docid, user, group) ) {continue;}
|
276
|
fieldname = rs.getString(2);
|
277
|
fielddata = rs.getString(3);
|
278
|
|
279
|
document = new StringBuffer();
|
280
|
|
281
|
document.append("<param name=\"");
|
282
|
document.append(fieldname);
|
283
|
document.append("\">");
|
284
|
document.append(fielddata);
|
285
|
document.append("</param>");
|
286
|
|
287
|
tableHasRows = rs.next();
|
288
|
if(docListResult.containsKey(docid))
|
289
|
{
|
290
|
String removedelement = (String)docListResult.remove(docid);
|
291
|
docListResult.put(docid, removedelement + document.toString());
|
292
|
}
|
293
|
else
|
294
|
{
|
295
|
docListResult.put(docid, document.toString());
|
296
|
}
|
297
|
}
|
298
|
}
|
299
|
|
300
|
//this loop adds the relation data to the resultdoc
|
301
|
//this code might be able to be added to the backtracking code above
|
302
|
Enumeration docidkeys = docListResult.keys();
|
303
|
while(docidkeys.hasMoreElements())
|
304
|
{
|
305
|
String docidkey = (String)docidkeys.nextElement();
|
306
|
pstmt = conn.prepareStatement(
|
307
|
qspec.printRelationSQL("metacat://docid#" + docidkey));
|
308
|
pstmt.execute();
|
309
|
rs = pstmt.getResultSet();
|
310
|
tableHasRows = rs.next();
|
311
|
while(tableHasRows)
|
312
|
{
|
313
|
String sub = rs.getString(1);
|
314
|
String rel = rs.getString(2);
|
315
|
String obj = rs.getString(3);
|
316
|
metacatURL murl = new metacatURL(sub);
|
317
|
if(murl.getURLType().equals("metacat"))
|
318
|
{//we only want to process metacat urls here.
|
319
|
String[] tempparam = murl.getParam(0);
|
320
|
if(tempparam[0].equals("docid") && tempparam[1].equals(docidkey))
|
321
|
{
|
322
|
document = new StringBuffer();
|
323
|
document.append("<relation>");
|
324
|
document.append("<relationtype>").append(rel);
|
325
|
document.append("</relationtype>");
|
326
|
document.append("<relationdoc>").append(obj);
|
327
|
document.append("</relationdoc>");
|
328
|
document.append("</relation>");
|
329
|
|
330
|
String removedelement = (String)docListResult.remove(docidkey);
|
331
|
docListResult.put(docidkey, removedelement + document.toString());
|
332
|
|
333
|
}
|
334
|
}
|
335
|
tableHasRows = rs.next();
|
336
|
}
|
337
|
}
|
338
|
pstmt.close();
|
339
|
} catch (SQLException e) {
|
340
|
System.err.println("Error getting id: " + e.getMessage());
|
341
|
} catch (IOException ioe) {
|
342
|
System.err.println("Error printing qspec:");
|
343
|
System.err.println(ioe.getMessage());
|
344
|
}
|
345
|
//System.out.println("docListResult: ");
|
346
|
//System.out.println(docListResult.toString());
|
347
|
return docListResult;
|
348
|
}
|
349
|
|
350
|
/**
|
351
|
* returns a string array of the contents of a particular node.
|
352
|
* If the node appears more than once, the contents are returned
|
353
|
* in the order in which they appearred in the document.
|
354
|
* @param nodename the name or path of the particular node.
|
355
|
* @param docid the docid of the document you want the node from.
|
356
|
* @param conn a database connection-this allows this method to be static
|
357
|
*/
|
358
|
public static Object[] getNodeContent(String nodename, String docid,
|
359
|
Connection conn)
|
360
|
{
|
361
|
StringBuffer query = new StringBuffer();
|
362
|
Vector result = new Vector();
|
363
|
PreparedStatement pstmt;
|
364
|
query.append("select nodedata from xml_nodes where parentnodeid in ");
|
365
|
query.append("(select nodeid from xml_index where path like '");
|
366
|
query.append(nodename);
|
367
|
query.append("' and docid like '").append(docid).append("')");
|
368
|
try
|
369
|
{
|
370
|
pstmt = conn.prepareStatement(query.toString());
|
371
|
|
372
|
// Execute the SQL query using the JDBC connection
|
373
|
pstmt.execute();
|
374
|
ResultSet rs = pstmt.getResultSet();
|
375
|
boolean tableHasRows = rs.next();
|
376
|
while (tableHasRows)
|
377
|
{
|
378
|
result.add(rs.getString(1));
|
379
|
System.out.println(rs.getString(1));
|
380
|
tableHasRows = rs.next();
|
381
|
}
|
382
|
}
|
383
|
catch (SQLException e)
|
384
|
{
|
385
|
System.err.println("Error getting id: " + e.getMessage());
|
386
|
}
|
387
|
|
388
|
return result.toArray();
|
389
|
}
|
390
|
|
391
|
/**
|
392
|
* format a structured query as an XML document that conforms
|
393
|
* to the pathquery.dtd and is appropriate for submission to the DBQuery
|
394
|
* structured query engine
|
395
|
*
|
396
|
* @param params The list of parameters that should be included in the query
|
397
|
*/
|
398
|
public static String createSQuery(Hashtable params)
|
399
|
{
|
400
|
StringBuffer query = new StringBuffer();
|
401
|
Enumeration elements;
|
402
|
Enumeration keys;
|
403
|
String doctype = null;
|
404
|
String casesensitive = null;
|
405
|
String searchmode = null;
|
406
|
Object nextkey;
|
407
|
Object nextelement;
|
408
|
//add the xml headers
|
409
|
query.append("<?xml version=\"1.0\"?>\n");
|
410
|
query.append("<pathquery version=\"1.0\"><meta_file_id>");
|
411
|
|
412
|
if(params.containsKey("meta_file_id"))
|
413
|
{
|
414
|
query.append( ((String[])params.get("meta_file_id"))[0]);
|
415
|
query.append("</meta_file_id>");
|
416
|
}
|
417
|
else
|
418
|
{
|
419
|
query.append("unspecified</meta_file_id>");
|
420
|
}
|
421
|
|
422
|
query.append("<querytitle>");
|
423
|
if(params.containsKey("querytitle"))
|
424
|
{
|
425
|
query.append(((String[])params.get("querytitle"))[0]);
|
426
|
query.append("</querytitle>");
|
427
|
}
|
428
|
else
|
429
|
{
|
430
|
query.append("unspecified</querytitle>");
|
431
|
}
|
432
|
|
433
|
if(params.containsKey("doctype"))
|
434
|
{
|
435
|
doctype = ((String[])params.get("doctype"))[0];
|
436
|
}
|
437
|
else
|
438
|
{
|
439
|
doctype = "ANY";
|
440
|
}
|
441
|
|
442
|
if(params.containsKey("returnfield"))
|
443
|
{
|
444
|
String[] returnfield = ((String[])params.get("returnfield"));
|
445
|
for(int i=0; i<returnfield.length; i++)
|
446
|
{
|
447
|
query.append("<returnfield>").append(returnfield[i]);
|
448
|
query.append("</returnfield>");
|
449
|
}
|
450
|
}
|
451
|
|
452
|
//if you don't limit the query by doctype, then it just creates
|
453
|
//an empty returndoctype tag.
|
454
|
if (!doctype.equals("any") &&
|
455
|
!doctype.equals("ANY") &&
|
456
|
!doctype.equals("") )
|
457
|
{
|
458
|
query.append("<returndoctype>");
|
459
|
query.append(doctype).append("</returndoctype>");
|
460
|
}
|
461
|
else
|
462
|
{
|
463
|
query.append("<returndoctype></returndoctype>");
|
464
|
}
|
465
|
|
466
|
//allows the dynamic switching of boolean operators
|
467
|
if(params.containsKey("operator"))
|
468
|
{
|
469
|
query.append("<querygroup operator=\"" +
|
470
|
((String[])params.get("operator"))[0] + "\">");
|
471
|
}
|
472
|
else
|
473
|
{ //the default operator is UNION
|
474
|
query.append("<querygroup operator=\"UNION\">");
|
475
|
}
|
476
|
|
477
|
if(params.containsKey("casesensitive"))
|
478
|
{
|
479
|
casesensitive = ((String[])params.get("casesensitive"))[0];
|
480
|
}
|
481
|
else
|
482
|
{
|
483
|
casesensitive = "false";
|
484
|
}
|
485
|
|
486
|
if(params.containsKey("searchmode"))
|
487
|
{
|
488
|
searchmode = ((String[])params.get("searchmode"))[0];
|
489
|
}
|
490
|
else
|
491
|
{
|
492
|
searchmode = "contains";
|
493
|
}
|
494
|
|
495
|
//anyfield is a special case because it does a
|
496
|
//free text search. It does not have a <pathexpr>
|
497
|
//tag. This allows for a free text search within the structured
|
498
|
//query. This is useful if the INTERSECT operator is used.
|
499
|
if(params.containsKey("anyfield"))
|
500
|
{
|
501
|
String[] anyfield = ((String[])params.get("anyfield"));
|
502
|
//allow for more than one value for anyfield
|
503
|
for(int i=0; i<anyfield.length; i++)
|
504
|
{
|
505
|
if(!anyfield[i].equals(""))
|
506
|
{
|
507
|
query.append("<queryterm casesensitive=\"" + casesensitive +
|
508
|
"\" " + "searchmode=\"" + searchmode + "\"><value>" +
|
509
|
anyfield[i] +
|
510
|
"</value></queryterm>");
|
511
|
}
|
512
|
}
|
513
|
}
|
514
|
|
515
|
//this while loop finds the rest of the parameters
|
516
|
//and attempts to query for the field specified
|
517
|
//by the parameter.
|
518
|
elements = params.elements();
|
519
|
keys = params.keys();
|
520
|
while(keys.hasMoreElements() && elements.hasMoreElements())
|
521
|
{
|
522
|
nextkey = keys.nextElement();
|
523
|
nextelement = elements.nextElement();
|
524
|
|
525
|
//make sure we aren't querying for any of these
|
526
|
//parameters since the are already in the query
|
527
|
//in one form or another.
|
528
|
if(!nextkey.toString().equals("doctype") &&
|
529
|
!nextkey.toString().equals("action") &&
|
530
|
!nextkey.toString().equals("qformat") &&
|
531
|
!nextkey.toString().equals("anyfield") &&
|
532
|
!nextkey.toString().equals("returnfield") &&
|
533
|
!nextkey.toString().equals("operator") )
|
534
|
{
|
535
|
//allow for more than value per field name
|
536
|
for(int i=0; i<((String[])nextelement).length; i++)
|
537
|
{
|
538
|
if(!((String[])nextelement)[i].equals(""))
|
539
|
{
|
540
|
query.append("<queryterm casesensitive=\"" + casesensitive +"\" " +
|
541
|
"searchmode=\"" + searchmode + "\">" +
|
542
|
"<value>" +
|
543
|
//add the query value
|
544
|
((String[])nextelement)[i] +
|
545
|
"</value><pathexpr>" +
|
546
|
//add the path to query by
|
547
|
nextkey.toString() +
|
548
|
"</pathexpr></queryterm>");
|
549
|
}
|
550
|
}
|
551
|
}
|
552
|
}
|
553
|
query.append("</querygroup></pathquery>");
|
554
|
//append on the end of the xml and return the result as a string
|
555
|
return query.toString();
|
556
|
}
|
557
|
|
558
|
/**
|
559
|
* format a simple free-text value query as an XML document that conforms
|
560
|
* to the pathquery.dtd and is appropriate for submission to the DBQuery
|
561
|
* structured query engine
|
562
|
*
|
563
|
* @param value the text string to search for in the xml catalog
|
564
|
* @param doctype the type of documents to include in the result set -- use
|
565
|
* "any" or "ANY" for unfiltered result sets
|
566
|
*/
|
567
|
public static String createQuery(String value, String doctype) {
|
568
|
StringBuffer xmlquery = new StringBuffer();
|
569
|
xmlquery.append("<?xml version=\"1.0\"?>\n");
|
570
|
xmlquery.append("<pathquery version=\"1.0\">");
|
571
|
xmlquery.append("<meta_file_id>Unspecified</meta_file_id>");
|
572
|
xmlquery.append("<querytitle>Unspecified</querytitle>");
|
573
|
|
574
|
if (!doctype.equals("any") && !doctype.equals("ANY")) {
|
575
|
xmlquery.append("<returndoctype>");
|
576
|
xmlquery.append(doctype).append("</returndoctype>");
|
577
|
}
|
578
|
|
579
|
xmlquery.append("<querygroup operator=\"UNION\">");
|
580
|
//chad added - 8/14
|
581
|
//the if statement allows a query to gracefully handle a null
|
582
|
//query. Without this if a nullpointerException is thrown.
|
583
|
if(!value.equals(""))
|
584
|
{
|
585
|
xmlquery.append("<queryterm casesensitive=\"false\" ");
|
586
|
xmlquery.append("searchmode=\"contains\">");
|
587
|
xmlquery.append("<value>").append(value).append("</value>");
|
588
|
xmlquery.append("</queryterm>");
|
589
|
}
|
590
|
xmlquery.append("</querygroup>");
|
591
|
xmlquery.append("</pathquery>");
|
592
|
|
593
|
|
594
|
return (xmlquery.toString());
|
595
|
}
|
596
|
|
597
|
/**
|
598
|
* format a simple free-text value query as an XML document that conforms
|
599
|
* to the pathquery.dtd and is appropriate for submission to the DBQuery
|
600
|
* structured query engine
|
601
|
*
|
602
|
* @param value the text string to search for in the xml catalog
|
603
|
*/
|
604
|
public static String createQuery(String value) {
|
605
|
return createQuery(value, "any");
|
606
|
}
|
607
|
|
608
|
/** Check for "read" permissions from DB connection */
|
609
|
private boolean hasReadPermission(Connection conn, String docid,
|
610
|
String user, String group)
|
611
|
throws SQLException {
|
612
|
// b' of the command line invocation
|
613
|
if ( (user == null) && (group == null) ) {
|
614
|
return true;
|
615
|
}
|
616
|
|
617
|
PreparedStatement pstmt;
|
618
|
// checking if user is owner of docid or if docid has public access
|
619
|
try {
|
620
|
pstmt = conn.prepareStatement(
|
621
|
"SELECT 'x' FROM xml_documents " +
|
622
|
"WHERE docid LIKE ? AND user_owner LIKE ? " +
|
623
|
"UNION " +
|
624
|
"SELECT 'x' FROM xml_documents " +
|
625
|
"WHERE docid LIKE ? AND public_access = 1");
|
626
|
// Bind the values to the query
|
627
|
pstmt.setString(1, docid);
|
628
|
pstmt.setString(2, user);
|
629
|
pstmt.setString(3, docid);
|
630
|
|
631
|
pstmt.execute();
|
632
|
ResultSet rs = pstmt.getResultSet();
|
633
|
boolean hasRow = rs.next();
|
634
|
pstmt.close();
|
635
|
if (hasRow) {
|
636
|
return true;
|
637
|
}
|
638
|
|
639
|
} catch (SQLException e) {
|
640
|
throw new
|
641
|
SQLException("Error checking document's owner or public access: "
|
642
|
+ e.getMessage());
|
643
|
}
|
644
|
|
645
|
// checking if docid has public access at this time
|
646
|
try {
|
647
|
pstmt = conn.prepareStatement(
|
648
|
"SELECT 'x' FROM xml_access " +
|
649
|
"WHERE docid LIKE ? " +
|
650
|
"AND principal_name = 'public' " +
|
651
|
"AND principal_type = 'user' " +
|
652
|
"AND sysdate BETWEEN nvl(begin_time,sysdate) " +
|
653
|
"AND nvl(end_time,sysdate)");
|
654
|
// Bind the values to the query
|
655
|
pstmt.setString(1, docid);
|
656
|
|
657
|
pstmt.execute();
|
658
|
ResultSet rs = pstmt.getResultSet();
|
659
|
boolean hasRow = rs.next();
|
660
|
pstmt.close();
|
661
|
if (hasRow) {
|
662
|
return true;
|
663
|
}
|
664
|
|
665
|
} catch (SQLException e) {
|
666
|
throw new
|
667
|
SQLException("Error checking doc's public access: " + e.getMessage());
|
668
|
}
|
669
|
|
670
|
// checking access type from xml_access table
|
671
|
int accesstype = 0;
|
672
|
try {
|
673
|
pstmt = conn.prepareStatement(
|
674
|
"SELECT access_type FROM xml_access " +
|
675
|
"WHERE docid LIKE ? " +
|
676
|
"AND principal_name LIKE ? " +
|
677
|
"AND principal_type = 'user' " +
|
678
|
"AND sysdate BETWEEN nvl(begin_time,sysdate) " +
|
679
|
"AND nvl(end_time,sysdate) " +
|
680
|
"UNION " +
|
681
|
"SELECT access_type FROM xml_access " +
|
682
|
"WHERE docid LIKE ? " +
|
683
|
"AND principal_name LIKE ? " +
|
684
|
"AND principal_type = 'group' " +
|
685
|
"AND sysdate BETWEEN nvl(begin_time,sysdate) " +
|
686
|
"AND nvl(end_time,sysdate)");
|
687
|
// Bind the values to the query
|
688
|
pstmt.setString(1, docid);
|
689
|
pstmt.setString(2, user);
|
690
|
pstmt.setString(3, docid);
|
691
|
pstmt.setString(2, group);
|
692
|
|
693
|
pstmt.execute();
|
694
|
ResultSet rs = pstmt.getResultSet();
|
695
|
boolean hasRows = rs.next();
|
696
|
while ( hasRows ) {
|
697
|
accesstype = rs.getInt(1);
|
698
|
if ( (accesstype & READ) == READ ) {
|
699
|
pstmt.close();
|
700
|
return true;
|
701
|
}
|
702
|
hasRows = rs.next();
|
703
|
}
|
704
|
|
705
|
pstmt.close();
|
706
|
return false;
|
707
|
|
708
|
} catch (SQLException e) {
|
709
|
throw new
|
710
|
SQLException("Error getting document's permissions: " + e.getMessage());
|
711
|
}
|
712
|
}
|
713
|
|
714
|
}
|
715
|
|
716
|
/**
|
717
|
* '$Log$
|
718
|
* 'Revision 1.20 2000/09/15 19:52:11 berkley
|
719
|
* 'Added functionality for package specifications. metacatservlet now contains a new action called getrelateddocument that handles retrieving related documents using the metacatURL specification (metacatURL.java). DBQuery contains new code in runQuery that embeds relation tags in the returned hashtable describing the documents related to each docid. querySpecification contains a new method which prints the sql that does the relation query.
|
720
|
* '
|
721
|
* 'Revision 1.19 2000/09/12 17:37:07 bojilova
|
722
|
* 'added check from "read" permission on "query" and "squery" actions
|
723
|
* 'for connected user or for "public" connection
|
724
|
* '
|
725
|
* 'Revision 1.18 2000/09/05 20:50:56 berkley
|
726
|
* 'Added a method called getNodeContent which retrieves the content of a node in a document. If there are more than one nodes with the same name returned, it returns an array with all of the data.
|
727
|
* '
|
728
|
* 'Revision 1.17 2000/08/31 21:20:39 berkley
|
729
|
* 'changed xslf for new returnfield scheme. the returnfields are now returned as <param name="<returnfield>"> tags.
|
730
|
* 'hThe sql for the returnfield query was redone to fix a previous problem with slow queries
|
731
|
* '
|
732
|
* 'Revision 1.16 2000/08/23 22:55:25 berkley
|
733
|
* 'changed the field names to be case-sensitive in the returnfields
|
734
|
* '
|
735
|
* 'Revision 1.15 2000/08/23 17:22:07 berkley
|
736
|
* 'added support for the returnfield parameter
|
737
|
* '-added the dynamic parameters to the returned hash table of documents
|
738
|
* '
|
739
|
* 'Revision 1.14 2000/08/17 16:02:34 berkley
|
740
|
* 'Made changes to createSQuery to allow for multiple parameters of the same name. Also changed the param list to include only "Hashtable params" without a "String doctype" since the doctype is already contained in the params.
|
741
|
* '
|
742
|
* 'Revision 1.13 2000/08/14 21:26:12 berkley
|
743
|
* 'Added createSQuery() to handle structured queries of an arbitrary number of parameters. Also modified createQuery() to handle a null query in a graceful manner.
|
744
|
* '
|
745
|
* 'Revision 1.12 2000/08/14 20:53:33 jones
|
746
|
* 'Added "release" keyword to all metacat source files so that the release
|
747
|
* 'number will be evident in software distributions.
|
748
|
* '
|
749
|
* 'Revision 1.11 2000/08/11 18:26:07 berkley
|
750
|
* 'added createSQuery
|
751
|
* '
|
752
|
* 'Revision 1.10 2000/07/26 20:40:41 higgins
|
753
|
* 'no message
|
754
|
* '
|
755
|
* 'Revision 1.9 2000/06/26 10:35:04 jones
|
756
|
* 'Merged in substantial changes to DBWriter and associated classes and to
|
757
|
* 'the MetaCatServlet in order to accomodate the new UPDATE and DELETE
|
758
|
* 'functions. The command line tools and the parameters for the
|
759
|
* 'servlet have changed substantially.
|
760
|
* '
|
761
|
* 'Revision 1.8.2.2 2000/06/25 23:38:16 jones
|
762
|
* 'Added RCSfile keyword
|
763
|
* '
|
764
|
* 'Revision 1.8.2.1 2000/06/25 23:34:17 jones
|
765
|
* 'Changed documentation formatting, added log entries at bottom of source files
|
766
|
* ''
|
767
|
*/
|