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