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-01-18 12:46:21 -0800 (Thu, 18 Jan 2001) $'
15
 * '$Revision: 673 $'
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

    
43
/** 
44
 * 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
 */
50
public class DBQuery {
51

    
52
  static final int ALL = 1;
53
  static final int WRITE = 2;
54
  static final int READ = 4;
55

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

    
78
          // Open a connection to the database
79
          MetaCatUtil   util = new MetaCatUtil();
80
          Connection dbconn = util.openDBConnection();
81

    
82
          // Execute the query
83
          DBQuery queryobj = new DBQuery(dbconn, util.getOption("saxparser"));
84
          FileReader xml = new FileReader(new File(xmlfile));
85
          Hashtable nodelist = null;
86
          nodelist = queryobj.findDocuments(xml, null, null);
87

    
88
          // Print the reulting document listing
89
          StringBuffer result = new StringBuffer();
90
          String document = null;
91
          String docid = null;
92
          result.append("<?xml version=\"1.0\"?>\n");
93
          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
          Enumeration doclist = nodelist.keys(); 
97
          while (doclist.hasMoreElements()) {
98
            docid = (String)doclist.nextElement();
99
            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
          System.err.println("EXCEPTION HANDLING REQUIRED");
109
          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
   * @param parserName the fully qualified name of a Java class implementing
123
   *                   the org.xml.sax.XMLReader interface
124
   */
125
  public DBQuery( Connection conn, String parserName ) 
126
                  throws IOException, 
127
                         SQLException, 
128
                         ClassNotFoundException {
129
    this.conn = conn;
130
    this.parserName = parserName;
131
  }
132
  
133
  public Hashtable findDocuments(Reader xmlquery, String user, String group)
134
  {
135
    return findDocuments(xmlquery, user, group, null);
136
  }
137
  
138
  /** 
139
   * routine to search the elements and attributes looking to match query
140
   *
141
   * @param xmlquery the xml serialization of the query (@see pathquery.dtd)
142
   * @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
   */
146
  public Hashtable findDocuments(Reader xmlquery, String user, String group,
147
                                 String[] returndoc)
148
  {
149
    //System.out.println("in finddocuments");
150
      Hashtable   docListResult = new Hashtable();
151
      PreparedStatement pstmt = null;
152
      String docid = null;
153
      String docname = null;
154
      String doctype = null;
155
      String doctitle = null;
156
      String createDate = null;
157
      String updateDate = null;
158
      String fieldname = null;
159
      String fielddata = null;
160
      String relation = null;
161
      Connection dbconn = null;
162
      int rev = 0;
163
      StringBuffer document = null; 
164
      Vector returndocVec = new Vector();
165
      
166
      if(returndoc != null)
167
      {//add the returndoc elements to a vector for easier manipulation
168
        for(int i=0; i<returndoc.length; i++)
169
        {
170
          returndocVec.add(new String((String)returndoc[i]));
171
        }
172
      }
173
      
174
      try {
175
        dbconn = util.openDBConnection();
176
        // Get the XML query and covert it into a SQL statment
177
        QuerySpecification qspec = new QuerySpecification(xmlquery, 
178
                                   parserName, 
179
                                   util.getOption("accNumSeparator"));
180
       // System.out.println(qspec.printSQL());
181
        pstmt = dbconn.prepareStatement( qspec.printSQL() );
182

    
183
        // Execute the SQL query using the JDBC connection
184
        pstmt.execute();
185
        ResultSet rs = pstmt.getResultSet();
186
        boolean tableHasRows = rs.next();
187
        while (tableHasRows) 
188
        {
189
          docid = rs.getString(1);
190
          if ( !hasPermission(dbconn, user, group, docid) ) {
191
            // Advance to the next record in the cursor
192
            tableHasRows = rs.next();
193
            continue;
194
          }
195
          docname = rs.getString(2);
196
          doctype = rs.getString(3);
197
          doctitle = rs.getString(4);
198
          createDate = rs.getString(5);
199
          updateDate = rs.getString(6);
200
          rev = rs.getInt(7);
201
          
202
          //System.out.println("vec.size = " + returndocVec.size());
203
          if(returndocVec.size() != 0 && !returndocVec.contains(doctype))
204
          { //there are returndocs to match (backtracking can now be performed). 
205
            //System.out.println("olddoctype: " + doctype);
206
            StringBuffer btBuf = new StringBuffer();
207
            btBuf.append("select object from xml_relation where ");
208
            btBuf.append("objdoctype in (");
209
            //build the doctype list for the backtracking sql statement
210
            for(int i=0; i<returndocVec.size(); i++)
211
            {
212
              btBuf.append("'").append((String)returndocVec.get(i)).append("'");
213
              if(i != (returndocVec.size() - 1))
214
              {
215
                btBuf.append(", ");
216
              } 
217
            }
218
            btBuf.append(") ");
219
            btBuf.append("and subject like '");
220
            //btBuf.append("metacat://").append(util.getOption("server"));
221
            //btBuf.append("?docid=").append(docid).append("'");
222
            btBuf.append("%docid=").append(docid).append("'");
223
            //System.out.println("sql: " + btBuf.toString());
224
            
225
            PreparedStatement npstmt = dbconn.prepareStatement(btBuf.toString());
226
            npstmt.execute();
227
            ResultSet btrs = npstmt.getResultSet();
228
            boolean hasBtRows = btrs.next();
229
            if(hasBtRows)
230
            { //there was a backtrackable document found
231
              DocumentImpl xmldoc = null;
232
              //System.out.println("document found is: " + btrs.getString(1));
233
              MetacatURL objURL = new MetacatURL(btrs.getString(1));
234
              try
235
              {
236
                xmldoc = new DocumentImpl(dbconn, objURL.getParam(0)[1]);
237
              }
238
              catch(Exception e)
239
              {
240
                System.out.println("Error getting document: " + e.getMessage());
241
              }
242
              
243
              docid   = xmldoc.getDocID();
244
              docname = xmldoc.getDocname();
245
              doctype = xmldoc.getDoctype();
246
              doctitle = xmldoc.getDocTitle();
247
              createDate = xmldoc.getCreateDate();
248
              updateDate = xmldoc.getUpdateDate();
249
              //System.out.println("docname: " + docname + " doctype: " + doctype + 
250
              //                   " doctitle: " + doctitle + " createdate: " +
251
              //                   createDate + " updatedate: " + updateDate);
252
            }
253
            npstmt.close();
254
            btrs.close();
255
          }
256
          
257
          document = new StringBuffer();
258
          //System.out.println("packagdoctype: " + util.getOption("packagedoctype"));
259
          //if(!doctype.equals(util.getOption("packagedoctype")))
260
          {
261
            String completeDocid = docid + util.getOption("accNumSeparator");
262
            completeDocid += rev;
263
            document.append("<docid>").append(completeDocid).append("</docid>");
264
            if (docname != null) {
265
              document.append("<docname>" + docname + "</docname>");
266
            }
267
            if (doctype != null) {
268
              document.append("<doctype>" + doctype + "</doctype>");
269
            }
270
            if (doctitle != null) {
271
              document.append("<doctitle>" + doctitle + "</doctitle>");
272
            }
273
            if(createDate != null) {
274
              document.append("<createdate>" + createDate + "</createdate>");
275
            }
276
            if(updateDate != null) {
277
              document.append("<updatedate>" + updateDate + "</updatedate>");
278
            }
279
            // Store the document id and the root node id
280
            docListResult.put(docid,(String)document.toString());
281
          }
282

    
283
          // Advance to the next record in the cursor
284
          tableHasRows = rs.next();
285
          System.out.println("next1");
286
        }
287
        System.out.println("rs1.close");
288
        rs.close();
289
        //pstmt.close();
290
        
291
        if(qspec.containsExtendedSQL())
292
        {
293
          Vector extendedFields = new Vector(qspec.getReturnFieldList());
294
          Vector results = new Vector();
295
          Enumeration keylist = docListResult.keys();
296
          StringBuffer doclist = new StringBuffer();
297
          while(keylist.hasMoreElements())
298
          {
299
            doclist.append("'");
300
            doclist.append((String)keylist.nextElement());
301
            doclist.append("',");
302
          }
303
          doclist.deleteCharAt(doclist.length()-1); //remove the last comma
304
          pstmt.close();
305
          pstmt = dbconn.prepareStatement(qspec.printExtendedSQL(
306
                                        doclist.toString()));
307
          pstmt.execute();
308
          rs = pstmt.getResultSet();
309
          tableHasRows = rs.next();
310
          while(tableHasRows) 
311
          {
312
            docid = rs.getString(1);
313
            if ( !hasPermission(dbconn, user, group, docid) ) {
314
              // Advance to the next record in the cursor
315
              tableHasRows = rs.next();
316
              continue;
317
            }
318
            fieldname = rs.getString(2);
319
            fielddata = rs.getString(3);
320
            
321
            document = new StringBuffer();
322

    
323
            document.append("<param name=\"");
324
            document.append(fieldname);
325
            document.append("\">");
326
            document.append(fielddata);
327
            document.append("</param>");
328

    
329
            tableHasRows = rs.next();
330
            System.out.println("next2");
331
            if(docListResult.containsKey(docid))
332
            {
333
              String removedelement = (String)docListResult.remove(docid);
334
              docListResult.put(docid, removedelement + document.toString());
335
            }
336
            else
337
            {
338
              docListResult.put(docid, document.toString()); 
339
            }
340
          }
341
          System.out.println("rs2.close");
342
          rs.close();
343
        }
344

    
345
        //this loop adds the relation data to the resultdoc
346
        //this code might be able to be added to the backtracking code above
347
        Enumeration docidkeys = docListResult.keys();
348
        while(docidkeys.hasMoreElements())
349
        {
350
          //String connstring = "metacat://"+util.getOption("server")+"?docid=";
351
          String connstring = "%docid=";
352
          String docidkey = (String)docidkeys.nextElement();
353
          //System.out.println("relationsql: " + qspec.printRelationSQL(
354
          //                                           connstring + docidkey));
355
          pstmt.close();
356
          pstmt = dbconn.prepareStatement(
357
                  qspec.printRelationSQL(connstring + docidkey));
358
          pstmt.execute();
359
          rs = pstmt.getResultSet();
360
          tableHasRows = rs.next();
361
          while(tableHasRows)
362
          {
363
            String sub = rs.getString(1);
364
            String rel = rs.getString(2);
365
            String obj = rs.getString(3);
366
            String subDT = rs.getString(4);
367
            String objDT = rs.getString(5);
368
            
369
            MetacatURL murl = new MetacatURL(sub);
370
            if(murl.getProtocol().equals("metacat"))
371
            {//we only want to process metacat urls here.
372
              String[] tempparam = murl.getParam(0);
373
              if(tempparam[0].equals("docid") && tempparam[1].equals(docidkey))
374
              {
375
                document = new StringBuffer();
376
                document.append("<relation>");
377
                document.append("<relationtype>").append(rel);
378
                document.append("</relationtype>");
379
                document.append("<relationdoc>").append(obj);
380
                document.append("</relationdoc>");
381
                document.append("<relationdoctype>").append(objDT);
382
                document.append("</relationdoctype>");
383
                document.append("</relation>");
384
                
385
                String removedelement = (String)docListResult.remove(docidkey);
386
                docListResult.put(docidkey, removedelement + document.toString());
387
                
388
              }
389
            }
390
            tableHasRows = rs.next();
391
            System.out.println("next3");
392
          }
393
          rs.close();
394
          System.out.println("rs3.close");
395
          System.out.println("pstmt.close()");
396
          pstmt.close();
397
        }
398
        
399
      } catch (SQLException e) {
400
        System.err.println("SQL Error in DBQuery.findDocuments: " + 
401
                           e.getMessage());
402
      } catch (IOException ioe) {
403
        System.err.println("Error printing qspec:");
404
        System.err.println(ioe.getMessage());
405
      } catch (Exception ee) {
406
        System.out.println("error in DBQuery.findDocuments: " + 
407
                           ee.getMessage());
408
      }
409
      finally {
410
        try
411
        {
412
          dbconn.close();
413
        }
414
        catch(SQLException sqle)
415
        {
416
          System.out.println("error closing conn in DBQuery.findDocuments");
417
        }
418
      }
419
    //System.out.println("docListResult: ");
420
    //System.out.println(docListResult.toString());
421
    return docListResult;
422
  }
423
  
424
  /**
425
   * returns a string array of the contents of a particular node. 
426
   * If the node appears more than once, the contents are returned 
427
   * in the order in which they appearred in the document.
428
   * @param nodename the name or path of the particular node.
429
   * @param docid the docid of the document you want the node from.
430
   * @param conn a database connection-this allows this method to be static
431
   */
432
  public static Object[] getNodeContent(String nodename, String docid, 
433
                                        Connection conn)
434
  {
435
    StringBuffer query = new StringBuffer();
436
    Vector result = new Vector();
437
    PreparedStatement pstmt = null;
438
    query.append("select nodedata from xml_nodes where parentnodeid in ");
439
    query.append("(select nodeid from xml_index where path like '");
440
    query.append(nodename);
441
    query.append("' and docid like '").append(docid).append("')");
442
    try
443
    {
444
      pstmt = conn.prepareStatement(query.toString());
445

    
446
      // Execute the SQL query using the JDBC connection
447
      pstmt.execute();
448
      ResultSet rs = pstmt.getResultSet();
449
      boolean tableHasRows = rs.next();
450
      while (tableHasRows) 
451
      {
452
        result.add(rs.getString(1));
453
        System.out.println(rs.getString(1));
454
        tableHasRows = rs.next();
455
      }
456
    } 
457
    catch (SQLException e) 
458
    {
459
      System.err.println("Error getting id: " + e.getMessage());
460
    } finally {
461
      try
462
      {
463
        pstmt.close();
464
      }
465
      catch(SQLException sqle) {}
466
    }
467
    return result.toArray();
468
  }
469
  
470
  /**
471
   * format a structured query as an XML document that conforms
472
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
473
   * structured query engine
474
   *
475
   * @param params The list of parameters that  should be included in the query
476
   */
477
  public static String createSQuery(Hashtable params)
478
  { 
479
    StringBuffer query = new StringBuffer();
480
    Enumeration elements;
481
    Enumeration keys;
482
    String doctype = null;
483
    String casesensitive = null;
484
    String searchmode = null;
485
    Object nextkey;
486
    Object nextelement;
487
    //add the xml headers
488
    query.append("<?xml version=\"1.0\"?>\n");
489
    query.append("<pathquery version=\"1.0\"><meta_file_id>");
490
    
491
    if(params.containsKey("meta_file_id"))
492
    {
493
      query.append( ((String[])params.get("meta_file_id"))[0]);
494
      query.append("</meta_file_id>");
495
    }
496
    else
497
    {
498
      query.append("unspecified</meta_file_id>");
499
    }
500
    
501
    query.append("<querytitle>");
502
    if(params.containsKey("querytitle"))
503
    {
504
      query.append(((String[])params.get("querytitle"))[0]);
505
      query.append("</querytitle>");
506
    }
507
    else
508
    {
509
      query.append("unspecified</querytitle>");
510
    }
511
    
512
    if(params.containsKey("doctype"))
513
    {
514
      doctype = ((String[])params.get("doctype"))[0]; 
515
    }
516
    else
517
    {
518
      doctype = "ANY";  
519
    }
520
    
521
    if(params.containsKey("returnfield"))
522
    {
523
      String[] returnfield = ((String[])params.get("returnfield"));
524
      for(int i=0; i<returnfield.length; i++)
525
      {
526
        query.append("<returnfield>").append(returnfield[i]);
527
        query.append("</returnfield>");
528
      }
529
    }
530
    
531
    if(params.containsKey("owner"))
532
    {
533
      String[] owner = ((String[])params.get("owner"));
534
      for(int i=0; i<owner.length; i++)
535
      {
536
        query.append("<owner>").append(owner[i]);
537
        query.append("</owner>");
538
      }
539
    }
540
    
541
    if(params.containsKey("site"))
542
    {
543
      String[] site = ((String[])params.get("site"));
544
      for(int i=0; i<site.length; i++)
545
      {
546
        query.append("<site>").append(site[i]);
547
        query.append("</site>");
548
      }
549
    }
550
    
551
    //if you don't limit the query by doctype, then it just creates
552
    //an empty returndoctype tag.
553
    if (!doctype.equals("any") && 
554
        !doctype.equals("ANY") &&
555
        !doctype.equals("") ) 
556
    {
557
       query.append("<returndoctype>");
558
       query.append(doctype).append("</returndoctype>");
559
    }
560
    else
561
    { 
562
      query.append("<returndoctype></returndoctype>");
563
    }
564
    
565
    //allows the dynamic switching of boolean operators
566
    if(params.containsKey("operator"))
567
    {
568
      query.append("<querygroup operator=\"" + 
569
                ((String[])params.get("operator"))[0] + "\">");
570
    }
571
    else
572
    { //the default operator is UNION
573
      query.append("<querygroup operator=\"UNION\">"); 
574
    }
575
        
576
    if(params.containsKey("casesensitive"))
577
    {
578
      casesensitive = ((String[])params.get("casesensitive"))[0]; 
579
    }
580
    else
581
    {
582
      casesensitive = "false"; 
583
    }
584
    
585
    if(params.containsKey("searchmode"))
586
    {
587
      searchmode = ((String[])params.get("searchmode"))[0]; 
588
    }
589
    else
590
    {
591
      searchmode = "contains"; 
592
    }
593
        
594
    //anyfield is a special case because it does a 
595
    //free text search.  It does not have a <pathexpr>
596
    //tag.  This allows for a free text search within the structured
597
    //query.  This is useful if the INTERSECT operator is used.
598
    if(params.containsKey("anyfield"))
599
    {
600
       String[] anyfield = ((String[])params.get("anyfield"));
601
       //allow for more than one value for anyfield
602
       for(int i=0; i<anyfield.length; i++)
603
       {
604
         if(!anyfield[i].equals(""))
605
         {
606
           query.append("<queryterm casesensitive=\"" + casesensitive + 
607
                        "\" " + "searchmode=\"" + searchmode + "\"><value>" +
608
                        anyfield[i] +
609
                        "</value></queryterm>"); 
610
         }
611
       }
612
    }
613
        
614
    //this while loop finds the rest of the parameters
615
    //and attempts to query for the field specified
616
    //by the parameter.
617
    elements = params.elements();
618
    keys = params.keys();
619
    while(keys.hasMoreElements() && elements.hasMoreElements())
620
    {
621
      nextkey = keys.nextElement();
622
      nextelement = elements.nextElement();
623

    
624
      //make sure we aren't querying for any of these
625
      //parameters since the are already in the query
626
      //in one form or another.
627
      if(!nextkey.toString().equals("doctype") && 
628
         !nextkey.toString().equals("action")  &&
629
         !nextkey.toString().equals("qformat") && 
630
         !nextkey.toString().equals("anyfield") &&
631
         !nextkey.toString().equals("returnfield") &&
632
         !nextkey.toString().equals("owner") &&
633
         !nextkey.toString().equals("site") &&
634
         !nextkey.toString().equals("operator") )
635
      {
636
        //allow for more than value per field name
637
        for(int i=0; i<((String[])nextelement).length; i++)
638
        {
639
          if(!((String[])nextelement)[i].equals(""))
640
          {
641
            query.append("<queryterm casesensitive=\"" + casesensitive +"\" " + 
642
                         "searchmode=\"" + searchmode + "\">" +
643
                         "<value>" +
644
                         //add the query value
645
                         ((String[])nextelement)[i] +
646
                         "</value><pathexpr>" +
647
                         //add the path to query by 
648
                         nextkey.toString() + 
649
                         "</pathexpr></queryterm>");
650
          }
651
        }
652
      }
653
    }
654
    query.append("</querygroup></pathquery>");
655
    //append on the end of the xml and return the result as a string
656
    return query.toString();
657
  }
658
  
659
  /**
660
   * format a simple free-text value query as an XML document that conforms
661
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
662
   * structured query engine
663
   *
664
   * @param value the text string to search for in the xml catalog
665
   * @param doctype the type of documents to include in the result set -- use
666
   *        "any" or "ANY" for unfiltered result sets
667
   */
668
   public static String createQuery(String value, String doctype) {
669
     StringBuffer xmlquery = new StringBuffer();
670
     xmlquery.append("<?xml version=\"1.0\"?>\n");
671
     xmlquery.append("<pathquery version=\"1.0\">");
672
     xmlquery.append("<meta_file_id>Unspecified</meta_file_id>");
673
     xmlquery.append("<querytitle>Unspecified</querytitle>");
674

    
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
     //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
     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
   
709
  /** 
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
                  throws SQLException
716
  {
717
    // b' of the command line invocation
718
    if ( (user == null) && (group == null) ) {
719
      return true;
720
    }
721
    
722
    // Check for READ permission on @docid for @user and/or @group
723
    AccessControlList aclobj = new AccessControlList(conn);
724
    boolean hasPermission = aclobj.hasPermission("READ",user,docid);
725
    if ( !hasPermission && group != null ) {
726
      hasPermission = aclobj.hasPermission("READ",group,docid);
727
    }
728
    
729
    return hasPermission;
730
  }
731
   
732
}
(14-14/43)