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
 *    Release: @release@
12
 *
13
 *   '$Author: bojilova $'
14
 *     '$Date: 2001-02-23 14:14:30 -0800 (Fri, 23 Feb 2001) $'
15
 * '$Revision: 706 $'
16
 *
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
 */
31

    
32
package edu.ucsb.nceas.metacat;
33

    
34
import java.io.*;
35
import java.util.Vector;
36
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
import java.io.File;
43
import java.io.FileWriter;
44
import java.io.BufferedWriter;
45

    
46
/** 
47
 * A Class that searches a relational DB for elements and 
48
 * attributes that have free text matches a query string,
49
 * or structured query matches to a path specified node in the 
50
 * XML hierarchy.  It returns a result set consisting of the 
51
 * document ID for each document that satisfies the query
52
 */
53
public class DBQuery {
54

    
55
  static final int ALL = 1;
56
  static final int WRITE = 2;
57
  static final int READ = 4;
58

    
59
  private Connection  conn = null;
60
  private String  parserName = null;
61
  private MetaCatUtil util = new MetaCatUtil();
62
  /**
63
   * the main routine used to test the DBQuery utility.
64
   * <p>
65
   * Usage: java DBQuery <xmlfile>
66
   *
67
   * @param xmlfile the filename of the xml file containing the query
68
   */
69
  static public void main(String[] args) {
70
     
71
     if (args.length < 1)
72
     {
73
        System.err.println("Wrong number of arguments!!!");
74
        System.err.println("USAGE: java DBQuery [-t] [-index] <xmlfile>");
75
        return;
76
     } else {
77
        try {
78

    
79
          int i = 0;
80
          boolean showRuntime = false;
81
          boolean useXMLIndex = false;
82
          if ( args[i].equals( "-t" ) ) {
83
            showRuntime = true;
84
            i++;
85
          }
86
          if ( args[i].equals( "-index" ) ) {
87
            useXMLIndex = true;
88
            i++;
89
          } 
90
          String xmlfile  = args[i];
91

    
92
          // Time the request if asked for
93
          double startTime = System.currentTimeMillis();
94

    
95
          // Open a connection to the database
96
          MetaCatUtil   util = new MetaCatUtil();
97
          Connection dbconn = util.openDBConnection();
98

    
99
          double connTime = System.currentTimeMillis();
100

    
101
          // Execute the query
102
          DBQuery queryobj = new DBQuery(dbconn, util.getOption("saxparser"));
103
          FileReader xml = new FileReader(new File(xmlfile));
104
          Hashtable nodelist = null;
105
          nodelist = queryobj.findDocuments(xml, null, null, useXMLIndex);
106

    
107
          // Print the reulting document listing
108
          StringBuffer result = new StringBuffer();
109
          String document = null;
110
          String docid = null;
111
          result.append("<?xml version=\"1.0\"?>\n");
112
          result.append("<resultset>\n"); 
113
  // following line removed by Dan Higgins to avoid insertion of query XML inside returned XML doc
114
  //        result.append("  <query>" + xmlfile + "</query>\n");
115
          Enumeration doclist = nodelist.keys(); 
116
          while (doclist.hasMoreElements()) {
117
            docid = (String)doclist.nextElement();
118
            document = (String)nodelist.get(docid);
119
            result.append("  <document>\n    " + document + 
120
                          "\n  </document>\n");
121
          }
122
          result.append("</resultset>\n");
123

    
124
          // Time the request if asked for
125
          double stopTime = System.currentTimeMillis();
126
          double dbOpenTime = (connTime - startTime)/1000;
127
          double readTime = (stopTime - connTime)/1000;
128
          double executionTime = (stopTime - startTime)/1000;
129
          if (showRuntime) {
130
            System.out.println("\n\nTotal Execution time was: " + 
131
                               executionTime + " seconds.");
132
            System.out.println("Time to open DB connection was: " + dbOpenTime + 
133
                               " seconds.");
134
            System.out.println("Time to read was: " + readTime +
135
                               " seconds.");
136
          }
137
          //System.out.println(result);
138
          //write into a file "result.txt"
139
          File f = new File("./result.txt");
140
          FileWriter fw = new FileWriter(f);
141
          BufferedWriter out = new BufferedWriter(fw);
142
          out.write(result.toString());          
143
    	    out.flush();
144
	        out.close();
145
	        fw.close();
146

    
147
        } catch (Exception e) {
148
          System.err.println("Error in DBQuery.main");
149
          System.err.println(e.getMessage());
150
          e.printStackTrace(System.err);
151
        }
152
     }
153
  }
154
  
155
  /**
156
   * construct an instance of the DBQuery class 
157
   *
158
   * <p>Generally, one would call the findDocuments() routine after creating 
159
   * an instance to specify the search query</p>
160
   *
161
   * @param conn the JDBC connection that we use for the query
162
   * @param parserName the fully qualified name of a Java class implementing
163
   *                   the org.xml.sax.XMLReader interface
164
   */
165
  public DBQuery( Connection conn, String parserName ) 
166
                  throws IOException, 
167
                         SQLException, 
168
                         ClassNotFoundException {
169
    this.conn = conn;
170
    this.parserName = parserName;
171
  }
172
  
173
  public Hashtable findDocuments(Reader xmlquery, String user, String group,
174
                                 boolean useXMLIndex)
175
  {
176
    return findDocuments(xmlquery, user, group, null, useXMLIndex);
177
  }
178
  
179
  public Hashtable findDocuments(Reader xmlquery, String user, String group,
180
                                 String[] returndoc)
181
  {
182
    return findDocuments(xmlquery, user, group, returndoc, true);
183
  }
184

    
185
  /** 
186
   * routine to search the elements and attributes looking to match query
187
   *
188
   * @param xmlquery the xml serialization of the query (@see pathquery.dtd)
189
   * @param user the username of the user
190
   * @param group the group of the user
191
   * @param returndoc an array of document types to backtrack against.
192
   */
193
  public Hashtable findDocuments(Reader xmlquery, String user, String group,
194
                                 String[] returndoc, boolean useXMLIndex)
195
  {
196
    //System.out.println("in finddocuments");
197
      Hashtable   docListResult = new Hashtable();
198
      PreparedStatement pstmt = null;
199
      String docid = null;
200
      String docname = null;
201
      String doctype = null;
202
// DOCTITLE attr cleared from the db
203
//      String doctitle = null;
204
      String createDate = null;
205
      String updateDate = null;
206
      String fieldname = null;
207
      String fielddata = null;
208
      String relation = null;
209
      Connection dbconn = null;
210
      int rev = 0;
211
      StringBuffer document = null; 
212
      Vector returndocVec = new Vector();
213
      
214
      if(returndoc != null)
215
      {//add the returndoc elements to a vector for easier manipulation
216
        for(int i=0; i<returndoc.length; i++)
217
        {
218
          returndocVec.add(new String((String)returndoc[i]));
219
        }
220
      }
221
      
222
      try {
223
        dbconn = util.openDBConnection();
224
        // Get the XML query and covert it into a SQL statment
225
        QuerySpecification qspec = new QuerySpecification(xmlquery, 
226
                                   parserName, 
227
                                   util.getOption("accNumSeparator"));
228
       // System.out.println(qspec.printSQL());
229
        pstmt = dbconn.prepareStatement( qspec.printSQL(useXMLIndex) );
230

    
231
        // Execute the SQL query using the JDBC connection
232
        pstmt.execute();
233
        ResultSet rs = pstmt.getResultSet();
234
        boolean tableHasRows = rs.next();
235
        while (tableHasRows) 
236
        {
237
          docid = rs.getString(1);
238
          if ( !hasPermission(dbconn, user, group, docid) ) {
239
            // Advance to the next record in the cursor
240
            tableHasRows = rs.next();
241
            continue;
242
          }
243
          docname = rs.getString(2);
244
          doctype = rs.getString(3);
245
// DOCTITLE attr cleared from the db
246
//          doctitle = rs.getString(4);
247
          createDate = rs.getString(4);
248
          updateDate = rs.getString(5);
249
          rev = rs.getInt(6);
250
          
251
          //System.out.println("vec.size = " + returndocVec.size());
252
          if(returndocVec.size() != 0 && !returndocVec.contains(doctype))
253
          { //there are returndocs to match (backtracking can now be performed). 
254
            //System.out.println("olddoctype: " + doctype);
255
            StringBuffer btBuf = new StringBuffer();
256
            btBuf.append("select object from xml_relation where ");
257
            btBuf.append("objdoctype in (");
258
            //build the doctype list for the backtracking sql statement
259
            for(int i=0; i<returndocVec.size(); i++)
260
            {
261
              btBuf.append("'").append((String)returndocVec.get(i)).append("'");
262
              if(i != (returndocVec.size() - 1))
263
              {
264
                btBuf.append(", ");
265
              } 
266
            }
267
            btBuf.append(") ");
268
            btBuf.append("and subject like '");
269
            //btBuf.append("metacat://").append(util.getOption("server"));
270
            //btBuf.append("?docid=").append(docid).append("'");
271
            btBuf.append("%docid=").append(docid).append("'");
272
            //System.out.println("sql: " + btBuf.toString());
273
            
274
            PreparedStatement npstmt = dbconn.prepareStatement(btBuf.toString());
275
            npstmt.execute();
276
            ResultSet btrs = npstmt.getResultSet();
277
            boolean hasBtRows = btrs.next();
278
            if(hasBtRows)
279
            { //there was a backtrackable document found
280
              DocumentImpl xmldoc = null;
281
              //System.out.println("document found is: " + btrs.getString(1));
282
              MetacatURL objURL = new MetacatURL(btrs.getString(1));
283
              try
284
              {
285
                xmldoc = new DocumentImpl(dbconn, objURL.getParam(0)[1]);
286
              }
287
              catch(Exception e)
288
              {
289
                System.out.println("Error getting document in " + 
290
                                   "DBQuery.findDocuments: " + e.getMessage());
291
              }
292
              
293
              docid   = xmldoc.getDocID();
294
              docname = xmldoc.getDocname();
295
              doctype = xmldoc.getDoctype();
296
// DOCTITLE attr cleared from the db
297
//              doctitle = xmldoc.getDocTitle();
298
              createDate = xmldoc.getCreateDate();
299
              updateDate = xmldoc.getUpdateDate();
300
              //System.out.println("docname: " + docname + " doctype: " + doctype + 
301
              //                   " doctitle: " + doctitle + " createdate: " +
302
              //                   createDate + " updatedate: " + updateDate);
303
            }
304
            npstmt.close();
305
            btrs.close();
306
          }
307
          
308
          document = new StringBuffer();
309
          //System.out.println("packagdoctype: " + util.getOption("packagedoctype"));
310
          //if(!doctype.equals(util.getOption("packagedoctype")))
311
          {
312
            String completeDocid = docid + util.getOption("accNumSeparator");
313
            completeDocid += rev;
314
            document.append("<docid>").append(completeDocid).append("</docid>");
315
            if (docname != null) {
316
              document.append("<docname>" + docname + "</docname>");
317
            }
318
            if (doctype != null) {
319
              document.append("<doctype>" + doctype + "</doctype>");
320
            }
321
// DOCTITLE attr cleared from the db
322
//            if (doctitle != null) {
323
//              document.append("<doctitle>" + doctitle + "</doctitle>");
324
//            }
325
            if(createDate != null) {
326
              document.append("<createdate>" + createDate + "</createdate>");
327
            }
328
            if(updateDate != null) {
329
              document.append("<updatedate>" + updateDate + "</updatedate>");
330
            }
331
            // Store the document id and the root node id
332
            docListResult.put(docid,(String)document.toString());
333
          }
334

    
335
          // Advance to the next record in the cursor
336
          tableHasRows = rs.next();
337
        }
338
        rs.close();
339
        //pstmt.close();
340
        
341
        if(qspec.containsExtendedSQL())
342
        {
343
          Vector extendedFields = new Vector(qspec.getReturnFieldList());
344
          Vector results = new Vector();
345
          Enumeration keylist = docListResult.keys();
346
          StringBuffer doclist = new StringBuffer();
347
          while(keylist.hasMoreElements())
348
          {
349
            doclist.append("'");
350
            doclist.append((String)keylist.nextElement());
351
            doclist.append("',");
352
          }
353
          doclist.deleteCharAt(doclist.length()-1); //remove the last comma
354
          pstmt.close();
355
          pstmt = dbconn.prepareStatement(qspec.printExtendedSQL(
356
                                        doclist.toString()));
357
          pstmt.execute();
358
          rs = pstmt.getResultSet();
359
          tableHasRows = rs.next();
360
          while(tableHasRows) 
361
          {
362
            docid = rs.getString(1);
363
            if ( !hasPermission(dbconn, user, group, docid) ) {
364
              // Advance to the next record in the cursor
365
              tableHasRows = rs.next();
366
              continue;
367
            }
368
            fieldname = rs.getString(2);
369
            fielddata = rs.getString(3);
370
            
371
            document = new StringBuffer();
372

    
373
            document.append("<param name=\"");
374
            document.append(fieldname);
375
            document.append("\">");
376
            document.append(fielddata);
377
            document.append("</param>");
378

    
379
            tableHasRows = rs.next();
380
            if(docListResult.containsKey(docid))
381
            {
382
              String removedelement = (String)docListResult.remove(docid);
383
              docListResult.put(docid, removedelement + document.toString());
384
            }
385
            else
386
            {
387
              docListResult.put(docid, document.toString()); 
388
            }
389
          }
390
          rs.close();
391
        }
392

    
393
        //this loop adds the relation data to the resultdoc
394
        //this code might be able to be added to the backtracking code above
395
        Enumeration docidkeys = docListResult.keys();
396
        while(docidkeys.hasMoreElements())
397
        {
398
          //String connstring = "metacat://"+util.getOption("server")+"?docid=";
399
          String connstring = "%docid=";
400
          String docidkey = (String)docidkeys.nextElement();
401
          //System.out.println("relationsql: " + qspec.printRelationSQL(
402
          //                                           connstring + docidkey));
403
          pstmt.close();
404
          pstmt = dbconn.prepareStatement(
405
                  qspec.printRelationSQL(connstring + docidkey));
406
          pstmt.execute();
407
          rs = pstmt.getResultSet();
408
          tableHasRows = rs.next();
409
          while(tableHasRows)
410
          {
411
            String sub = rs.getString(1);
412
            String rel = rs.getString(2);
413
            String obj = rs.getString(3);
414
            String subDT = rs.getString(4);
415
            String objDT = rs.getString(5);
416
            
417
            MetacatURL murl = new MetacatURL(sub);
418
            if(murl.getProtocol().equals("metacat"))
419
            {//we only want to process metacat urls here.
420
              String[] tempparam = murl.getParam(0);
421
              if(tempparam[0].equals("docid") && tempparam[1].equals(docidkey))
422
              {
423
                document = new StringBuffer();
424
                document.append("<relation>");
425
                document.append("<relationtype>").append(rel);
426
                document.append("</relationtype>");
427
                document.append("<relationdoc>").append(obj);
428
                document.append("</relationdoc>");
429
                document.append("<relationdoctype>").append(objDT);
430
                document.append("</relationdoctype>");
431
                document.append("</relation>");
432
                
433
                String removedelement = (String)docListResult.remove(docidkey);
434
                docListResult.put(docidkey, removedelement + document.toString());
435
                
436
              }
437
            }
438
            tableHasRows = rs.next();
439
          }
440
          rs.close();
441
          pstmt.close();
442
        }
443
        
444
      } catch (SQLException e) {
445
        System.err.println("SQL Error in DBQuery.findDocuments: " + 
446
                           e.getMessage());
447
      } catch (IOException ioe) {
448
        System.err.println("IO error in DBQuery.findDocuments:");
449
        System.err.println(ioe.getMessage());
450
      } catch (Exception ee) {
451
        System.out.println("Exception in DBQuery.findDocuments: " + 
452
                           ee.getMessage());
453
      }
454
      finally {
455
        try
456
        {
457
          dbconn.close();
458
        }
459
        catch(SQLException sqle)
460
        {
461
          System.out.println("error closing conn in DBQuery.findDocuments");
462
        }
463
      }
464
    //System.out.println("docListResult: ");
465
    //System.out.println(docListResult.toString());
466
    return docListResult;
467
  }
468
  
469
  /**
470
   * returns a string array of the contents of a particular node. 
471
   * If the node appears more than once, the contents are returned 
472
   * in the order in which they appearred in the document.
473
   * @param nodename the name or path of the particular node.
474
   * @param docid the docid of the document you want the node from.
475
   * @param conn a database connection-this allows this method to be static
476
   */
477
  public static Object[] getNodeContent(String nodename, String docid, 
478
                                        Connection conn)
479
  {
480
    StringBuffer query = new StringBuffer();
481
    Vector result = new Vector();
482
    PreparedStatement pstmt = null;
483
    query.append("select nodedata from xml_nodes where parentnodeid in ");
484
    query.append("(select nodeid from xml_index where path like '");
485
    query.append(nodename);
486
    query.append("' and docid like '").append(docid).append("')");
487
    try
488
    {
489
      pstmt = conn.prepareStatement(query.toString());
490

    
491
      // Execute the SQL query using the JDBC connection
492
      pstmt.execute();
493
      ResultSet rs = pstmt.getResultSet();
494
      boolean tableHasRows = rs.next();
495
      while (tableHasRows) 
496
      {
497
        result.add(rs.getString(1));
498
        System.out.println(rs.getString(1));
499
        tableHasRows = rs.next();
500
      }
501
    } 
502
    catch (SQLException e) 
503
    {
504
      System.err.println("Error in DBQuery.getNodeContent: " + e.getMessage());
505
    } finally {
506
      try
507
      {
508
        pstmt.close();
509
      }
510
      catch(SQLException sqle) {}
511
    }
512
    return result.toArray();
513
  }
514
  
515
  /**
516
   * format a structured query as an XML document that conforms
517
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
518
   * structured query engine
519
   *
520
   * @param params The list of parameters that  should be included in the query
521
   */
522
  public static String createSQuery(Hashtable params)
523
  { 
524
    StringBuffer query = new StringBuffer();
525
    Enumeration elements;
526
    Enumeration keys;
527
    String doctype = null;
528
    String casesensitive = null;
529
    String searchmode = null;
530
    Object nextkey;
531
    Object nextelement;
532
    //add the xml headers
533
    query.append("<?xml version=\"1.0\"?>\n");
534
    query.append("<pathquery version=\"1.0\"><meta_file_id>");
535
    
536
    if(params.containsKey("meta_file_id"))
537
    {
538
      query.append( ((String[])params.get("meta_file_id"))[0]);
539
      query.append("</meta_file_id>");
540
    }
541
    else
542
    {
543
      query.append("unspecified</meta_file_id>");
544
    }
545
    
546
// DOCTITLE attr cleared from the db
547
//    query.append("<querytitle>");
548
//    if(params.containsKey("querytitle"))
549
//    {
550
//      query.append(((String[])params.get("querytitle"))[0]);
551
//      query.append("</querytitle>");
552
//    }
553
//    else
554
//    {
555
//      query.append("unspecified</querytitle>");
556
//    }
557
    
558
    if(params.containsKey("doctype"))
559
    {
560
      doctype = ((String[])params.get("doctype"))[0]; 
561
    }
562
    else
563
    {
564
      doctype = "ANY";  
565
    }
566
    
567
    if(params.containsKey("returnfield"))
568
    {
569
      String[] returnfield = ((String[])params.get("returnfield"));
570
      for(int i=0; i<returnfield.length; i++)
571
      {
572
        query.append("<returnfield>").append(returnfield[i]);
573
        query.append("</returnfield>");
574
      }
575
    }
576
    
577
    if(params.containsKey("owner"))
578
    {
579
      String[] owner = ((String[])params.get("owner"));
580
      for(int i=0; i<owner.length; i++)
581
      {
582
        query.append("<owner>").append(owner[i]);
583
        query.append("</owner>");
584
      }
585
    }
586
    
587
    if(params.containsKey("site"))
588
    {
589
      String[] site = ((String[])params.get("site"));
590
      for(int i=0; i<site.length; i++)
591
      {
592
        query.append("<site>").append(site[i]);
593
        query.append("</site>");
594
      }
595
    }
596
    
597
    //if you don't limit the query by doctype, then it just creates
598
    //an empty returndoctype tag.
599
    if (!doctype.equals("any") && 
600
        !doctype.equals("ANY") &&
601
        !doctype.equals("") ) 
602
    {
603
       query.append("<returndoctype>");
604
       query.append(doctype).append("</returndoctype>");
605
    }
606
    else
607
    { 
608
      query.append("<returndoctype></returndoctype>");
609
    }
610
    
611
    //allows the dynamic switching of boolean operators
612
    if(params.containsKey("operator"))
613
    {
614
      query.append("<querygroup operator=\"" + 
615
                ((String[])params.get("operator"))[0] + "\">");
616
    }
617
    else
618
    { //the default operator is UNION
619
      query.append("<querygroup operator=\"UNION\">"); 
620
    }
621
        
622
    if(params.containsKey("casesensitive"))
623
    {
624
      casesensitive = ((String[])params.get("casesensitive"))[0]; 
625
    }
626
    else
627
    {
628
      casesensitive = "false"; 
629
    }
630
    
631
    if(params.containsKey("searchmode"))
632
    {
633
      searchmode = ((String[])params.get("searchmode"))[0]; 
634
    }
635
    else
636
    {
637
      searchmode = "contains"; 
638
    }
639
        
640
    //anyfield is a special case because it does a 
641
    //free text search.  It does not have a <pathexpr>
642
    //tag.  This allows for a free text search within the structured
643
    //query.  This is useful if the INTERSECT operator is used.
644
    if(params.containsKey("anyfield"))
645
    {
646
       String[] anyfield = ((String[])params.get("anyfield"));
647
       //allow for more than one value for anyfield
648
       for(int i=0; i<anyfield.length; i++)
649
       {
650
         if(!anyfield[i].equals(""))
651
         {
652
           query.append("<queryterm casesensitive=\"" + casesensitive + 
653
                        "\" " + "searchmode=\"" + searchmode + "\"><value>" +
654
                        anyfield[i] +
655
                        "</value></queryterm>"); 
656
         }
657
       }
658
    }
659
        
660
    //this while loop finds the rest of the parameters
661
    //and attempts to query for the field specified
662
    //by the parameter.
663
    elements = params.elements();
664
    keys = params.keys();
665
    while(keys.hasMoreElements() && elements.hasMoreElements())
666
    {
667
      nextkey = keys.nextElement();
668
      nextelement = elements.nextElement();
669

    
670
      //make sure we aren't querying for any of these
671
      //parameters since the are already in the query
672
      //in one form or another.
673
      if(!nextkey.toString().equals("doctype") && 
674
         !nextkey.toString().equals("action")  &&
675
         !nextkey.toString().equals("qformat") && 
676
         !nextkey.toString().equals("anyfield") &&
677
         !nextkey.toString().equals("returnfield") &&
678
         !nextkey.toString().equals("owner") &&
679
         !nextkey.toString().equals("site") &&
680
         !nextkey.toString().equals("operator") )
681
      {
682
        //allow for more than value per field name
683
        for(int i=0; i<((String[])nextelement).length; i++)
684
        {
685
          if(!((String[])nextelement)[i].equals(""))
686
          {
687
            query.append("<queryterm casesensitive=\"" + casesensitive +"\" " + 
688
                         "searchmode=\"" + searchmode + "\">" +
689
                         "<value>" +
690
                         //add the query value
691
                         ((String[])nextelement)[i] +
692
                         "</value><pathexpr>" +
693
                         //add the path to query by 
694
                         nextkey.toString() + 
695
                         "</pathexpr></queryterm>");
696
          }
697
        }
698
      }
699
    }
700
    query.append("</querygroup></pathquery>");
701
    //append on the end of the xml and return the result as a string
702
    return query.toString();
703
  }
704
  
705
  /**
706
   * format a simple free-text value query as an XML document that conforms
707
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
708
   * structured query engine
709
   *
710
   * @param value the text string to search for in the xml catalog
711
   * @param doctype the type of documents to include in the result set -- use
712
   *        "any" or "ANY" for unfiltered result sets
713
   */
714
   public static String createQuery(String value, String doctype) {
715
     StringBuffer xmlquery = new StringBuffer();
716
     xmlquery.append("<?xml version=\"1.0\"?>\n");
717
     xmlquery.append("<pathquery version=\"1.0\">");
718
     xmlquery.append("<meta_file_id>Unspecified</meta_file_id>");
719
// DOCTITLE attr cleared from the db
720
//     xmlquery.append("<querytitle>Unspecified</querytitle>");
721

    
722
     if (!doctype.equals("any") && !doctype.equals("ANY")) {
723
       xmlquery.append("<returndoctype>");
724
       xmlquery.append(doctype).append("</returndoctype>");
725
     }
726

    
727
     xmlquery.append("<querygroup operator=\"UNION\">");
728
     //chad added - 8/14
729
     //the if statement allows a query to gracefully handle a null 
730
     //query.  Without this if a nullpointerException is thrown.
731
     if(!value.equals(""))
732
     {
733
       xmlquery.append("<queryterm casesensitive=\"false\" ");
734
       xmlquery.append("searchmode=\"contains\">");
735
       xmlquery.append("<value>").append(value).append("</value>");
736
       xmlquery.append("</queryterm>");
737
     }
738
     xmlquery.append("</querygroup>");
739
     xmlquery.append("</pathquery>");
740

    
741
     
742
     return (xmlquery.toString());
743
   }
744

    
745
  /**
746
   * format a simple free-text value query as an XML document that conforms
747
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
748
   * structured query engine
749
   *
750
   * @param value the text string to search for in the xml catalog
751
   */
752
   public static String createQuery(String value) {
753
     return createQuery(value, "any");
754
   }
755
   
756
  /** 
757
    * Check for "READ" permission on @docid for @user and/or @group 
758
    * from DB connection 
759
    */
760
  private boolean hasPermission ( Connection conn, String user,
761
                                  String group, String docid ) 
762
                  throws SQLException
763
  {
764
    // b' of the command line invocation
765
    if ( (user == null) && (group == null) ) {
766
      return true;
767
    }
768
    
769
    // Check for READ permission on @docid for @user and/or @group
770
    AccessControlList aclobj = new AccessControlList(conn);
771
    boolean hasPermission = aclobj.hasPermission("READ",user,docid);
772
    if ( !hasPermission && group != null ) {
773
      hasPermission = aclobj.hasPermission("READ",group,docid);
774
    }
775
    
776
    return hasPermission;
777
  }
778
   
779
}
(14-14/43)