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 940 tao
import edu.ucsb.nceas.morpho.datapackage.*;
35 155 jones
import java.io.*;
36 401 berkley
import java.util.Vector;
37 940 tao
import java.util.zip.*;
38 155 jones
import java.net.URL;
39
import java.net.MalformedURLException;
40
import java.sql.*;
41
import java.util.Stack;
42
import java.util.Hashtable;
43
import java.util.Enumeration;
44 706 bojilova
import java.io.File;
45
import java.io.FileWriter;
46
import java.io.BufferedWriter;
47 940 tao
import javax.servlet.ServletOutputStream;
48 155 jones
49
/**
50 172 jones
 * A Class that searches a relational DB for elements and
51
 * attributes that have free text matches a query string,
52
 * or structured query matches to a path specified node in the
53
 * XML hierarchy.  It returns a result set consisting of the
54
 * document ID for each document that satisfies the query
55 155 jones
 */
56
public class DBQuery {
57
58 441 bojilova
  static final int ALL = 1;
59
  static final int WRITE = 2;
60
  static final int READ = 4;
61 940 tao
62 1217 tao
  //private Connection  conn = null;
63 535 jones
  private String  parserName = null;
64 465 berkley
  private MetaCatUtil util = new MetaCatUtil();
65 155 jones
  /**
66
   * the main routine used to test the DBQuery utility.
67 184 jones
   * <p>
68
   * Usage: java DBQuery <xmlfile>
69 155 jones
   *
70 170 jones
   * @param xmlfile the filename of the xml file containing the query
71 155 jones
   */
72
  static public void main(String[] args) {
73
74 184 jones
     if (args.length < 1)
75 155 jones
     {
76
        System.err.println("Wrong number of arguments!!!");
77 706 bojilova
        System.err.println("USAGE: java DBQuery [-t] [-index] <xmlfile>");
78 155 jones
        return;
79
     } else {
80
        try {
81
82 706 bojilova
          int i = 0;
83
          boolean showRuntime = false;
84
          boolean useXMLIndex = false;
85
          if ( args[i].equals( "-t" ) ) {
86
            showRuntime = true;
87
            i++;
88
          }
89
          if ( args[i].equals( "-index" ) ) {
90
            useXMLIndex = true;
91
            i++;
92
          }
93
          String xmlfile  = args[i];
94
95
          // Time the request if asked for
96
          double startTime = System.currentTimeMillis();
97
98 155 jones
          // Open a connection to the database
99 184 jones
          MetaCatUtil   util = new MetaCatUtil();
100 1217 tao
          //Connection dbconn = util.openDBConnection();
101 706 bojilova
102 705 berkley
          double connTime = System.currentTimeMillis();
103 706 bojilova
104 170 jones
          // Execute the query
105 1217 tao
          DBQuery queryobj = new DBQuery(util.getOption("saxparser"));
106 170 jones
          FileReader xml = new FileReader(new File(xmlfile));
107 155 jones
          Hashtable nodelist = null;
108 706 bojilova
          nodelist = queryobj.findDocuments(xml, null, null, useXMLIndex);
109
110 172 jones
          // Print the reulting document listing
111 155 jones
          StringBuffer result = new StringBuffer();
112
          String document = null;
113 170 jones
          String docid = null;
114 155 jones
          result.append("<?xml version=\"1.0\"?>\n");
115 296 higgins
          result.append("<resultset>\n");
116 940 tao
117 743 jones
          if (!showRuntime)
118 710 berkley
          {
119
            Enumeration doclist = nodelist.keys();
120
            while (doclist.hasMoreElements()) {
121
              docid = (String)doclist.nextElement();
122
              document = (String)nodelist.get(docid);
123
              result.append("  <document>\n    " + document +
124
                            "\n  </document>\n");
125
            }
126
127
            result.append("</resultset>\n");
128 155 jones
          }
129 706 bojilova
          // Time the request if asked for
130
          double stopTime = System.currentTimeMillis();
131 705 berkley
          double dbOpenTime = (connTime - startTime)/1000;
132 706 bojilova
          double readTime = (stopTime - connTime)/1000;
133 705 berkley
          double executionTime = (stopTime - startTime)/1000;
134 706 bojilova
          if (showRuntime) {
135 710 berkley
            System.out.print("  " + executionTime);
136
            System.out.print("  " + dbOpenTime);
137
            System.out.print("  " + readTime);
138
            System.out.print("  " + nodelist.size());
139
            System.out.println();
140 706 bojilova
          }
141
          //System.out.println(result);
142
          //write into a file "result.txt"
143 743 jones
          if (!showRuntime)
144 710 berkley
          {
145
            File f = new File("./result.txt");
146
            FileWriter fw = new FileWriter(f);
147
            BufferedWriter out = new BufferedWriter(fw);
148
            out.write(result.toString());
149
            out.flush();
150
            out.close();
151
            fw.close();
152
          }
153
154
        }
155
        catch (Exception e) {
156 675 berkley
          System.err.println("Error in DBQuery.main");
157 155 jones
          System.err.println(e.getMessage());
158
          e.printStackTrace(System.err);
159
        }
160
     }
161
  }
162
163
  /**
164
   * construct an instance of the DBQuery class
165
   *
166
   * <p>Generally, one would call the findDocuments() routine after creating
167
   * an instance to specify the search query</p>
168
   *
169
   * @param conn the JDBC connection that we use for the query
170 172 jones
   * @param parserName the fully qualified name of a Java class implementing
171 185 jones
   *                   the org.xml.sax.XMLReader interface
172 155 jones
   */
173 1217 tao
  public DBQuery(String parserName )
174 155 jones
                  throws IOException,
175
                         SQLException,
176 172 jones
                         ClassNotFoundException {
177 1217 tao
    //this.conn = conn;
178 172 jones
    this.parserName = parserName;
179 155 jones
  }
180
181 745 jones
  /**
182
   * routine to search the elements and attributes looking to match query
183
   *
184
   * @param xmlquery the xml serialization of the query (@see pathquery.dtd)
185
   * @param user the username of the user
186
   * @param group the group of the user
187
   */
188 802 bojilova
  public Hashtable findDocuments(Reader xmlquery, String user, String[] groups)
189 465 berkley
  {
190 802 bojilova
    return findDocuments(xmlquery, user, groups, true);
191 465 berkley
  }
192 706 bojilova
193 155 jones
  /**
194
   * routine to search the elements and attributes looking to match query
195
   *
196 178 jones
   * @param xmlquery the xml serialization of the query (@see pathquery.dtd)
197 465 berkley
   * @param user the username of the user
198
   * @param group the group of the user
199 745 jones
   * @param useXMLIndex flag whether to search using the path index
200 155 jones
   */
201 802 bojilova
  public Hashtable findDocuments(Reader xmlquery, String user, String[] groups,
202 745 jones
                                 boolean useXMLIndex)
203 453 berkley
  {
204 1834 tao
      Hashtable result = new Hashtable();
205
      try
206
      {
207
        // Get the XML query and covert it into a SQL statment
208
        QuerySpecification qspec = new QuerySpecification(xmlquery,
209
                                   parserName,
210
                                   util.getOption("accNumSeparator"));
211
        result = findDocuments(qspec, user, groups, useXMLIndex);
212
      }
213
      catch (IOException ioe)
214
      {
215
        MetaCatUtil.debugMessage("IO error in DBQuery.findDocuments:", 30);
216
        MetaCatUtil.debugMessage(ioe.getMessage(), 30);
217
      }
218
      return result;
219
  }
220
221
  /**
222
   * routine to search the elements and attributes looking to match query
223
   *
224
   * @param qspec java object of the query
225
   * @param user the username of the user
226
   * @param group the group of the user
227
   * @param useXMLIndex flag whether to search using the path index
228
   */
229
  public Hashtable findDocuments(QuerySpecification qspec, String user,
230
                                  String[] groups, boolean useXMLIndex)
231
  {
232 535 jones
      Hashtable   docListResult = new Hashtable();
233 667 berkley
      PreparedStatement pstmt = null;
234 170 jones
      String docid = null;
235 155 jones
      String docname = null;
236
      String doctype = null;
237 401 berkley
      String createDate = null;
238
      String updateDate = null;
239
      String fieldname = null;
240
      String fielddata = null;
241 453 berkley
      String relation = null;
242 1217 tao
      //Connection dbconn = null;
243
      //Connection dbconn2 = null;
244 624 berkley
      int rev = 0;
245 1217 tao
      StringBuffer document = null;
246
      DBConnection dbconn = null;
247
      int serialNumber = -1;
248 465 berkley
249 155 jones
      try {
250 1300 tao
251 1217 tao
252
        dbconn=DBConnectionPool.getDBConnection("DBQuery.findDocuments");
253
        serialNumber=dbconn.getCheckOutSerialNumber();
254 1300 tao
255 1297 tao
        String query = qspec.printSQL(useXMLIndex);
256 1303 tao
        String ownerQuery = getOwnerQuery(user);
257 1297 tao
        MetaCatUtil.debugMessage("query: "+query, 30);
258 1303 tao
        //MetaCatUtil.debugMessage("query: "+ownerQuery, 30);
259
        // if query is not the owner query, we need to check the permission
260
        // otherwise we don't need (owner has all permission by default)
261
        if (!query.equals(ownerQuery))
262
        {
263
          // set user name and group
264
          qspec.setUserName(user);
265
          qspec.setGroup(groups);
266
          // Get access query
267
          String accessQuery = qspec.getAccessQuery();
268
          query = query + accessQuery;
269
          MetaCatUtil.debugMessage(" final query: "+query, 30);
270
        }
271 1300 tao
272 1297 tao
        double startTime = System.currentTimeMillis()/1000;
273
        pstmt = dbconn.prepareStatement(query);
274 790 bojilova
275 172 jones
        // Execute the SQL query using the JDBC connection
276 155 jones
        pstmt.execute();
277
        ResultSet rs = pstmt.getResultSet();
278 1297 tao
        double queryExecuteTime =System.currentTimeMillis()/1000;
279
        MetaCatUtil.debugMessage("Time for execute query: "+
280
                                            (queryExecuteTime -startTime), 30);
281 155 jones
        boolean tableHasRows = rs.next();
282 667 berkley
        while (tableHasRows)
283
        {
284 768 bojilova
          docid = rs.getString(1).trim();
285 1300 tao
          //long checkTimeStart = System.currentTimeMillis();
286
          //boolean permit =hasPermission(user, groups, docid);
287
          //long checkTimeEnd = System.currentTimeMillis();
288
          //MetaCatUtil.debugMessage("check permission time: "+
289
                                  //(checkTimeEnd - checkTimeStart), 30);
290
          //if ( !permit ) {
291 612 bojilova
            // Advance to the next record in the cursor
292 1300 tao
            //tableHasRows = rs.next();
293
            //continue;
294
          //}
295 1297 tao
296 155 jones
          docname = rs.getString(2);
297
          doctype = rs.getString(3);
298 692 bojilova
          createDate = rs.getString(4);
299
          updateDate = rs.getString(5);
300
          rev = rs.getInt(6);
301 743 jones
302 745 jones
          // if there are returndocs to match, backtracking can be performed
303
          // otherwise, just return the document that was hit
304
          Vector returndocVec = qspec.getReturnDocList();
305 1349 tao
          if (returndocVec.size() != 0 && !returndocVec.contains(doctype)
306
              && !qspec.isPercentageSearch())
307 743 jones
          {
308 1349 tao
            MetaCatUtil.debugMessage("Back tracing now...", 20);
309 743 jones
            String sep = util.getOption("accNumSeparator");
310 465 berkley
            StringBuffer btBuf = new StringBuffer();
311 743 jones
            btBuf.append("select docid from xml_relation where ");
312
313 465 berkley
            //build the doctype list for the backtracking sql statement
314 743 jones
            btBuf.append("packagetype in (");
315 465 berkley
            for(int i=0; i<returndocVec.size(); i++)
316
            {
317
              btBuf.append("'").append((String)returndocVec.get(i)).append("'");
318 743 jones
              if (i != (returndocVec.size() - 1))
319 465 berkley
              {
320
                btBuf.append(", ");
321 475 berkley
              }
322 465 berkley
            }
323
            btBuf.append(") ");
324 743 jones
325
            btBuf.append("and (subject like '");
326 1347 tao
            btBuf.append(docid).append("'");
327 743 jones
            btBuf.append("or object like '");
328 1347 tao
            btBuf.append(docid).append("')");
329 667 berkley
330 743 jones
            PreparedStatement npstmt = dbconn.
331
                                       prepareStatement(btBuf.toString());
332 1217 tao
            //should incease usage count
333
            dbconn.increaseUsageCount(1);
334 671 berkley
            npstmt.execute();
335
            ResultSet btrs = npstmt.getResultSet();
336 465 berkley
            boolean hasBtRows = btrs.next();
337 743 jones
            while (hasBtRows)
338 465 berkley
            { //there was a backtrackable document found
339
              DocumentImpl xmldoc = null;
340 743 jones
              String packageDocid = btrs.getString(1);
341 1096 tao
              util.debugMessage("Getting document for docid: "+packageDocid,40);
342 465 berkley
              try
343
              {
344 800 jones
                //  THIS CONSTRUCTOR BUILDS THE WHOLE XML doc not needed here
345
                // xmldoc = new DocumentImpl(dbconn, packageDocid);
346
                //  thus use the following to get the doc info only
347
                //  xmldoc = new DocumentImpl(dbconn);
348 1217 tao
                xmldoc = new DocumentImpl(packageDocid, false);
349 800 jones
                if (xmldoc == null) {
350 1096 tao
                  util.debugMessage("Document was null for: "+packageDocid, 50);
351 800 jones
                }
352 465 berkley
              }
353
              catch(Exception e)
354
              {
355 675 berkley
                System.out.println("Error getting document in " +
356
                                   "DBQuery.findDocuments: " + e.getMessage());
357 465 berkley
              }
358
359 800 jones
              String docid_org = xmldoc.getDocID();
360
              if (docid_org == null) {
361 1096 tao
                util.debugMessage("Docid_org was null.", 40);
362 800 jones
              }
363
              docid   = docid_org.trim();
364 465 berkley
              docname = xmldoc.getDocname();
365
              doctype = xmldoc.getDoctype();
366
              createDate = xmldoc.getCreateDate();
367
              updateDate = xmldoc.getUpdateDate();
368 743 jones
              rev = xmldoc.getRev();
369
370
              document = new StringBuffer();
371
372
              String completeDocid = docid + util.getOption("accNumSeparator");
373
              completeDocid += rev;
374
              document.append("<docid>").append(completeDocid);
375
              document.append("</docid>");
376
              if (docname != null) {
377
                document.append("<docname>" + docname + "</docname>");
378
              }
379
              if (doctype != null) {
380
                document.append("<doctype>" + doctype + "</doctype>");
381
              }
382
              if (createDate != null) {
383
                document.append("<createdate>" + createDate + "</createdate>");
384
              }
385
              if (updateDate != null) {
386
                document.append("<updatedate>" + updateDate + "</updatedate>");
387
              }
388
              // Store the document id and the root node id
389
              docListResult.put(docid,(String)document.toString());
390
391
              // Get the next package document linked to our hit
392
              hasBtRows = btrs.next();
393 465 berkley
            }
394 671 berkley
            npstmt.close();
395 465 berkley
            btrs.close();
396 1349 tao
          }
397
          else if (returndocVec.size() != 0 && returndocVec.contains(doctype))
398
          {
399 465 berkley
400 743 jones
            document = new StringBuffer();
401
402 624 berkley
            String completeDocid = docid + util.getOption("accNumSeparator");
403
            completeDocid += rev;
404
            document.append("<docid>").append(completeDocid).append("</docid>");
405 465 berkley
            if (docname != null) {
406
              document.append("<docname>" + docname + "</docname>");
407
            }
408
            if (doctype != null) {
409
              document.append("<doctype>" + doctype + "</doctype>");
410
            }
411 743 jones
            if (createDate != null) {
412 465 berkley
              document.append("<createdate>" + createDate + "</createdate>");
413
            }
414 743 jones
            if (updateDate != null) {
415 465 berkley
              document.append("<updatedate>" + updateDate + "</updatedate>");
416
            }
417
            // Store the document id and the root node id
418
            docListResult.put(docid,(String)document.toString());
419 743 jones
420 155 jones
          }
421
422
          // Advance to the next record in the cursor
423
          tableHasRows = rs.next();
424
        }
425 667 berkley
        rs.close();
426 818 berkley
        pstmt.close();
427 1297 tao
        double docListTime =System.currentTimeMillis()/1000;
428
        MetaCatUtil.debugMessage("prepare docid list time: "
429
                                          +(docListTime-queryExecuteTime), 30);
430 401 berkley
431 743 jones
        if (qspec.containsExtendedSQL())
432 401 berkley
        {
433
          Vector extendedFields = new Vector(qspec.getReturnFieldList());
434
          Vector results = new Vector();
435 465 berkley
          Enumeration keylist = docListResult.keys();
436
          StringBuffer doclist = new StringBuffer();
437 1361 tao
          Hashtable parentidList = new Hashtable();
438
          Hashtable returnFieldValue = new Hashtable();
439 465 berkley
          while(keylist.hasMoreElements())
440
          {
441
            doclist.append("'");
442
            doclist.append((String)keylist.nextElement());
443
            doclist.append("',");
444
          }
445 1445 tao
          if (doclist.length() > 0)
446
          {
447
            Hashtable controlPairs = new Hashtable();
448
            double extendedQueryStart = System.currentTimeMillis()/1000;
449 834 jones
            doclist.deleteCharAt(doclist.length()-1); //remove the last comma
450 1445 tao
            // check if user has permission to see the return field data
451
            String accessControlSQL = qspec.
452
                        printAccessControlSQLForReturnField(doclist.toString());
453
            pstmt = dbconn.prepareStatement(accessControlSQL);
454
            //increase dbconnection usage count
455
            dbconn.increaseUsageCount(1);
456
            pstmt.execute();
457
            rs = pstmt.getResultSet();
458
            tableHasRows = rs.next();
459
            while(tableHasRows)
460
            {
461
              long startNodeId = rs.getLong(1);
462
              long endNodeId = rs.getLong(2);
463
              controlPairs.put(new Long(startNodeId), new Long(endNodeId));
464 1450 tao
              tableHasRows = rs.next();
465 1445 tao
            }
466
467
            double extendedAccessQueryEnd = System.currentTimeMillis()/1000;
468
            MetaCatUtil.debugMessage("Time for execute access extended query: "
469
                              +(extendedAccessQueryEnd-extendedQueryStart), 30);
470
471 1448 tao
            String extendedQuery = qspec.printExtendedSQL(doclist.toString(),
472
                                                          controlPairs);
473 1353 tao
            MetaCatUtil.debugMessage("Extended query: "+ extendedQuery, 30);
474 1297 tao
            pstmt = dbconn.prepareStatement(extendedQuery);
475 1217 tao
            //increase dbconnection usage count
476
            dbconn.increaseUsageCount(1);
477 834 jones
            pstmt.execute();
478
            rs = pstmt.getResultSet();
479 1297 tao
            double extendedQueryEnd = System.currentTimeMillis()/1000;
480
            MetaCatUtil.debugMessage("Time for execute extended query: "
481
                                    +(extendedQueryEnd-extendedQueryStart), 30);
482 401 berkley
            tableHasRows = rs.next();
483 834 jones
            while(tableHasRows)
484 401 berkley
            {
485 1361 tao
              ReturnFieldValue returnValue = new ReturnFieldValue();
486 834 jones
              docid = rs.getString(1).trim();
487
              fieldname = rs.getString(2);
488
              fielddata = rs.getString(3);
489 1630 tao
              fielddata = MetaCatUtil.normalize(fielddata);
490
491 1361 tao
              String parentId = rs.getString(4);
492
493
              StringBuffer value = new StringBuffer();
494
              if (!parentidList.containsKey(parentId))
495
              {
496
                // don't need to merger nodedata
497
                value.append("<param name=\"");
498
                value.append(fieldname);
499
                value.append("\">");
500
                value.append(fielddata);
501
                value.append("</param>");
502
                //set returnvalue
503
                returnValue.setDocid(docid);
504
                returnValue.setFieldValue(fielddata);
505
                returnValue.setXMLFieldValue(value.toString());
506
                // Store it in hastable
507
                parentidList.put(parentId, returnValue);
508
              }
509
              else
510
              {
511
                // need to merge nodedata if they have same parent id ant
512
                // node type is text
513
                fielddata = (String)((ReturnFieldValue)
514
                       parentidList.get(parentId)).getFieldValue() +  fielddata;
515
                value.append("<param name=\"");
516
                value.append(fieldname);
517
                value.append("\">");
518
                value.append(fielddata);
519
                value.append("</param>");
520
                returnValue.setDocid(docid);
521
                returnValue.setFieldValue(fielddata);
522
                returnValue.setXMLFieldValue(value.toString());
523
                // remove the old return value from paretnidList
524
                parentidList.remove(parentId);
525
                // store the new return value in parentidlit
526
                parentidList.put(parentId, returnValue);
527
              }
528
               tableHasRows = rs.next();
529
            }//while
530
            rs.close();
531
            pstmt.close();
532 1353 tao
533 1361 tao
            // put the merger node data info into doclistReult
534
            Enumeration xmlFieldValue = parentidList.elements();
535
            while( xmlFieldValue.hasMoreElements() )
536
            {
537
              ReturnFieldValue object = (ReturnFieldValue)
538
                                         xmlFieldValue.nextElement();
539
              docid = object.getDocid();
540 834 jones
              if (docListResult.containsKey(docid))
541
              {
542 1361 tao
                  String removedelement = (String)docListResult.remove(docid);
543
                  docListResult.put(docid, removedelement +
544
                                    object.getXMLFieldValue());
545 834 jones
              }
546
              else
547
              {
548 1361 tao
                  docListResult.put(docid, object.getXMLFieldValue());
549 834 jones
              }
550 1361 tao
            }//while
551 1297 tao
            double docListResultEnd = System.currentTimeMillis()/1000;
552
            MetaCatUtil.debugMessage("Time for prepare doclistresult after"+
553
                                      " execute extended query: "
554
                                    +(docListResultEnd-extendedQueryEnd), 30);
555 1353 tao
556 1361 tao
557 1353 tao
            // get attribures return
558
            docListResult = getAttributeValueForReturn
559
                                      (qspec,docListResult, doclist.toString());
560
          }//if doclist lenght is great than zero
561
562
        }//if has extended query
563 818 berkley
564 1353 tao
565 465 berkley
        //this loop adds the relation data to the resultdoc
566
        //this code might be able to be added to the backtracking code above
567 1297 tao
        double startRelation = System.currentTimeMillis()/1000;
568 465 berkley
        Enumeration docidkeys = docListResult.keys();
569
        while(docidkeys.hasMoreElements())
570 453 berkley
        {
571 602 berkley
          //String connstring = "metacat://"+util.getOption("server")+"?docid=";
572
          String connstring = "%docid=";
573 465 berkley
          String docidkey = (String)docidkeys.nextElement();
574 743 jones
          pstmt = dbconn.prepareStatement(qspec.printRelationSQL(docidkey));
575 465 berkley
          pstmt.execute();
576
          rs = pstmt.getResultSet();
577
          tableHasRows = rs.next();
578
          while(tableHasRows)
579
          {
580
            String sub = rs.getString(1);
581
            String rel = rs.getString(2);
582
            String obj = rs.getString(3);
583 489 berkley
            String subDT = rs.getString(4);
584
            String objDT = rs.getString(5);
585
586 894 berkley
            document = new StringBuffer();
587
            document.append("<triple>");
588
            document.append("<subject>").append(MetaCatUtil.normalize(sub));
589
            document.append("</subject>");
590
            if ( subDT != null ) {
591
              document.append("<subjectdoctype>").append(subDT);
592
              document.append("</subjectdoctype>");
593
            }
594 940 tao
            document.append("<relationship>").
595
                                          append(MetaCatUtil.normalize(rel));
596 894 berkley
            document.append("</relationship>");
597
            document.append("<object>").append(MetaCatUtil.normalize(obj));
598
            document.append("</object>");
599
            if ( objDT != null ) {
600
              document.append("<objectdoctype>").append(objDT);
601
              document.append("</objectdoctype>");
602
            }
603
            document.append("</triple>");
604
605
            String removedelement = (String)docListResult.remove(docidkey);
606
            docListResult.put(docidkey, removedelement +
607
                              document.toString());
608 465 berkley
            tableHasRows = rs.next();
609 453 berkley
          }
610 667 berkley
          rs.close();
611
          pstmt.close();
612 453 berkley
        }
613 1297 tao
        double endRelation = System.currentTimeMillis()/1000;
614
        MetaCatUtil.debugMessage("Time for adding relation to docListResult: "+
615
                                (endRelation-startRelation), 30);
616 667 berkley
617 155 jones
      } catch (SQLException e) {
618 667 berkley
        System.err.println("SQL Error in DBQuery.findDocuments: " +
619
                           e.getMessage());
620
      } catch (Exception ee) {
621 800 jones
        System.err.println("Exception in DBQuery.findDocuments: " +
622 667 berkley
                           ee.getMessage());
623 800 jones
        ee.printStackTrace(System.err);
624 155 jones
      }
625 1217 tao
      finally
626
      {
627 667 berkley
        try
628
        {
629 1217 tao
          pstmt.close();
630
        }//try
631
        catch (SQLException sqlE)
632 667 berkley
        {
633 1217 tao
          MetaCatUtil.debugMessage("Error in DBQuery.findDocuments: "
634
                                      +sqlE.getMessage(), 30);
635
        }//catch
636
        finally
637
        {
638
          DBConnectionPool.returnDBConnection(dbconn, serialNumber);
639
        }//finally
640
      }//finally
641 423 berkley
    //System.out.println("docListResult: ");
642
    //System.out.println(docListResult.toString());
643 155 jones
    return docListResult;
644
  }
645 1303 tao
  /*
646 1353 tao
   * A method to return search result after running a query which return
647
   * field have attribue
648
   */
649
  private Hashtable getAttributeValueForReturn(QuerySpecification squery,
650
                                               Hashtable docInformationList,
651
                                               String docList)
652
  {
653
    StringBuffer XML = null;
654
    String sql = null;
655
    DBConnection dbconn = null;
656
    PreparedStatement pstmt = null;
657
    ResultSet rs = null;
658
    int serialNumber = -1;
659
    boolean tableHasRows =false;
660
661
    //check the parameter
662
    if (squery == null || docList==null || docList.length() <0)
663
    {
664
      return docInformationList;
665
    }
666
667
    // if has attribute as return field
668
    if (squery.containAttributeReturnField())
669
    {
670
      sql = squery.printAttributeQuery(docList);
671
      try
672
      {
673
        dbconn=DBConnectionPool.getDBConnection("DBQuery.getAttributeValue");
674
        serialNumber=dbconn.getCheckOutSerialNumber();
675
        pstmt = dbconn.prepareStatement(sql);
676
        pstmt.execute();
677
        rs = pstmt.getResultSet();
678
        tableHasRows = rs.next();
679
        while(tableHasRows)
680
        {
681
          String docid = rs.getString(1).trim();
682
          String fieldname = rs.getString(2);
683
          String fielddata = rs.getString(3);
684
          String attirbuteName = rs.getString(4);
685
          XML = new StringBuffer();
686
687
          XML.append("<param name=\"");
688
          XML.append(fieldname);
689
          XML.append(QuerySpecification.ATTRIBUTESYMBOL);
690
          XML.append(attirbuteName);
691
          XML.append("\">");
692
          XML.append(fielddata);
693
          XML.append("</param>");
694
          tableHasRows = rs.next();
695
696
          if (docInformationList.containsKey(docid))
697
          {
698
            String removedelement = (String)docInformationList.remove(docid);
699
            docInformationList.put(docid, removedelement + XML.toString());
700
          }
701
          else
702
          {
703
            docInformationList.put(docid, XML.toString());
704
          }
705
        }//while
706
        rs.close();
707
        pstmt.close();
708
      }
709
      catch(Exception se)
710
      {
711
        MetaCatUtil.debugMessage("Error in DBQuery.getAttributeValue1: "
712
                                      +se.getMessage(), 30);
713
      }
714
      finally
715
      {
716
        try
717
        {
718
          pstmt.close();
719
        }//try
720
        catch (SQLException sqlE)
721
        {
722
          MetaCatUtil.debugMessage("Error in DBQuery.getAttributeValue2: "
723
                                      +sqlE.getMessage(), 30);
724
        }//catch
725
        finally
726
        {
727
          DBConnectionPool.returnDBConnection(dbconn, serialNumber);
728
        }//finally
729
      }//finally
730
    }//if
731
    return docInformationList;
732
733
  }
734
735
736
  /*
737 1303 tao
   * A method to create a query to get owner's docid list
738
   */
739
  private String getOwnerQuery(String owner)
740
  {
741
    StringBuffer self = new StringBuffer();
742
743
    self.append("SELECT docid,docname,doctype,");
744
    self.append("date_created, date_updated, rev ");
745
    self.append("FROM xml_documents WHERE docid IN (");
746
    self.append("(");
747
    self.append("SELECT DISTINCT docid FROM xml_nodes WHERE \n");
748
    self.append("nodedata LIKE '%%%' ");
749
    self.append(") \n");
750
    self.append(") ");
751
    self.append(" AND (");
752
    self.append(" user_owner = '" + owner + "'");
753
    self.append(") ");
754
    return self.toString();
755
  }
756 342 berkley
  /**
757 436 berkley
   * returns a string array of the contents of a particular node.
758
   * If the node appears more than once, the contents are returned
759
   * in the order in which they appearred in the document.
760
   * @param nodename the name or path of the particular node.
761
   * @param docid the docid of the document you want the node from.
762
   */
763 1217 tao
  public static Object[] getNodeContent(String nodename, String docid)
764 436 berkley
  {
765 1217 tao
    DBConnection dbconn = null;
766
    int serialNumber = -1;
767 436 berkley
    StringBuffer query = new StringBuffer();
768
    Vector result = new Vector();
769 667 berkley
    PreparedStatement pstmt = null;
770 436 berkley
    query.append("select nodedata from xml_nodes where parentnodeid in ");
771
    query.append("(select nodeid from xml_index where path like '");
772
    query.append(nodename);
773
    query.append("' and docid like '").append(docid).append("')");
774
    try
775
    {
776 1217 tao
      dbconn=DBConnectionPool.getDBConnection("DBQuery.getNodeContent");
777
        serialNumber=dbconn.getCheckOutSerialNumber();
778
      pstmt = dbconn.prepareStatement(query.toString());
779 436 berkley
780
      // Execute the SQL query using the JDBC connection
781
      pstmt.execute();
782
      ResultSet rs = pstmt.getResultSet();
783
      boolean tableHasRows = rs.next();
784
      while (tableHasRows)
785
      {
786
        result.add(rs.getString(1));
787 1297 tao
        //System.out.println(rs.getString(1));
788 436 berkley
        tableHasRows = rs.next();
789
      }
790
    }
791
    catch (SQLException e)
792
    {
793 675 berkley
      System.err.println("Error in DBQuery.getNodeContent: " + e.getMessage());
794 667 berkley
    } finally {
795
      try
796
      {
797
        pstmt.close();
798
      }
799 1217 tao
      catch(SQLException sqle)
800
      {}
801
      finally
802
      {
803
        DBConnectionPool.returnDBConnection(dbconn, serialNumber);
804
      }
805
806 667 berkley
    }
807 436 berkley
    return result.toArray();
808
  }
809
810
  /**
811 342 berkley
   * format a structured query as an XML document that conforms
812
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
813
   * structured query engine
814
   *
815 743 jones
   * @param params The list of parameters that should be included in the query
816 342 berkley
   */
817 372 berkley
  public static String createSQuery(Hashtable params)
818 350 berkley
  {
819
    StringBuffer query = new StringBuffer();
820 342 berkley
    Enumeration elements;
821
    Enumeration keys;
822 743 jones
    String filterDoctype = null;
823 372 berkley
    String casesensitive = null;
824
    String searchmode = null;
825 342 berkley
    Object nextkey;
826
    Object nextelement;
827 350 berkley
    //add the xml headers
828
    query.append("<?xml version=\"1.0\"?>\n");
829 743 jones
    query.append("<pathquery version=\"1.0\">\n");
830
831
    if (params.containsKey("meta_file_id"))
832 342 berkley
    {
833 743 jones
      query.append("<meta_file_id>");
834 342 berkley
      query.append( ((String[])params.get("meta_file_id"))[0]);
835 535 jones
      query.append("</meta_file_id>");
836 342 berkley
    }
837 350 berkley
838 743 jones
    if (params.containsKey("returndoctype"))
839 372 berkley
    {
840 744 jones
      String[] returnDoctypes = ((String[])params.get("returndoctype"));
841
      for(int i=0; i<returnDoctypes.length; i++)
842
      {
843
        String doctype = (String)returnDoctypes[i];
844
845
        if (!doctype.equals("any") &&
846
            !doctype.equals("ANY") &&
847
            !doctype.equals("") )
848
        {
849
          query.append("<returndoctype>").append(doctype);
850
          query.append("</returndoctype>");
851
        }
852
      }
853 372 berkley
    }
854 744 jones
855 743 jones
    if (params.containsKey("filterdoctype"))
856
    {
857
      String[] filterDoctypes = ((String[])params.get("filterdoctype"));
858
      for(int i=0; i<filterDoctypes.length; i++)
859
      {
860
        query.append("<filterdoctype>").append(filterDoctypes[i]);
861
        query.append("</filterdoctype>");
862
      }
863
    }
864 372 berkley
865 743 jones
    if (params.containsKey("returnfield"))
866 401 berkley
    {
867
      String[] returnfield = ((String[])params.get("returnfield"));
868
      for(int i=0; i<returnfield.length; i++)
869
      {
870
        query.append("<returnfield>").append(returnfield[i]);
871
        query.append("</returnfield>");
872
      }
873
    }
874
875 743 jones
    if (params.containsKey("owner"))
876 535 jones
    {
877
      String[] owner = ((String[])params.get("owner"));
878
      for(int i=0; i<owner.length; i++)
879
      {
880
        query.append("<owner>").append(owner[i]);
881
        query.append("</owner>");
882
      }
883
    }
884
885 743 jones
    if (params.containsKey("site"))
886 535 jones
    {
887
      String[] site = ((String[])params.get("site"));
888
      for(int i=0; i<site.length; i++)
889
      {
890
        query.append("<site>").append(site[i]);
891
        query.append("</site>");
892
      }
893
    }
894
895 350 berkley
    //allows the dynamic switching of boolean operators
896 743 jones
    if (params.containsKey("operator"))
897 350 berkley
    {
898
      query.append("<querygroup operator=\"" +
899 535 jones
                ((String[])params.get("operator"))[0] + "\">");
900 350 berkley
    }
901
    else
902
    { //the default operator is UNION
903
      query.append("<querygroup operator=\"UNION\">");
904
    }
905 535 jones
906 743 jones
    if (params.containsKey("casesensitive"))
907 372 berkley
    {
908
      casesensitive = ((String[])params.get("casesensitive"))[0];
909
    }
910
    else
911
    {
912
      casesensitive = "false";
913
    }
914
915 743 jones
    if (params.containsKey("searchmode"))
916 372 berkley
    {
917
      searchmode = ((String[])params.get("searchmode"))[0];
918
    }
919
    else
920
    {
921
      searchmode = "contains";
922
    }
923 535 jones
924 342 berkley
    //anyfield is a special case because it does a
925
    //free text search.  It does not have a <pathexpr>
926 350 berkley
    //tag.  This allows for a free text search within the structured
927
    //query.  This is useful if the INTERSECT operator is used.
928 743 jones
    if (params.containsKey("anyfield"))
929 342 berkley
    {
930 372 berkley
       String[] anyfield = ((String[])params.get("anyfield"));
931
       //allow for more than one value for anyfield
932
       for(int i=0; i<anyfield.length; i++)
933 350 berkley
       {
934 743 jones
         if (!anyfield[i].equals(""))
935 372 berkley
         {
936
           query.append("<queryterm casesensitive=\"" + casesensitive +
937
                        "\" " + "searchmode=\"" + searchmode + "\"><value>" +
938 535 jones
                        anyfield[i] +
939
                        "</value></queryterm>");
940 372 berkley
         }
941 350 berkley
       }
942 342 berkley
    }
943 535 jones
944 342 berkley
    //this while loop finds the rest of the parameters
945
    //and attempts to query for the field specified
946
    //by the parameter.
947
    elements = params.elements();
948
    keys = params.keys();
949
    while(keys.hasMoreElements() && elements.hasMoreElements())
950
    {
951
      nextkey = keys.nextElement();
952 535 jones
      nextelement = elements.nextElement();
953 372 berkley
954 535 jones
      //make sure we aren't querying for any of these
955
      //parameters since the are already in the query
956 342 berkley
      //in one form or another.
957 743 jones
      if (!nextkey.toString().equals("returndoctype") &&
958
         !nextkey.toString().equals("filterdoctype")  &&
959 535 jones
         !nextkey.toString().equals("action")  &&
960
         !nextkey.toString().equals("qformat") &&
961
         !nextkey.toString().equals("anyfield") &&
962 401 berkley
         !nextkey.toString().equals("returnfield") &&
963 535 jones
         !nextkey.toString().equals("owner") &&
964
         !nextkey.toString().equals("site") &&
965
         !nextkey.toString().equals("operator") )
966
      {
967 372 berkley
        //allow for more than value per field name
968
        for(int i=0; i<((String[])nextelement).length; i++)
969
        {
970 743 jones
          if (!((String[])nextelement)[i].equals(""))
971 372 berkley
          {
972
            query.append("<queryterm casesensitive=\"" + casesensitive +"\" " +
973 535 jones
                         "searchmode=\"" + searchmode + "\">" +
974
                         "<value>" +
975 372 berkley
                         //add the query value
976 535 jones
                         ((String[])nextelement)[i] +
977
                         "</value><pathexpr>" +
978
                         //add the path to query by
979 372 berkley
                         nextkey.toString() +
980
                         "</pathexpr></queryterm>");
981
          }
982
        }
983 535 jones
      }
984 342 berkley
    }
985
    query.append("</querygroup></pathquery>");
986 350 berkley
    //append on the end of the xml and return the result as a string
987 342 berkley
    return query.toString();
988
  }
989
990 181 jones
  /**
991
   * format a simple free-text value query as an XML document that conforms
992
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
993
   * structured query engine
994
   *
995
   * @param value the text string to search for in the xml catalog
996
   * @param doctype the type of documents to include in the result set -- use
997
   *        "any" or "ANY" for unfiltered result sets
998
   */
999
   public static String createQuery(String value, String doctype) {
1000
     StringBuffer xmlquery = new StringBuffer();
1001
     xmlquery.append("<?xml version=\"1.0\"?>\n");
1002
     xmlquery.append("<pathquery version=\"1.0\">");
1003
1004
     if (!doctype.equals("any") && !doctype.equals("ANY")) {
1005
       xmlquery.append("<returndoctype>");
1006
       xmlquery.append(doctype).append("</returndoctype>");
1007
     }
1008
1009
     xmlquery.append("<querygroup operator=\"UNION\">");
1010 350 berkley
     //chad added - 8/14
1011
     //the if statement allows a query to gracefully handle a null
1012
     //query.  Without this if a nullpointerException is thrown.
1013 743 jones
     if (!value.equals(""))
1014 350 berkley
     {
1015
       xmlquery.append("<queryterm casesensitive=\"false\" ");
1016
       xmlquery.append("searchmode=\"contains\">");
1017
       xmlquery.append("<value>").append(value).append("</value>");
1018
       xmlquery.append("</queryterm>");
1019
     }
1020 181 jones
     xmlquery.append("</querygroup>");
1021
     xmlquery.append("</pathquery>");
1022
1023
1024
     return (xmlquery.toString());
1025
   }
1026
1027
  /**
1028
   * format a simple free-text value query as an XML document that conforms
1029
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
1030
   * structured query engine
1031
   *
1032
   * @param value the text string to search for in the xml catalog
1033
   */
1034
   public static String createQuery(String value) {
1035
     return createQuery(value, "any");
1036
   }
1037 441 bojilova
1038 570 bojilova
  /**
1039
    * Check for "READ" permission on @docid for @user and/or @group
1040
    * from DB connection
1041
    */
1042 1217 tao
  private boolean hasPermission (String user,
1043 802 bojilova
                                  String[] groups, String docid )
1044 957 tao
                  throws SQLException, Exception
1045 570 bojilova
  {
1046 802 bojilova
    // Check for READ permission on @docid for @user and/or @groups
1047 1427 tao
   PermissionController controller = new PermissionController(docid);
1048
   return controller.hasPermission(user,groups,
1049
                                 AccessControlInterface.READSTRING);
1050 441 bojilova
  }
1051 940 tao
1052
  /**
1053
    * Get all docIds list for a data packadge
1054
    * @param dataPackageDocid, the string in docId field of xml_relation table
1055
    */
1056
  private Vector getCurrentDocidListForDataPackage(String dataPackageDocid)
1057
  {
1058 1217 tao
    DBConnection dbConn = null;
1059
    int serialNumber = -1;
1060 940 tao
    Vector docIdList=new Vector();//return value
1061 1217 tao
    PreparedStatement pStmt = null;
1062 940 tao
    ResultSet rs=null;
1063
    String docIdInSubjectField=null;
1064
    String docIdInObjectField=null;
1065 1292 tao
1066
    // Check the parameter
1067
    if (dataPackageDocid == null || dataPackageDocid.equals(""))
1068
    {
1069
      return docIdList;
1070
    }//if
1071
1072 940 tao
    //the query stirng
1073
    String query="SELECT subject, object from xml_relation where docId = ?";
1074
    try
1075
    {
1076 1217 tao
      dbConn=DBConnectionPool.
1077
                  getDBConnection("DBQuery.getCurrentDocidListForDataPackage");
1078
      serialNumber=dbConn.getCheckOutSerialNumber();
1079
      pStmt=dbConn.prepareStatement(query);
1080 940 tao
      //bind the value to query
1081
      pStmt.setString(1, dataPackageDocid);
1082
1083
      //excute the query
1084
      pStmt.execute();
1085
      //get the result set
1086
      rs=pStmt.getResultSet();
1087
      //process the result
1088
      while (rs.next())
1089
      {
1090
        //In order to get the whole docIds in a data packadge,
1091
        //we need to put the docIds of subject and object field in xml_relation
1092
        //into the return vector
1093
        docIdInSubjectField=rs.getString(1);//the result docId in subject field
1094
        docIdInObjectField=rs.getString(2);//the result docId in object field
1095
1096
        //don't put the duplicate docId into the vector
1097
        if (!docIdList.contains(docIdInSubjectField))
1098
        {
1099
          docIdList.add(docIdInSubjectField);
1100
        }
1101
1102
        //don't put the duplicate docId into the vector
1103
        if (!docIdList.contains(docIdInObjectField))
1104
        {
1105
          docIdList.add(docIdInObjectField);
1106
        }
1107
      }//while
1108
      //close the pStmt
1109
      pStmt.close();
1110
    }//try
1111
    catch (SQLException e)
1112
    {
1113 1292 tao
      MetaCatUtil.debugMessage("Error in getDocidListForDataPackage: "
1114 1096 tao
                            +e.getMessage(), 30);
1115 940 tao
    }//catch
1116 1217 tao
    finally
1117
    {
1118
      try
1119
      {
1120
        pStmt.close();
1121
      }//try
1122
      catch (SQLException ee)
1123
      {
1124 1292 tao
        MetaCatUtil.debugMessage("Error in getDocidListForDataPackage: "
1125 1217 tao
                            +ee.getMessage(), 30);
1126
      }//catch
1127
      finally
1128
      {
1129
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1130
      }//fianlly
1131
    }//finally
1132 940 tao
    return docIdList;
1133
  }//getCurrentDocidListForDataPackadge()
1134
1135
  /**
1136
   * Get all docIds list for a data packadge
1137
   * @param dataPackageDocid, the string in docId field of xml_relation table
1138
   */
1139
  private Vector getOldVersionDocidListForDataPackage(String dataPackageDocid)
1140
  {
1141 441 bojilova
1142 940 tao
    Vector docIdList=new Vector();//return value
1143
    Vector tripleList=null;
1144
    String xml=null;
1145 1292 tao
1146
     // Check the parameter
1147
    if (dataPackageDocid == null || dataPackageDocid.equals(""))
1148
    {
1149
      return docIdList;
1150
    }//if
1151
1152
    try
1153
    {
1154 1217 tao
      //initial a documentImpl object
1155
      DocumentImpl packageDocument =
1156
                  new DocumentImpl(dataPackageDocid);
1157
      //transfer to documentImpl object to string
1158
      xml=packageDocument.toString();
1159 940 tao
1160 1217 tao
      //create a tripcollection object
1161
      TripleCollection tripleForPackage = new
1162 940 tao
                                     TripleCollection(new StringReader(xml));
1163 1217 tao
      //get the vetor of triples
1164
      tripleList=tripleForPackage.getCollection();
1165 940 tao
1166 1217 tao
      for (int i= 0; i<tripleList.size(); i++)
1167 940 tao
      {
1168 1217 tao
        //put subject docid  into docIdlist without duplicate
1169
        if (!docIdList.contains(((Triple)tripleList.elementAt(i)).getSubject()))
1170
        {
1171
          //put subject docid  into docIdlist
1172
          docIdList.add(((Triple)tripleList.get(i)).getSubject());
1173
        }
1174
        //put object docid into docIdlist without duplicate
1175
        if (!docIdList.contains(((Triple)tripleList.elementAt(i)).getObject()))
1176
        {
1177
          docIdList.add(((Triple)(tripleList.get(i))).getObject());
1178
        }
1179
      }//for
1180 1292 tao
    }//try
1181
    catch (Exception e)
1182
    {
1183
      MetaCatUtil.debugMessage("Error in getOldVersionAllDocumentImpl: "
1184
                            +e.getMessage(), 30);
1185
    }//catch
1186 1217 tao
1187 1292 tao
    // return result
1188 940 tao
    return docIdList;
1189
  }//getDocidListForPackageInXMLRevisions()
1190
1191
  /**
1192
   * Check if the docId is a data packadge id. If the id is a data packadage
1193
   *id, it should be store in the docId fields in xml_relation table.
1194
   *So we can use a query to get the entries which the docId equals the given
1195
   *value. If the result is null. The docId is not a packadge id. Otherwise,
1196
   * it is.
1197
   * @param docId, the id need to be checked
1198
   */
1199
  private boolean isDataPackageId(String docId)
1200
  {
1201
    boolean result=false;
1202 1217 tao
    PreparedStatement pStmt = null;
1203 940 tao
    ResultSet rs=null;
1204
    String query="SELECT docId from xml_relation where docId = ?";
1205 1217 tao
    DBConnection dbConn = null;
1206
    int serialNumber = -1;
1207 940 tao
    try
1208
    {
1209 1217 tao
      dbConn=DBConnectionPool.
1210
                  getDBConnection("DBQuery.isDataPackageId");
1211
      serialNumber=dbConn.getCheckOutSerialNumber();
1212
      pStmt=dbConn.prepareStatement(query);
1213 940 tao
      //bind the value to query
1214
      pStmt.setString(1, docId);
1215
      //execute the query
1216
      pStmt.execute();
1217
      rs=pStmt.getResultSet();
1218
      //process the result
1219
      if (rs.next()) //There are some records for the id in docId fields
1220
      {
1221
        result=true;//It is a data packadge id
1222
      }
1223
      pStmt.close();
1224
    }//try
1225
    catch (SQLException e)
1226
    {
1227 1217 tao
      util.debugMessage("Error in isDataPackageId: "
1228 1096 tao
                            +e.getMessage(), 30);
1229 940 tao
    }
1230 1217 tao
    finally
1231
    {
1232
      try
1233
      {
1234
        pStmt.close();
1235
      }//try
1236
      catch (SQLException ee)
1237
      {
1238
        MetaCatUtil.debugMessage("Error in isDataPackageId: "
1239
                                                        + ee.getMessage(), 30);
1240
      }//catch
1241
      finally
1242
      {
1243
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1244
      }//finally
1245
    }//finally
1246 940 tao
    return result;
1247
  }//isDataPackageId()
1248
1249
  /**
1250 945 tao
   * Check if the user has the permission to export data package
1251
   * @param conn, the connection
1252
   * @param docId, the id need to be checked
1253
   * @param user, the name of user
1254
   * @param groups, the user's group
1255
   */
1256 1217 tao
   private boolean hasPermissionToExportPackage(String docId,
1257 945 tao
                                        String user, String[] groups)
1258
                   throws Exception
1259
   {
1260 1217 tao
     //DocumentImpl doc=new DocumentImpl(conn,docId);
1261
     return DocumentImpl.hasReadPermission(user, groups,docId);
1262 945 tao
   }
1263
1264
  /**
1265 940 tao
   *Get the current Rev for a docid in xml_documents table
1266
   * @param docId, the id need to get version numb
1267
   * If the return value is -5, means no value in rev field for this docid
1268
   */
1269
  private int getCurrentRevFromXMLDoumentsTable(String docId)
1270 1292 tao
                                                throws SQLException
1271 940 tao
  {
1272
    int rev=-5;
1273 1217 tao
    PreparedStatement pStmt = null;
1274 940 tao
    ResultSet rs=null;
1275
    String query="SELECT rev from xml_documents where docId = ?";
1276 1217 tao
    DBConnection dbConn=null;
1277
    int serialNumber = -1;
1278 940 tao
    try
1279
    {
1280 1217 tao
      dbConn=DBConnectionPool.
1281
                  getDBConnection("DBQuery.getCurrentRevFromXMLDocumentsTable");
1282
      serialNumber=dbConn.getCheckOutSerialNumber();
1283
      pStmt=dbConn.prepareStatement(query);
1284 940 tao
      //bind the value to query
1285
      pStmt.setString(1, docId);
1286
      //execute the query
1287
      pStmt.execute();
1288
      rs=pStmt.getResultSet();
1289
      //process the result
1290
      if (rs.next()) //There are some records for rev
1291
      {
1292
        rev=rs.getInt(1);;//It is the version for given docid
1293
      }
1294
      else
1295
      {
1296
        rev=-5;
1297
      }
1298 1292 tao
1299 940 tao
    }//try
1300
    catch (SQLException e)
1301
    {
1302 1292 tao
      MetaCatUtil.debugMessage("Error in getCurrentRevFromXMLDoumentsTable: "
1303 1096 tao
                            +e.getMessage(), 30);
1304 1292 tao
      throw e;
1305 1217 tao
    }//catch
1306
    finally
1307
    {
1308
      try
1309
      {
1310
        pStmt.close();
1311
      }//try
1312
      catch (SQLException ee)
1313
      {
1314
        MetaCatUtil.debugMessage("Error in getCurrentRevFromXMLDoumentsTable: "
1315
                                  +ee.getMessage(), 30);
1316
      }//catch
1317
      finally
1318
      {
1319
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1320
      }//finally
1321
    }//finally
1322 940 tao
    return rev;
1323
  }//getCurrentRevFromXMLDoumentsTable
1324
1325
 /**
1326
   *put a doc into a zip output stream
1327
   *@param docImpl, docmentImpl object which will be sent to zip output stream
1328
   *@param zipOut, zip output stream which the docImpl will be put
1329
   *@param packageZipEntry, the zip entry name for whole package
1330
   */
1331
  private void addDocToZipOutputStream(DocumentImpl docImpl,
1332
                                ZipOutputStream zipOut, String packageZipEntry)
1333
               throws ClassNotFoundException, IOException, SQLException,
1334
                      McdbException, Exception
1335
  {
1336
    byte[] byteString = null;
1337
    ZipEntry zEntry = null;
1338
1339
    byteString = docImpl.toString().getBytes();
1340
    //use docId as the zip entry's name
1341
    zEntry = new ZipEntry(packageZipEntry+"/metadata/"+docImpl.getDocID());
1342
    zEntry.setSize(byteString.length);
1343
    zipOut.putNextEntry(zEntry);
1344
    zipOut.write(byteString, 0, byteString.length);
1345
    zipOut.closeEntry();
1346
1347
  }//addDocToZipOutputStream()
1348
1349
1350
  /**
1351 1292 tao
   * Transfer a docid vetor to a documentImpl vector. The documentImpl vetor
1352
   * only inlcudes current version. If a DocumentImple object
1353
   * couldn't find for a docid, then the String of this docid was added to vetor
1354
   * rather than DocumentImple object.
1355
   * @param docIdList, a vetor hold a docid list for a data package. In docid,
1356
   * there is not version number in it.
1357 940 tao
   */
1358
1359
  private Vector getCurrentAllDocumentImpl( Vector docIdList)
1360
                              throws McdbException,Exception
1361
  {
1362 1217 tao
    //Connection dbConn=null;
1363 940 tao
    Vector documentImplList=new Vector();
1364
    int rev=0;
1365
1366 1292 tao
    // Check the parameter
1367
    if (docIdList.isEmpty())
1368 940 tao
    {
1369 1292 tao
      return documentImplList;
1370
    }//if
1371
1372 940 tao
    //for every docid in vector
1373
    for (int i=0;i<docIdList.size();i++)
1374
    {
1375 1292 tao
      try
1376
      {
1377
        //get newest version for this docId
1378
        rev=getCurrentRevFromXMLDoumentsTable((String)docIdList.elementAt(i));
1379
1380
        // There is no record for this docId in xml_documents table
1381
        if (rev ==-5)
1382
        {
1383
          // Rather than put DocumentImple object, put a String Object(docid)
1384
          // into the documentImplList
1385
          documentImplList.add((String)docIdList.elementAt(i));
1386
          // Skip other code
1387
          continue;
1388
        }
1389 948 tao
1390 1292 tao
        String docidPlusVersion=((String)docIdList.elementAt(i))
1391 948 tao
                        +util.getOption("accNumSeparator")+rev;
1392 1292 tao
1393
1394
        //create new documentImpl object
1395
        DocumentImpl documentImplObject =
1396 1217 tao
                                    new DocumentImpl(docidPlusVersion);
1397 1292 tao
       //add them to vector
1398
        documentImplList.add(documentImplObject);
1399
      }//try
1400
      catch (Exception e)
1401
      {
1402
        MetaCatUtil.debugMessage("Error in getCurrentAllDocumentImpl: "
1403
                            +e.getMessage(), 30);
1404
        // continue the for loop
1405
        continue;
1406
      }
1407 940 tao
    }//for
1408
    return documentImplList;
1409
  }
1410
1411
  /**
1412 1292 tao
   * Transfer a docid vetor to a documentImpl vector. If a DocumentImple object
1413
   * couldn't find for a docid, then the String of this docid was added to vetor
1414
   * rather than DocumentImple object.
1415
   * @param docIdList, a vetor hold a docid list for a data package. In docid,
1416
   *t here is version number in it.
1417 940 tao
   */
1418
  private Vector getOldVersionAllDocumentImpl( Vector docIdList)
1419
  {
1420 1217 tao
    //Connection dbConn=null;
1421 940 tao
    Vector documentImplList=new Vector();
1422
    String siteCode=null;
1423
    String uniqueId=null;
1424
    int rev=0;
1425
1426 1292 tao
    // Check the parameter
1427
    if (docIdList.isEmpty())
1428 940 tao
    {
1429 1292 tao
      return documentImplList;
1430
    }//if
1431
1432 940 tao
    //for every docid in vector
1433
    for (int i=0;i<docIdList.size();i++)
1434
    {
1435
1436 948 tao
        String docidPlusVersion=(String)(docIdList.elementAt(i));
1437 1292 tao
1438
        try
1439
        {
1440
          //create new documentImpl object
1441
          DocumentImpl documentImplObject =
1442 1217 tao
                                    new DocumentImpl(docidPlusVersion);
1443 1292 tao
          //add them to vector
1444
          documentImplList.add(documentImplObject);
1445
        }//try
1446
        catch (McdbDocNotFoundException notFoundE)
1447
        {
1448
          MetaCatUtil.debugMessage("Error in DBQuery.getOldVersionAllDocument"+
1449
                                  "Imple" + notFoundE.getMessage(), 30);
1450
          // Rather than add a DocumentImple object into vetor, a String object
1451
          // - the doicd was added to the vector
1452
          documentImplList.add(docidPlusVersion);
1453
          // Continue the for loop
1454
          continue;
1455
        }//catch
1456
        catch (Exception e)
1457
        {
1458
          MetaCatUtil.debugMessage("Error in DBQuery.getOldVersionAllDocument"+
1459
                                  "Imple" + e.getMessage(), 30);
1460
          // Continue the for loop
1461
          continue;
1462
        }//catch
1463
1464 948 tao
1465 940 tao
    }//for
1466
    return documentImplList;
1467 1292 tao
  }//getOldVersionAllDocumentImple
1468
1469 940 tao
  /**
1470
   *put a data file into a zip output stream
1471
   *@param docImpl, docmentImpl object which will be sent to zip output stream
1472
   *@param zipOut, the zip output stream which the docImpl will be put
1473
   *@param packageZipEntry, the zip entry name for whole package
1474
   */
1475
  private void addDataFileToZipOutputStream(DocumentImpl docImpl,
1476
                                ZipOutputStream zipOut, String packageZipEntry)
1477
               throws ClassNotFoundException, IOException, SQLException,
1478
                      McdbException, Exception
1479
  {
1480
    byte[] byteString = null;
1481
    ZipEntry zEntry = null;
1482
    // this is data file; add file to zip
1483
    String filePath = util.getOption("datafilepath");
1484
    if (!filePath.endsWith("/"))
1485
    {
1486
      filePath += "/";
1487
    }
1488
    String fileName = filePath + docImpl.getDocID();
1489 963 berkley
    zEntry = new ZipEntry(packageZipEntry+"/data/"+docImpl.getDocID());
1490 940 tao
    zipOut.putNextEntry(zEntry);
1491
    FileInputStream fin = null;
1492
    try
1493
    {
1494
      fin = new FileInputStream(fileName);
1495
      byte[] buf = new byte[4 * 1024]; // 4K buffer
1496
      int b = fin.read(buf);
1497
      while (b != -1)
1498
      {
1499
        zipOut.write(buf, 0, b);
1500
        b = fin.read(buf);
1501
      }//while
1502
      zipOut.closeEntry();
1503
    }//try
1504
    catch (IOException ioe)
1505
    {
1506 1096 tao
      util.debugMessage("There is an exception: "+ioe.getMessage(), 30);
1507 940 tao
    }//catch
1508
  }//addDataFileToZipOutputStream()
1509
1510
  /**
1511
   *create a html summary for data package and put it into zip output stream
1512
   *@param docImplList, the documentImpl ojbects in data package
1513
   *@param zipOut, the zip output stream which the html should be put
1514
   *@param packageZipEntry, the zip entry name for whole package
1515
   */
1516
   private void addHtmlSummaryToZipOutputStream(Vector docImplList,
1517
                                ZipOutputStream zipOut, String packageZipEntry)
1518
                                           throws Exception
1519
  {
1520
    StringBuffer htmlDoc = new StringBuffer();
1521
    ZipEntry zEntry = null;
1522
    byte[] byteString=null;
1523
    InputStream source;
1524
    DBTransform xmlToHtml;
1525 1292 tao
1526 940 tao
    //create a DBTransform ojbect
1527 1217 tao
    xmlToHtml = new DBTransform();
1528 940 tao
    //head of html
1529
    htmlDoc.append("<html><head></head><body>");
1530
    for (int i=0; i<docImplList.size(); i++)
1531
    {
1532 1292 tao
      // If this String object, this means it is missed data file
1533
      if ((((docImplList.elementAt(i)).getClass()).toString())
1534
                                             .equals("class java.lang.String"))
1535
      {
1536
1537
        htmlDoc.append("<a href=\"");
1538
        String dataFileid =(String)docImplList.elementAt(i);
1539
        htmlDoc.append("./data/").append(dataFileid).append("\">");
1540
        htmlDoc.append("Data File: ");
1541
        htmlDoc.append(dataFileid).append("</a><br>");
1542
        htmlDoc.append("<br><hr><br>");
1543
1544
      }//if
1545
      else if ((((DocumentImpl)docImplList.elementAt(i)).getDoctype()).
1546 940 tao
                                                         compareTo("BIN")!=0)
1547
      { //this is an xml file so we can transform it.
1548
        //transform each file individually then concatenate all of the
1549
        //transformations together.
1550
1551
        //for metadata xml title
1552
        htmlDoc.append("<h2>");
1553
        htmlDoc.append(((DocumentImpl)docImplList.elementAt(i)).getDocID());
1554
        //htmlDoc.append(".");
1555
        //htmlDoc.append(((DocumentImpl)docImplList.elementAt(i)).getRev());
1556
        htmlDoc.append("</h2>");
1557
        //do the actual transform
1558
        StringWriter docString = new StringWriter();
1559
        xmlToHtml.transformXMLDocument(
1560
                        ((DocumentImpl)docImplList.elementAt(i)).toString(),
1561
           "-//NCEAS//eml-generic//EN", "-//W3C//HTML//EN", "html", docString);
1562
        htmlDoc.append(docString.toString());
1563
        htmlDoc.append("<br><br><hr><br><br>");
1564
      }//if
1565
      else
1566
      { //this is a data file so we should link to it in the html
1567
        htmlDoc.append("<a href=\"");
1568
        String dataFileid =((DocumentImpl)docImplList.elementAt(i)).getDocID();
1569
        htmlDoc.append("./data/").append(dataFileid).append("\">");
1570
        htmlDoc.append("Data File: ");
1571
        htmlDoc.append(dataFileid).append("</a><br>");
1572
        htmlDoc.append("<br><hr><br>");
1573
      }//else
1574
    }//for
1575
    htmlDoc.append("</body></html>");
1576
    byteString = htmlDoc.toString().getBytes();
1577
    zEntry = new ZipEntry(packageZipEntry+"/metadata.html");
1578
    zEntry.setSize(byteString.length);
1579
    zipOut.putNextEntry(zEntry);
1580
    zipOut.write(byteString, 0, byteString.length);
1581
    zipOut.closeEntry();
1582 1217 tao
    //dbConn.close();
1583 940 tao
1584
  }//addHtmlSummaryToZipOutputStream
1585
1586 945 tao
1587
1588 940 tao
  /**
1589
   * put a data packadge into a zip output stream
1590
   * @param docId, which the user want to put into zip output stream
1591
   * @param out, a servletoutput stream which the zip output stream will be put
1592
   * @param user, the username of the user
1593
   * @param groups, the group of the user
1594
   */
1595
  public ZipOutputStream getZippedPackage(String docIdString,
1596 1292 tao
        ServletOutputStream out, String user, String[] groups, String passWord)
1597 940 tao
                    throws ClassNotFoundException, IOException, SQLException,
1598
                      McdbException, NumberFormatException, Exception
1599
  {
1600
    ZipOutputStream zOut = null;
1601
    String elementDocid=null;
1602
    DocumentImpl docImpls=null;
1603 1217 tao
    //Connection dbConn = null;
1604 940 tao
    Vector docIdList=new Vector();
1605 945 tao
    Vector documentImplList=new Vector();
1606
    Vector htmlDocumentImplList=new Vector();
1607 940 tao
    String packageId=null;
1608
    String rootName="package";//the package zip entry name
1609
1610
    String docId=null;
1611
    int version=-5;
1612 1292 tao
    // Docid without revision
1613 940 tao
    docId=MetaCatUtil.getDocIdFromString(docIdString);
1614 1292 tao
    // revision number
1615 940 tao
    version=MetaCatUtil.getVersionFromString(docIdString);
1616
1617
    //check if the reqused docId is a data package id
1618 1356 tao
    if (!isDataPackageId(docId))
1619 940 tao
    {
1620 1356 tao
1621
      /*Exception e = new Exception("The request the doc id " +docIdString+
1622 940 tao
                                    " is not a data package id");
1623 1356 tao
      throw e;*/
1624
1625
1626
      //CB 1/6/03: if the requested docid is not a datapackage, we just zip
1627
      //up the single document and return the zip file.
1628
1629
      if(!hasPermissionToExportPackage(docId, user, groups))
1630
      {
1631
1632
        Exception e = new Exception("User " + user + " does not have permission"
1633
                         +" to export the data package " + docIdString);
1634
        throw e;
1635
      }
1636
1637
      docImpls=new DocumentImpl(docId);
1638
      //checking if the user has the permission to read the documents
1639
      if (docImpls.hasReadPermission(user,groups,docImpls.getDocID()))
1640
      {
1641
        zOut = new ZipOutputStream(out);
1642
        //if the docImpls is metadata
1643
        if ((docImpls.getDoctype()).compareTo("BIN")!=0)
1644
        {
1645
          //add metadata into zip output stream
1646
          addDocToZipOutputStream(docImpls, zOut, rootName);
1647
        }//if
1648
        else
1649
        {
1650
          //it is data file
1651
          addDataFileToZipOutputStream(docImpls, zOut, rootName);
1652
          htmlDocumentImplList.add(docImpls);
1653
        }//else
1654
      }//if
1655
1656
      zOut.finish(); //terminate the zip file
1657
      return zOut;
1658 940 tao
    }
1659 1292 tao
    // Check the permission of user
1660 1217 tao
    else if(!hasPermissionToExportPackage(docId, user, groups))
1661 945 tao
    {
1662 1292 tao
1663 945 tao
      Exception e = new Exception("User " + user + " does not have permission"
1664
                       +" to export the data package " + docIdString);
1665
      throw e;
1666
    }
1667 940 tao
    else //it is a packadge id
1668
    {
1669
      //store the package id
1670
      packageId=docId;
1671 1292 tao
      //get current version in database
1672
      int currentVersion = getCurrentRevFromXMLDoumentsTable(packageId);
1673
      //If it is for current version (-1 means user didn't specify revision)
1674
      if ((version ==-1)||version==currentVersion)
1675 940 tao
      {
1676
        //get current version number
1677 1292 tao
        version=currentVersion;
1678 940 tao
        //get package zip entry name
1679
        //it should be docId.revsion.package
1680
        rootName=packageId+util.getOption("accNumSeparator")+version+
1681
                                  util.getOption("accNumSeparator")+"package";
1682
        //get the whole id list for data packadge
1683
        docIdList=getCurrentDocidListForDataPackage(packageId);
1684
        //get the whole documentImple object
1685
        documentImplList=getCurrentAllDocumentImpl(docIdList);
1686
1687
      }//if
1688 1292 tao
      else if (version > currentVersion || version < -1)
1689
      {
1690
        throw new Exception ("The user specified docid: "+docId+"."+version
1691
                                              +" doesn't exist");
1692
      }//else if
1693 940 tao
      else  //for an old version
1694
      {
1695
1696
        rootName=docIdString+util.getOption("accNumSeparator")+"package";
1697
        //get the whole id list for data packadge
1698
        docIdList=getOldVersionDocidListForDataPackage(docIdString);
1699
1700
        //get the whole documentImple object
1701
        documentImplList=getOldVersionAllDocumentImpl(docIdList);
1702
      }//else
1703
1704 1292 tao
      // Make sure documentImplist is not empty
1705
      if (documentImplList.isEmpty())
1706
      {
1707
        throw new Exception ("Couldn't find component for data package: "
1708
                                              + packageId);
1709
      }//if
1710 940 tao
1711 1292 tao
1712
       zOut = new ZipOutputStream(out);
1713 940 tao
      //put every element into zip output stream
1714
      for (int i=0; i < documentImplList.size(); i++ )
1715
      {
1716 1292 tao
        // if the object in the vetor is String, this means we couldn't find
1717
        // the document locally, we need find it remote
1718
       if ((((documentImplList.elementAt(i)).getClass()).toString())
1719
                                             .equals("class java.lang.String"))
1720
        {
1721
          // Get String object from vetor
1722
          String documentId = (String) documentImplList.elementAt(i);
1723
          MetaCatUtil.debugMessage("docid: "+documentId, 30);
1724
          // Get doicd without revision
1725
          String docidWithoutRevision =
1726
                                     MetaCatUtil.getDocIdFromString(documentId);
1727
          MetaCatUtil.debugMessage("docidWithoutRevsion: "
1728
                                                     +docidWithoutRevision, 30);
1729
          // Get revision
1730
          String revision = MetaCatUtil.getRevisionStringFromString(documentId);
1731
          MetaCatUtil.debugMessage("revsion from docIdentifier: "+revision, 30);
1732
          // Zip entry string
1733
          String zipEntryPath = rootName+"/data/";
1734
          // Create a RemoteDocument object
1735
          RemoteDocument remoteDoc =
1736
                          new RemoteDocument(docidWithoutRevision,revision,user,
1737
                                                     passWord, zipEntryPath);
1738
          // Here we only read data file from remote metacat
1739
          String docType = remoteDoc.getDocType();
1740
          if (docType!=null)
1741
          {
1742
            if (docType.equals("BIN"))
1743
            {
1744
              // Put remote document to zip output
1745
              remoteDoc.readDocumentFromRemoteServerByZip(zOut);
1746
              // Add String object to htmlDocumentImplList
1747
              String elementInHtmlList = remoteDoc.getDocIdWithoutRevsion()+
1748
               MetaCatUtil.getOption("accNumSeparator")+remoteDoc.getRevision();
1749
              htmlDocumentImplList.add(elementInHtmlList);
1750
            }//if
1751
          }//if
1752
1753
        }//if
1754
        else
1755
        {
1756
          //create a docmentImpls object (represent xml doc) base on the docId
1757
          docImpls=(DocumentImpl)documentImplList.elementAt(i);
1758
          //checking if the user has the permission to read the documents
1759
          if (docImpls.hasReadPermission(user,groups,docImpls.getDocID()))
1760
          {
1761 948 tao
            //if the docImpls is metadata
1762 1292 tao
            if ((docImpls.getDoctype()).compareTo("BIN")!=0)
1763
            {
1764 948 tao
              //add metadata into zip output stream
1765
              addDocToZipOutputStream(docImpls, zOut, rootName);
1766
              //add the documentImpl into the vetor which will be used in html
1767
              htmlDocumentImplList.add(docImpls);
1768 953 tao
1769 1292 tao
            }//if
1770
            else
1771
            {
1772
              //it is data file
1773
              addDataFileToZipOutputStream(docImpls, zOut, rootName);
1774
              htmlDocumentImplList.add(docImpls);
1775
            }//else
1776 948 tao
          }//if
1777 1292 tao
        }//else
1778 940 tao
      }//for
1779
1780
      //add html summary file
1781 945 tao
      addHtmlSummaryToZipOutputStream(htmlDocumentImplList, zOut, rootName);
1782 940 tao
      zOut.finish(); //terminate the zip file
1783 1217 tao
      //dbConn.close();
1784 940 tao
      return zOut;
1785
    }//else
1786
  }//getZippedPackage()
1787 1361 tao
1788
   private class ReturnFieldValue
1789
  {
1790
    private String docid          = null; //return field value for this docid
1791
    private String fieldValue     = null;
1792
    private String xmlFieldValue  = null; //return field value in xml format
1793
1794
1795
    public void setDocid(String myDocid)
1796
    {
1797
      docid = myDocid;
1798
    }
1799
1800
    public String getDocid()
1801
    {
1802
      return docid;
1803
    }
1804
1805
    public void setFieldValue(String myValue)
1806
    {
1807
      fieldValue = myValue;
1808
    }
1809
1810
    public String getFieldValue()
1811
    {
1812
      return fieldValue;
1813
    }
1814
1815
    public void setXMLFieldValue(String xml)
1816
    {
1817
      xmlFieldValue = xml;
1818
    }
1819
1820
    public String getXMLFieldValue()
1821
    {
1822
      return xmlFieldValue;
1823
    }
1824
1825 940 tao
1826 1361 tao
  }
1827
1828 155 jones
}