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