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: jones $'
14
 *     '$Date: 2000-11-27 13:55:08 -0800 (Mon, 27 Nov 2000) $'
15
 * '$Revision: 566 $'
16
 */
17

    
18
package edu.ucsb.nceas.metacat;
19

    
20
import java.io.*;
21
import java.util.Vector;
22
import java.net.URL;
23
import java.net.MalformedURLException;
24
import java.sql.*;
25
import java.util.Stack;
26
import java.util.Hashtable;
27
import java.util.Enumeration;
28

    
29
/** 
30
 * A Class that searches a relational DB for elements and 
31
 * attributes that have free text matches a query string,
32
 * or structured query matches to a path specified node in the 
33
 * XML hierarchy.  It returns a result set consisting of the 
34
 * document ID for each document that satisfies the query
35
 */
36
public class DBQuery {
37

    
38
  static final int ALL = 1;
39
  static final int WRITE = 2;
40
  static final int READ = 4;
41

    
42
  private Connection  conn = null;
43
  private String  parserName = null;
44
  private MetaCatUtil util = new MetaCatUtil();
45
  /**
46
   * the main routine used to test the DBQuery utility.
47
   * <p>
48
   * Usage: java DBQuery <xmlfile>
49
   *
50
   * @param xmlfile the filename of the xml file containing the query
51
   */
52
  static public void main(String[] args) {
53
     
54
     if (args.length < 1)
55
     {
56
        System.err.println("Wrong number of arguments!!!");
57
        System.err.println("USAGE: java DBQuery <xmlfile>");
58
        return;
59
     } else {
60
        try {
61
                    
62
          String xmlfile  = args[0];
63

    
64
          // Open a connection to the database
65
          MetaCatUtil   util = new MetaCatUtil();
66
          Connection dbconn = util.openDBConnection();
67

    
68
          // Execute the query
69
          DBQuery queryobj = new DBQuery(dbconn, util.getOption("saxparser"));
70
          FileReader xml = new FileReader(new File(xmlfile));
71
          Hashtable nodelist = null;
72
          nodelist = queryobj.findDocuments(xml, null, null);
73

    
74
          // Print the reulting document listing
75
          StringBuffer result = new StringBuffer();
76
          String document = null;
77
          String docid = null;
78
          result.append("<?xml version=\"1.0\"?>\n");
79
          result.append("<resultset>\n"); 
80
  // following line removed by Dan Higgins to avoid insertion of query XML inside returned XML doc
81
  //        result.append("  <query>" + xmlfile + "</query>\n");
82
          Enumeration doclist = nodelist.keys(); 
83
          while (doclist.hasMoreElements()) {
84
            docid = (String)doclist.nextElement();
85
            document = (String)nodelist.get(docid);
86
            result.append("  <document>\n    " + document + 
87
                          "\n  </document>\n");
88
          }
89
          result.append("</resultset>\n");
90

    
91
          System.out.println(result);
92

    
93
        } catch (Exception e) {
94
          System.err.println("EXCEPTION HANDLING REQUIRED");
95
          System.err.println(e.getMessage());
96
          e.printStackTrace(System.err);
97
        }
98
     }
99
  }
100
  
101
  /**
102
   * construct an instance of the DBQuery class 
103
   *
104
   * <p>Generally, one would call the findDocuments() routine after creating 
105
   * an instance to specify the search query</p>
106
   *
107
   * @param conn the JDBC connection that we use for the query
108
   * @param parserName the fully qualified name of a Java class implementing
109
   *                   the org.xml.sax.XMLReader interface
110
   */
111
  public DBQuery( Connection conn, String parserName ) 
112
                  throws IOException, 
113
                         SQLException, 
114
                         ClassNotFoundException {
115
    this.conn = conn;
116
    this.parserName = parserName;
117
  }
118
  
119
  public Hashtable findDocuments(Reader xmlquery, String user, String group)
120
  {
121
    return findDocuments(xmlquery, user, group, null);
122
  }
123
  
124
  /** 
125
   * routine to search the elements and attributes looking to match query
126
   *
127
   * @param xmlquery the xml serialization of the query (@see pathquery.dtd)
128
   * @param user the username of the user
129
   * @param group the group of the user
130
   * @param returndoc an array of document types to backtrack against.
131
   */
132
  public Hashtable findDocuments(Reader xmlquery, String user, String group,
133
                                 String[] returndoc)
134
  {
135
      Hashtable   docListResult = new Hashtable();
136
      PreparedStatement pstmt;
137
      String docid = null;
138
      String docname = null;
139
      String doctype = null;
140
      String doctitle = null;
141
      String createDate = null;
142
      String updateDate = null;
143
      String fieldname = null;
144
      String fielddata = null;
145
      String relation = null;
146
      StringBuffer document = null; 
147
      Vector returndocVec = new Vector();
148
      
149
      if(returndoc != null)
150
      {//add the returndoc elements to a vector for easier manipulation
151
        for(int i=0; i<returndoc.length; i++)
152
        {
153
          returndocVec.add(new String((String)returndoc[i]));
154
        }
155
      }
156
      
157
      try {
158
        // Get the XML query and covert it into a SQL statment
159
        QuerySpecification qspec = new QuerySpecification(xmlquery, 
160
                                   parserName, 
161
                                   util.getOption("accNumberSeparator"));
162
        //System.out.println(qspec.printSQL());
163
        pstmt = conn.prepareStatement( qspec.printSQL() );
164

    
165
        // Execute the SQL query using the JDBC connection
166
        pstmt.execute();
167
        ResultSet rs = pstmt.getResultSet();
168
        boolean tableHasRows = rs.next();
169
        while (tableHasRows) {
170
          docid = rs.getString(1);
171
          if ( !hasReadPermission(conn, docid, user, group) ) {continue;}
172
          docname = rs.getString(2);
173
          doctype = rs.getString(3);
174
          doctitle = rs.getString(4);
175
          createDate = rs.getString(5);
176
          updateDate = rs.getString(6);
177
//System.out.println("vec.size = " + returndocVec.size());
178
          if(returndocVec.size() != 0 && !returndocVec.contains(doctype))
179
          { //there are returndocs to match (backtracking can now be performed). 
180
//System.out.println("olddoctype: " + doctype);
181
            StringBuffer btBuf = new StringBuffer();
182
            btBuf.append("select object from xml_relation where ");
183
            btBuf.append("objdoctype in (");
184
            //build the doctype list for the backtracking sql statement
185
            for(int i=0; i<returndocVec.size(); i++)
186
            {
187
              btBuf.append("'").append((String)returndocVec.get(i)).append("'");
188
              if(i != (returndocVec.size() - 1))
189
              {
190
                btBuf.append(", ");
191
              } 
192
            }
193
            btBuf.append(") ");
194
            btBuf.append("and subject like '");
195
            btBuf.append("metacat://").append(util.getOption("server"));
196
            btBuf.append("?docid=").append(docid).append("'");
197
            pstmt = conn.prepareStatement(btBuf.toString());
198
            pstmt.execute();
199
            ResultSet btrs = pstmt.getResultSet();
200
            boolean hasBtRows = btrs.next();
201
            if(hasBtRows)
202
            { //there was a backtrackable document found
203
              DocumentImpl xmldoc = null;
204
              //System.out.println("document found is: " + btrs.getString(1));
205
              MetacatURL objURL = new MetacatURL(btrs.getString(1));
206
              try
207
              {
208
                xmldoc = new DocumentImpl(conn, objURL.getParam(0)[1]);
209
              }
210
              catch(Exception e)
211
              {
212
                System.out.println("Error getting document: " + e.getMessage());
213
              }
214
              
215
              docid   = xmldoc.getDocID();
216
              docname = xmldoc.getDocname();
217
              doctype = xmldoc.getDoctype();
218
              doctitle = xmldoc.getDocTitle();
219
              createDate = xmldoc.getCreateDate();
220
              updateDate = xmldoc.getUpdateDate();
221
              //System.out.println("docname: " + docname + " doctype: " + doctype + 
222
              //                   " doctitle: " + doctitle + " createdate: " +
223
              //                   createDate + " updatedate: " + updateDate);
224
            }
225
            btrs.close();
226
          }
227
          
228
          document = new StringBuffer();
229
          //System.out.println("packagdoctype: " + util.getOption("packagedoctype"));
230
          if(!doctype.equals(util.getOption("packagedoctype")))
231
          {
232
            document.append("<docid>").append(docid).append("</docid>");
233
            if (docname != null) {
234
              document.append("<docname>" + docname + "</docname>");
235
            }
236
            if (doctype != null) {
237
              document.append("<doctype>" + doctype + "</doctype>");
238
            }
239
            if (doctitle != null) {
240
              document.append("<doctitle>" + doctitle + "</doctitle>");
241
            }
242
            if(createDate != null) {
243
              document.append("<createdate>" + createDate + "</createdate>");
244
            }
245
            if(updateDate != null) {
246
              document.append("<updatedate>" + updateDate + "</updatedate>");
247
            }
248
            // Store the document id and the root node id
249
            docListResult.put(docid,(String)document.toString());
250
          }
251

    
252
          // Advance to the next record in the cursor
253
          tableHasRows = rs.next();
254
        }
255
        
256
        if(qspec.containsExtendedSQL())
257
        {
258
          Vector extendedFields = new Vector(qspec.getReturnFieldList());
259
          Vector results = new Vector();
260
          Enumeration keylist = docListResult.keys();
261
          StringBuffer doclist = new StringBuffer();
262
          while(keylist.hasMoreElements())
263
          {
264
            doclist.append("'");
265
            doclist.append((String)keylist.nextElement());
266
            doclist.append("',");
267
          }
268
          doclist.deleteCharAt(doclist.length()-1); //remove the last comma
269
          pstmt = conn.prepareStatement(qspec.printExtendedSQL(
270
                                        doclist.toString()));
271
          pstmt.execute();
272
          rs = pstmt.getResultSet();
273
          tableHasRows = rs.next();
274
          while(tableHasRows) 
275
          {
276
            docid = rs.getString(1);
277
            if ( !hasReadPermission(conn, docid, user, group) ) {continue;}
278
            fieldname = rs.getString(2);
279
            fielddata = rs.getString(3);
280
            
281
            document = new StringBuffer();
282

    
283
            document.append("<param name=\"");
284
            document.append(fieldname);
285
            document.append("\">");
286
            document.append(fielddata);
287
            document.append("</param>");
288

    
289
            tableHasRows = rs.next();
290
            if(docListResult.containsKey(docid))
291
            {
292
              String removedelement = (String)docListResult.remove(docid);
293
              docListResult.put(docid, removedelement + document.toString());
294
            }
295
            else
296
            {
297
              docListResult.put(docid, document.toString()); 
298
            }
299
          }
300
        }
301

    
302
        //this loop adds the relation data to the resultdoc
303
        //this code might be able to be added to the backtracking code above
304
        Enumeration docidkeys = docListResult.keys();
305
        while(docidkeys.hasMoreElements())
306
        {
307
          String connstring = "metacat://"+util.getOption("server")+"?docid=";
308
          String docidkey = (String)docidkeys.nextElement();
309
          pstmt = conn.prepareStatement(
310
                  qspec.printRelationSQL(connstring + docidkey));
311
          pstmt.execute();
312
          rs = pstmt.getResultSet();
313
          tableHasRows = rs.next();
314
          while(tableHasRows)
315
          {
316
            String sub = rs.getString(1);
317
            String rel = rs.getString(2);
318
            String obj = rs.getString(3);
319
            String subDT = rs.getString(4);
320
            String objDT = rs.getString(5);
321
            
322
            MetacatURL murl = new MetacatURL(sub);
323
            if(murl.getProtocol().equals("metacat"))
324
            {//we only want to process metacat urls here.
325
              String[] tempparam = murl.getParam(0);
326
              if(tempparam[0].equals("docid") && tempparam[1].equals(docidkey))
327
              {
328
                document = new StringBuffer();
329
                document.append("<relation>");
330
                document.append("<relationtype>").append(rel);
331
                document.append("</relationtype>");
332
                document.append("<relationdoc>").append(obj);
333
                document.append("</relationdoc>");
334
                document.append("<relationdoctype>").append(objDT);
335
                document.append("</relationdoctype>");
336
                document.append("</relation>");
337
                
338
                String removedelement = (String)docListResult.remove(docidkey);
339
                docListResult.put(docidkey, removedelement + document.toString());
340
                
341
              }
342
            }
343
            tableHasRows = rs.next();
344
          }
345
        }
346
        pstmt.close();
347
      } catch (SQLException e) {
348
        System.err.println("Error getting id: " + e.getMessage());
349
      } catch (IOException ioe) {
350
        System.err.println("Error printing qspec:");
351
        System.err.println(ioe.getMessage());
352
      }
353
    //System.out.println("docListResult: ");
354
    //System.out.println(docListResult.toString());
355
    return docListResult;
356
  }
357
  
358
  /**
359
   * returns a string array of the contents of a particular node. 
360
   * If the node appears more than once, the contents are returned 
361
   * in the order in which they appearred in the document.
362
   * @param nodename the name or path of the particular node.
363
   * @param docid the docid of the document you want the node from.
364
   * @param conn a database connection-this allows this method to be static
365
   */
366
  public static Object[] getNodeContent(String nodename, String docid, 
367
                                        Connection conn)
368
  {
369
    StringBuffer query = new StringBuffer();
370
    Vector result = new Vector();
371
    PreparedStatement pstmt;
372
    query.append("select nodedata from xml_nodes where parentnodeid in ");
373
    query.append("(select nodeid from xml_index where path like '");
374
    query.append(nodename);
375
    query.append("' and docid like '").append(docid).append("')");
376
    try
377
    {
378
      pstmt = conn.prepareStatement(query.toString());
379

    
380
      // Execute the SQL query using the JDBC connection
381
      pstmt.execute();
382
      ResultSet rs = pstmt.getResultSet();
383
      boolean tableHasRows = rs.next();
384
      while (tableHasRows) 
385
      {
386
        result.add(rs.getString(1));
387
        System.out.println(rs.getString(1));
388
        tableHasRows = rs.next();
389
      }
390
    } 
391
    catch (SQLException e) 
392
    {
393
      System.err.println("Error getting id: " + e.getMessage());
394
    } 
395
    
396
    return result.toArray();
397
  }
398
  
399
  /**
400
   * format a structured query as an XML document that conforms
401
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
402
   * structured query engine
403
   *
404
   * @param params The list of parameters that  should be included in the query
405
   */
406
  public static String createSQuery(Hashtable params)
407
  { 
408
    StringBuffer query = new StringBuffer();
409
    Enumeration elements;
410
    Enumeration keys;
411
    String doctype = null;
412
    String casesensitive = null;
413
    String searchmode = null;
414
    Object nextkey;
415
    Object nextelement;
416
    //add the xml headers
417
    query.append("<?xml version=\"1.0\"?>\n");
418
    query.append("<pathquery version=\"1.0\"><meta_file_id>");
419
    
420
    if(params.containsKey("meta_file_id"))
421
    {
422
      query.append( ((String[])params.get("meta_file_id"))[0]);
423
      query.append("</meta_file_id>");
424
    }
425
    else
426
    {
427
      query.append("unspecified</meta_file_id>");
428
    }
429
    
430
    query.append("<querytitle>");
431
    if(params.containsKey("querytitle"))
432
    {
433
      query.append(((String[])params.get("querytitle"))[0]);
434
      query.append("</querytitle>");
435
    }
436
    else
437
    {
438
      query.append("unspecified</querytitle>");
439
    }
440
    
441
    if(params.containsKey("doctype"))
442
    {
443
      doctype = ((String[])params.get("doctype"))[0]; 
444
    }
445
    else
446
    {
447
      doctype = "ANY";  
448
    }
449
    
450
    if(params.containsKey("returnfield"))
451
    {
452
      String[] returnfield = ((String[])params.get("returnfield"));
453
      for(int i=0; i<returnfield.length; i++)
454
      {
455
        query.append("<returnfield>").append(returnfield[i]);
456
        query.append("</returnfield>");
457
      }
458
    }
459
    
460
    if(params.containsKey("owner"))
461
    {
462
      String[] owner = ((String[])params.get("owner"));
463
      for(int i=0; i<owner.length; i++)
464
      {
465
        query.append("<owner>").append(owner[i]);
466
        query.append("</owner>");
467
      }
468
    }
469
    
470
    if(params.containsKey("site"))
471
    {
472
      String[] site = ((String[])params.get("site"));
473
      for(int i=0; i<site.length; i++)
474
      {
475
        query.append("<site>").append(site[i]);
476
        query.append("</site>");
477
      }
478
    }
479
    
480
    //if you don't limit the query by doctype, then it just creates
481
    //an empty returndoctype tag.
482
    if (!doctype.equals("any") && 
483
        !doctype.equals("ANY") &&
484
        !doctype.equals("") ) 
485
    {
486
       query.append("<returndoctype>");
487
       query.append(doctype).append("</returndoctype>");
488
    }
489
    else
490
    { 
491
      query.append("<returndoctype></returndoctype>");
492
    }
493
    
494
    //allows the dynamic switching of boolean operators
495
    if(params.containsKey("operator"))
496
    {
497
      query.append("<querygroup operator=\"" + 
498
                ((String[])params.get("operator"))[0] + "\">");
499
    }
500
    else
501
    { //the default operator is UNION
502
      query.append("<querygroup operator=\"UNION\">"); 
503
    }
504
        
505
    if(params.containsKey("casesensitive"))
506
    {
507
      casesensitive = ((String[])params.get("casesensitive"))[0]; 
508
    }
509
    else
510
    {
511
      casesensitive = "false"; 
512
    }
513
    
514
    if(params.containsKey("searchmode"))
515
    {
516
      searchmode = ((String[])params.get("searchmode"))[0]; 
517
    }
518
    else
519
    {
520
      searchmode = "contains"; 
521
    }
522
        
523
    //anyfield is a special case because it does a 
524
    //free text search.  It does not have a <pathexpr>
525
    //tag.  This allows for a free text search within the structured
526
    //query.  This is useful if the INTERSECT operator is used.
527
    if(params.containsKey("anyfield"))
528
    {
529
       String[] anyfield = ((String[])params.get("anyfield"));
530
       //allow for more than one value for anyfield
531
       for(int i=0; i<anyfield.length; i++)
532
       {
533
         if(!anyfield[i].equals(""))
534
         {
535
           query.append("<queryterm casesensitive=\"" + casesensitive + 
536
                        "\" " + "searchmode=\"" + searchmode + "\"><value>" +
537
                        anyfield[i] +
538
                        "</value></queryterm>"); 
539
         }
540
       }
541
    }
542
        
543
    //this while loop finds the rest of the parameters
544
    //and attempts to query for the field specified
545
    //by the parameter.
546
    elements = params.elements();
547
    keys = params.keys();
548
    while(keys.hasMoreElements() && elements.hasMoreElements())
549
    {
550
      nextkey = keys.nextElement();
551
      nextelement = elements.nextElement();
552

    
553
      //make sure we aren't querying for any of these
554
      //parameters since the are already in the query
555
      //in one form or another.
556
      if(!nextkey.toString().equals("doctype") && 
557
         !nextkey.toString().equals("action")  &&
558
         !nextkey.toString().equals("qformat") && 
559
         !nextkey.toString().equals("anyfield") &&
560
         !nextkey.toString().equals("returnfield") &&
561
         !nextkey.toString().equals("owner") &&
562
         !nextkey.toString().equals("site") &&
563
         !nextkey.toString().equals("operator") )
564
      {
565
        //allow for more than value per field name
566
        for(int i=0; i<((String[])nextelement).length; i++)
567
        {
568
          if(!((String[])nextelement)[i].equals(""))
569
          {
570
            query.append("<queryterm casesensitive=\"" + casesensitive +"\" " + 
571
                         "searchmode=\"" + searchmode + "\">" +
572
                         "<value>" +
573
                         //add the query value
574
                         ((String[])nextelement)[i] +
575
                         "</value><pathexpr>" +
576
                         //add the path to query by 
577
                         nextkey.toString() + 
578
                         "</pathexpr></queryterm>");
579
          }
580
        }
581
      }
582
    }
583
    query.append("</querygroup></pathquery>");
584
    //append on the end of the xml and return the result as a string
585
    return query.toString();
586
  }
587
  
588
  /**
589
   * format a simple free-text value query as an XML document that conforms
590
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
591
   * structured query engine
592
   *
593
   * @param value the text string to search for in the xml catalog
594
   * @param doctype the type of documents to include in the result set -- use
595
   *        "any" or "ANY" for unfiltered result sets
596
   */
597
   public static String createQuery(String value, String doctype) {
598
     StringBuffer xmlquery = new StringBuffer();
599
     xmlquery.append("<?xml version=\"1.0\"?>\n");
600
     xmlquery.append("<pathquery version=\"1.0\">");
601
     xmlquery.append("<meta_file_id>Unspecified</meta_file_id>");
602
     xmlquery.append("<querytitle>Unspecified</querytitle>");
603

    
604
     if (!doctype.equals("any") && !doctype.equals("ANY")) {
605
       xmlquery.append("<returndoctype>");
606
       xmlquery.append(doctype).append("</returndoctype>");
607
     }
608

    
609
     xmlquery.append("<querygroup operator=\"UNION\">");
610
     //chad added - 8/14
611
     //the if statement allows a query to gracefully handle a null 
612
     //query.  Without this if a nullpointerException is thrown.
613
     if(!value.equals(""))
614
     {
615
       xmlquery.append("<queryterm casesensitive=\"false\" ");
616
       xmlquery.append("searchmode=\"contains\">");
617
       xmlquery.append("<value>").append(value).append("</value>");
618
       xmlquery.append("</queryterm>");
619
     }
620
     xmlquery.append("</querygroup>");
621
     xmlquery.append("</pathquery>");
622

    
623
     
624
     return (xmlquery.toString());
625
   }
626

    
627
  /**
628
   * format a simple free-text value query as an XML document that conforms
629
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
630
   * structured query engine
631
   *
632
   * @param value the text string to search for in the xml catalog
633
   */
634
   public static String createQuery(String value) {
635
     return createQuery(value, "any");
636
   }
637
   
638
  /** Check for "read" permissions from DB connection */
639
  private boolean hasReadPermission(Connection conn, String docid, 
640
                                     String user, String group) 
641
                                     throws SQLException {
642
    // b' of the command line invocation
643
    if ( (user == null) && (group == null) ) {
644
      return true;
645
    }
646
    
647
    PreparedStatement pstmt;
648
    // checking if user is owner of docid or if docid has public access
649
    try {
650
      pstmt = conn.prepareStatement(
651
                   "SELECT 'x' FROM xml_documents " +
652
                   "WHERE docid LIKE ? AND user_owner LIKE ? " + 
653
                   "UNION " +
654
                   "SELECT 'x' FROM xml_documents " +
655
                   "WHERE docid LIKE ? AND public_access = 1");
656
      // Bind the values to the query
657
      pstmt.setString(1, docid);
658
      pstmt.setString(2, user);
659
      pstmt.setString(3, docid);
660

    
661
      pstmt.execute();
662
      ResultSet rs = pstmt.getResultSet();
663
      boolean hasRow = rs.next();
664
      pstmt.close();
665
      if (hasRow) {
666
        return true;
667
      }
668
      
669
    } catch (SQLException e) {
670
      throw new 
671
        SQLException("Error checking document's owner or public access: "
672
                      + e.getMessage());
673
    }
674

    
675
    // checking if docid has public access at this time
676
    try {
677
      pstmt = conn.prepareStatement(
678
                   "SELECT 'x' FROM xml_access " +
679
                   "WHERE docid LIKE ? " +
680
                   "AND principal_name = 'public' " +
681
                   "AND principal_type = 'user' " +
682
                   "AND sysdate BETWEEN nvl(begin_time,sysdate) " +
683
                                   "AND nvl(end_time,sysdate)");
684
      // Bind the values to the query
685
      pstmt.setString(1, docid);
686

    
687
      pstmt.execute();
688
      ResultSet rs = pstmt.getResultSet();
689
      boolean hasRow = rs.next();
690
      pstmt.close();
691
      if (hasRow) {
692
        return true;
693
      }
694
      
695
    } catch (SQLException e) {
696
      throw new 
697
        SQLException("Error checking doc's public access: " + e.getMessage());
698
    }
699

    
700
    // checking access type from xml_access table
701
    int accesstype = 0;
702
    try {
703
      pstmt = conn.prepareStatement(
704
                   "SELECT access_type FROM xml_access " +
705
                   "WHERE docid LIKE ? " + 
706
                   "AND principal_name LIKE ? " +
707
                   "AND principal_type = 'user' " +
708
                   "AND sysdate BETWEEN nvl(begin_time,sysdate) " +
709
                                   "AND nvl(end_time,sysdate) " +
710
                   "UNION " +
711
                   "SELECT access_type FROM xml_access " +
712
                   "WHERE docid LIKE ? " + 
713
                   "AND principal_name LIKE ? " +
714
                   "AND principal_type = 'group' " +
715
                   "AND sysdate BETWEEN nvl(begin_time,sysdate) " +
716
                                   "AND nvl(end_time,sysdate)");
717
      // Bind the values to the query
718
      pstmt.setString(1, docid);
719
      pstmt.setString(2, user);
720
      pstmt.setString(3, docid);
721
      pstmt.setString(4, group);
722

    
723
      pstmt.execute();
724
      ResultSet rs = pstmt.getResultSet();
725
      boolean hasRows = rs.next();
726
      while ( hasRows ) {
727
        accesstype = rs.getInt(1);
728
        if ( (accesstype & READ) == READ ) {
729
          pstmt.close();
730
          return true;
731
        }
732
        hasRows = rs.next();
733
      }
734

    
735
      pstmt.close();
736
      return false;
737
      
738
    } catch (SQLException e) {
739
      throw new 
740
      SQLException("Error getting document's permissions: " + e.getMessage());
741
    }
742
  }
743
   
744
}
(13-13/36)