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 535 jones
      Hashtable   docListResult = new Hashtable();
205 667 berkley
      PreparedStatement pstmt = null;
206 170 jones
      String docid = null;
207 155 jones
      String docname = null;
208
      String doctype = null;
209 401 berkley
      String createDate = null;
210
      String updateDate = null;
211
      String fieldname = null;
212
      String fielddata = null;
213 453 berkley
      String relation = null;
214 1217 tao
      //Connection dbconn = null;
215
      //Connection dbconn2 = null;
216 624 berkley
      int rev = 0;
217 1217 tao
      StringBuffer document = null;
218
      DBConnection dbconn = null;
219
      int serialNumber = -1;
220 465 berkley
221 155 jones
      try {
222 1217 tao
        /*if (conn == null || conn.isClosed()) {
223 710 berkley
          dbconn = util.openDBConnection();
224 743 jones
        } else {
225 710 berkley
          dbconn = conn;
226 1217 tao
        }*/
227
228
        dbconn=DBConnectionPool.getDBConnection("DBQuery.findDocuments");
229
        serialNumber=dbconn.getCheckOutSerialNumber();
230 766 bojilova
        // problem with ODBC driver multi-threading
231 790 bojilova
     //   dbconn2 = util.openDBConnection(); // for use by AccessControlList
232 766 bojilova
233 172 jones
        // Get the XML query and covert it into a SQL statment
234 178 jones
        QuerySpecification qspec = new QuerySpecification(xmlquery,
235 535 jones
                                   parserName,
236 624 berkley
                                   util.getOption("accNumSeparator"));
237 790 bojilova
  //System.out.println(qspec.printSQL(useXMLIndex));
238 706 bojilova
        pstmt = dbconn.prepareStatement( qspec.printSQL(useXMLIndex) );
239 790 bojilova
240 172 jones
        // Execute the SQL query using the JDBC connection
241 155 jones
        pstmt.execute();
242
        ResultSet rs = pstmt.getResultSet();
243
        boolean tableHasRows = rs.next();
244 667 berkley
        while (tableHasRows)
245
        {
246 768 bojilova
          docid = rs.getString(1).trim();
247 1217 tao
          if ( !hasPermission(user, groups, docid) ) {
248 612 bojilova
            // Advance to the next record in the cursor
249
            tableHasRows = rs.next();
250
            continue;
251
          }
252 155 jones
          docname = rs.getString(2);
253
          doctype = rs.getString(3);
254 692 bojilova
          createDate = rs.getString(4);
255
          updateDate = rs.getString(5);
256
          rev = rs.getInt(6);
257 743 jones
258 745 jones
          // if there are returndocs to match, backtracking can be performed
259
          // otherwise, just return the document that was hit
260
          Vector returndocVec = qspec.getReturnDocList();
261 743 jones
          if (returndocVec.size() != 0 && !returndocVec.contains(doctype))
262
          {
263 1096 tao
            MetaCatUtil.debugMessage("Back tracing now...", 50);
264 743 jones
            String sep = util.getOption("accNumSeparator");
265 465 berkley
            StringBuffer btBuf = new StringBuffer();
266 743 jones
            btBuf.append("select docid from xml_relation where ");
267
268 465 berkley
            //build the doctype list for the backtracking sql statement
269 743 jones
            btBuf.append("packagetype in (");
270 465 berkley
            for(int i=0; i<returndocVec.size(); i++)
271
            {
272
              btBuf.append("'").append((String)returndocVec.get(i)).append("'");
273 743 jones
              if (i != (returndocVec.size() - 1))
274 465 berkley
              {
275
                btBuf.append(", ");
276 475 berkley
              }
277 465 berkley
            }
278
            btBuf.append(") ");
279 743 jones
280
            btBuf.append("and (subject like '");
281
            btBuf.append(docid).append(sep).append(rev).append("'");
282
            btBuf.append("or object like '");
283
            btBuf.append(docid).append(sep).append(rev).append("')");
284 667 berkley
285 743 jones
            PreparedStatement npstmt = dbconn.
286
                                       prepareStatement(btBuf.toString());
287 1217 tao
            //should incease usage count
288
            dbconn.increaseUsageCount(1);
289 671 berkley
            npstmt.execute();
290
            ResultSet btrs = npstmt.getResultSet();
291 465 berkley
            boolean hasBtRows = btrs.next();
292 743 jones
            while (hasBtRows)
293 465 berkley
            { //there was a backtrackable document found
294
              DocumentImpl xmldoc = null;
295 743 jones
              String packageDocid = btrs.getString(1);
296 1096 tao
              util.debugMessage("Getting document for docid: "+packageDocid,40);
297 465 berkley
              try
298
              {
299 800 jones
                //  THIS CONSTRUCTOR BUILDS THE WHOLE XML doc not needed here
300
                // xmldoc = new DocumentImpl(dbconn, packageDocid);
301
                //  thus use the following to get the doc info only
302
                //  xmldoc = new DocumentImpl(dbconn);
303 1217 tao
                xmldoc = new DocumentImpl(packageDocid, false);
304 800 jones
                if (xmldoc == null) {
305 1096 tao
                  util.debugMessage("Document was null for: "+packageDocid, 50);
306 800 jones
                }
307 465 berkley
              }
308
              catch(Exception e)
309
              {
310 675 berkley
                System.out.println("Error getting document in " +
311
                                   "DBQuery.findDocuments: " + e.getMessage());
312 465 berkley
              }
313
314 800 jones
              String docid_org = xmldoc.getDocID();
315
              if (docid_org == null) {
316 1096 tao
                util.debugMessage("Docid_org was null.", 40);
317 800 jones
              }
318
              docid   = docid_org.trim();
319 465 berkley
              docname = xmldoc.getDocname();
320
              doctype = xmldoc.getDoctype();
321
              createDate = xmldoc.getCreateDate();
322
              updateDate = xmldoc.getUpdateDate();
323 743 jones
              rev = xmldoc.getRev();
324
325
              document = new StringBuffer();
326
327
              String completeDocid = docid + util.getOption("accNumSeparator");
328
              completeDocid += rev;
329
              document.append("<docid>").append(completeDocid);
330
              document.append("</docid>");
331
              if (docname != null) {
332
                document.append("<docname>" + docname + "</docname>");
333
              }
334
              if (doctype != null) {
335
                document.append("<doctype>" + doctype + "</doctype>");
336
              }
337
              if (createDate != null) {
338
                document.append("<createdate>" + createDate + "</createdate>");
339
              }
340
              if (updateDate != null) {
341
                document.append("<updatedate>" + updateDate + "</updatedate>");
342
              }
343
              // Store the document id and the root node id
344
              docListResult.put(docid,(String)document.toString());
345
346
              // Get the next package document linked to our hit
347
              hasBtRows = btrs.next();
348 465 berkley
            }
349 671 berkley
            npstmt.close();
350 465 berkley
            btrs.close();
351 743 jones
          } else {
352 465 berkley
353 743 jones
            document = new StringBuffer();
354
355 624 berkley
            String completeDocid = docid + util.getOption("accNumSeparator");
356
            completeDocid += rev;
357
            document.append("<docid>").append(completeDocid).append("</docid>");
358 465 berkley
            if (docname != null) {
359
              document.append("<docname>" + docname + "</docname>");
360
            }
361
            if (doctype != null) {
362
              document.append("<doctype>" + doctype + "</doctype>");
363
            }
364 743 jones
            if (createDate != null) {
365 465 berkley
              document.append("<createdate>" + createDate + "</createdate>");
366
            }
367 743 jones
            if (updateDate != null) {
368 465 berkley
              document.append("<updatedate>" + updateDate + "</updatedate>");
369
            }
370
            // Store the document id and the root node id
371
            docListResult.put(docid,(String)document.toString());
372 743 jones
373 155 jones
          }
374
375
          // Advance to the next record in the cursor
376
          tableHasRows = rs.next();
377
        }
378 667 berkley
        rs.close();
379 818 berkley
        pstmt.close();
380 401 berkley
381 743 jones
        if (qspec.containsExtendedSQL())
382 401 berkley
        {
383
          Vector extendedFields = new Vector(qspec.getReturnFieldList());
384
          Vector results = new Vector();
385 465 berkley
          Enumeration keylist = docListResult.keys();
386
          StringBuffer doclist = new StringBuffer();
387
          while(keylist.hasMoreElements())
388
          {
389
            doclist.append("'");
390
            doclist.append((String)keylist.nextElement());
391
            doclist.append("',");
392
          }
393 834 jones
          if (doclist.length() > 0) {
394
            doclist.deleteCharAt(doclist.length()-1); //remove the last comma
395
            //pstmt.close();
396
            pstmt = dbconn.prepareStatement(qspec.printExtendedSQL(
397 465 berkley
                                        doclist.toString()));
398 1217 tao
            //increase dbconnection usage count
399
            dbconn.increaseUsageCount(1);
400 834 jones
            pstmt.execute();
401
            rs = pstmt.getResultSet();
402 401 berkley
            tableHasRows = rs.next();
403 834 jones
            while(tableHasRows)
404 401 berkley
            {
405 834 jones
              docid = rs.getString(1).trim();
406 1217 tao
              if ( !hasPermission(user, groups, docid) ) {
407 834 jones
                // Advance to the next record in the cursor
408
                tableHasRows = rs.next();
409
                continue;
410
              }
411
              fieldname = rs.getString(2);
412
              fielddata = rs.getString(3);
413
414
              document = new StringBuffer();
415
416
              document.append("<param name=\"");
417
              document.append(fieldname);
418
              document.append("\">");
419
              document.append(fielddata);
420
              document.append("</param>");
421
422
              tableHasRows = rs.next();
423
              if (docListResult.containsKey(docid))
424
              {
425
                String removedelement = (String)docListResult.remove(docid);
426
                docListResult.put(docid, removedelement + document.toString());
427
              }
428
              else
429
              {
430
                docListResult.put(docid, document.toString());
431
              }
432 401 berkley
            }
433
          }
434 667 berkley
          rs.close();
435 401 berkley
        }
436 818 berkley
        pstmt.close();
437
438 465 berkley
        //this loop adds the relation data to the resultdoc
439
        //this code might be able to be added to the backtracking code above
440
        Enumeration docidkeys = docListResult.keys();
441
        while(docidkeys.hasMoreElements())
442 453 berkley
        {
443 602 berkley
          //String connstring = "metacat://"+util.getOption("server")+"?docid=";
444
          String connstring = "%docid=";
445 465 berkley
          String docidkey = (String)docidkeys.nextElement();
446 743 jones
          pstmt = dbconn.prepareStatement(qspec.printRelationSQL(docidkey));
447 465 berkley
          pstmt.execute();
448
          rs = pstmt.getResultSet();
449
          tableHasRows = rs.next();
450
          while(tableHasRows)
451
          {
452
            String sub = rs.getString(1);
453
            String rel = rs.getString(2);
454
            String obj = rs.getString(3);
455 489 berkley
            String subDT = rs.getString(4);
456
            String objDT = rs.getString(5);
457
458 894 berkley
            document = new StringBuffer();
459
            document.append("<triple>");
460
            document.append("<subject>").append(MetaCatUtil.normalize(sub));
461
            document.append("</subject>");
462
            if ( subDT != null ) {
463
              document.append("<subjectdoctype>").append(subDT);
464
              document.append("</subjectdoctype>");
465
            }
466 940 tao
            document.append("<relationship>").
467
                                          append(MetaCatUtil.normalize(rel));
468 894 berkley
            document.append("</relationship>");
469
            document.append("<object>").append(MetaCatUtil.normalize(obj));
470
            document.append("</object>");
471
            if ( objDT != null ) {
472
              document.append("<objectdoctype>").append(objDT);
473
              document.append("</objectdoctype>");
474
            }
475
            document.append("</triple>");
476
477
            String removedelement = (String)docListResult.remove(docidkey);
478
            docListResult.put(docidkey, removedelement +
479
                              document.toString());
480 465 berkley
            tableHasRows = rs.next();
481 453 berkley
          }
482 667 berkley
          rs.close();
483
          pstmt.close();
484 453 berkley
        }
485 667 berkley
486 155 jones
      } catch (SQLException e) {
487 667 berkley
        System.err.println("SQL Error in DBQuery.findDocuments: " +
488
                           e.getMessage());
489 170 jones
      } catch (IOException ioe) {
490 675 berkley
        System.err.println("IO error in DBQuery.findDocuments:");
491 170 jones
        System.err.println(ioe.getMessage());
492 667 berkley
      } catch (Exception ee) {
493 800 jones
        System.err.println("Exception in DBQuery.findDocuments: " +
494 667 berkley
                           ee.getMessage());
495 800 jones
        ee.printStackTrace(System.err);
496 155 jones
      }
497 1217 tao
      finally
498
      {
499 667 berkley
        try
500
        {
501 1217 tao
          pstmt.close();
502
        }//try
503
        catch (SQLException sqlE)
504 667 berkley
        {
505 1217 tao
          MetaCatUtil.debugMessage("Error in DBQuery.findDocuments: "
506
                                      +sqlE.getMessage(), 30);
507
        }//catch
508
        finally
509
        {
510
          DBConnectionPool.returnDBConnection(dbconn, serialNumber);
511
        }//finally
512
      }//finally
513 423 berkley
    //System.out.println("docListResult: ");
514
    //System.out.println(docListResult.toString());
515 155 jones
    return docListResult;
516
  }
517 342 berkley
518
  /**
519 436 berkley
   * returns a string array of the contents of a particular node.
520
   * If the node appears more than once, the contents are returned
521
   * in the order in which they appearred in the document.
522
   * @param nodename the name or path of the particular node.
523
   * @param docid the docid of the document you want the node from.
524
   */
525 1217 tao
  public static Object[] getNodeContent(String nodename, String docid)
526 436 berkley
  {
527 1217 tao
    DBConnection dbconn = null;
528
    int serialNumber = -1;
529 436 berkley
    StringBuffer query = new StringBuffer();
530
    Vector result = new Vector();
531 667 berkley
    PreparedStatement pstmt = null;
532 436 berkley
    query.append("select nodedata from xml_nodes where parentnodeid in ");
533
    query.append("(select nodeid from xml_index where path like '");
534
    query.append(nodename);
535
    query.append("' and docid like '").append(docid).append("')");
536
    try
537
    {
538 1217 tao
      dbconn=DBConnectionPool.getDBConnection("DBQuery.getNodeContent");
539
        serialNumber=dbconn.getCheckOutSerialNumber();
540
      pstmt = dbconn.prepareStatement(query.toString());
541 436 berkley
542
      // Execute the SQL query using the JDBC connection
543
      pstmt.execute();
544
      ResultSet rs = pstmt.getResultSet();
545
      boolean tableHasRows = rs.next();
546
      while (tableHasRows)
547
      {
548
        result.add(rs.getString(1));
549
        System.out.println(rs.getString(1));
550
        tableHasRows = rs.next();
551
      }
552
    }
553
    catch (SQLException e)
554
    {
555 675 berkley
      System.err.println("Error in DBQuery.getNodeContent: " + e.getMessage());
556 667 berkley
    } finally {
557
      try
558
      {
559
        pstmt.close();
560
      }
561 1217 tao
      catch(SQLException sqle)
562
      {}
563
      finally
564
      {
565
        DBConnectionPool.returnDBConnection(dbconn, serialNumber);
566
      }
567
568 667 berkley
    }
569 436 berkley
    return result.toArray();
570
  }
571
572
  /**
573 342 berkley
   * format a structured query as an XML document that conforms
574
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
575
   * structured query engine
576
   *
577 743 jones
   * @param params The list of parameters that should be included in the query
578 342 berkley
   */
579 372 berkley
  public static String createSQuery(Hashtable params)
580 350 berkley
  {
581
    StringBuffer query = new StringBuffer();
582 342 berkley
    Enumeration elements;
583
    Enumeration keys;
584 743 jones
    String filterDoctype = null;
585 372 berkley
    String casesensitive = null;
586
    String searchmode = null;
587 342 berkley
    Object nextkey;
588
    Object nextelement;
589 350 berkley
    //add the xml headers
590
    query.append("<?xml version=\"1.0\"?>\n");
591 743 jones
    query.append("<pathquery version=\"1.0\">\n");
592
593
    if (params.containsKey("meta_file_id"))
594 342 berkley
    {
595 743 jones
      query.append("<meta_file_id>");
596 342 berkley
      query.append( ((String[])params.get("meta_file_id"))[0]);
597 535 jones
      query.append("</meta_file_id>");
598 342 berkley
    }
599 350 berkley
600 743 jones
    if (params.containsKey("returndoctype"))
601 372 berkley
    {
602 744 jones
      String[] returnDoctypes = ((String[])params.get("returndoctype"));
603
      for(int i=0; i<returnDoctypes.length; i++)
604
      {
605
        String doctype = (String)returnDoctypes[i];
606
607
        if (!doctype.equals("any") &&
608
            !doctype.equals("ANY") &&
609
            !doctype.equals("") )
610
        {
611
          query.append("<returndoctype>").append(doctype);
612
          query.append("</returndoctype>");
613
        }
614
      }
615 372 berkley
    }
616 744 jones
617 743 jones
    if (params.containsKey("filterdoctype"))
618
    {
619
      String[] filterDoctypes = ((String[])params.get("filterdoctype"));
620
      for(int i=0; i<filterDoctypes.length; i++)
621
      {
622
        query.append("<filterdoctype>").append(filterDoctypes[i]);
623
        query.append("</filterdoctype>");
624
      }
625
    }
626 372 berkley
627 743 jones
    if (params.containsKey("returnfield"))
628 401 berkley
    {
629
      String[] returnfield = ((String[])params.get("returnfield"));
630
      for(int i=0; i<returnfield.length; i++)
631
      {
632
        query.append("<returnfield>").append(returnfield[i]);
633
        query.append("</returnfield>");
634
      }
635
    }
636
637 743 jones
    if (params.containsKey("owner"))
638 535 jones
    {
639
      String[] owner = ((String[])params.get("owner"));
640
      for(int i=0; i<owner.length; i++)
641
      {
642
        query.append("<owner>").append(owner[i]);
643
        query.append("</owner>");
644
      }
645
    }
646
647 743 jones
    if (params.containsKey("site"))
648 535 jones
    {
649
      String[] site = ((String[])params.get("site"));
650
      for(int i=0; i<site.length; i++)
651
      {
652
        query.append("<site>").append(site[i]);
653
        query.append("</site>");
654
      }
655
    }
656
657 350 berkley
    //allows the dynamic switching of boolean operators
658 743 jones
    if (params.containsKey("operator"))
659 350 berkley
    {
660
      query.append("<querygroup operator=\"" +
661 535 jones
                ((String[])params.get("operator"))[0] + "\">");
662 350 berkley
    }
663
    else
664
    { //the default operator is UNION
665
      query.append("<querygroup operator=\"UNION\">");
666
    }
667 535 jones
668 743 jones
    if (params.containsKey("casesensitive"))
669 372 berkley
    {
670
      casesensitive = ((String[])params.get("casesensitive"))[0];
671
    }
672
    else
673
    {
674
      casesensitive = "false";
675
    }
676
677 743 jones
    if (params.containsKey("searchmode"))
678 372 berkley
    {
679
      searchmode = ((String[])params.get("searchmode"))[0];
680
    }
681
    else
682
    {
683
      searchmode = "contains";
684
    }
685 535 jones
686 342 berkley
    //anyfield is a special case because it does a
687
    //free text search.  It does not have a <pathexpr>
688 350 berkley
    //tag.  This allows for a free text search within the structured
689
    //query.  This is useful if the INTERSECT operator is used.
690 743 jones
    if (params.containsKey("anyfield"))
691 342 berkley
    {
692 372 berkley
       String[] anyfield = ((String[])params.get("anyfield"));
693
       //allow for more than one value for anyfield
694
       for(int i=0; i<anyfield.length; i++)
695 350 berkley
       {
696 743 jones
         if (!anyfield[i].equals(""))
697 372 berkley
         {
698
           query.append("<queryterm casesensitive=\"" + casesensitive +
699
                        "\" " + "searchmode=\"" + searchmode + "\"><value>" +
700 535 jones
                        anyfield[i] +
701
                        "</value></queryterm>");
702 372 berkley
         }
703 350 berkley
       }
704 342 berkley
    }
705 535 jones
706 342 berkley
    //this while loop finds the rest of the parameters
707
    //and attempts to query for the field specified
708
    //by the parameter.
709
    elements = params.elements();
710
    keys = params.keys();
711
    while(keys.hasMoreElements() && elements.hasMoreElements())
712
    {
713
      nextkey = keys.nextElement();
714 535 jones
      nextelement = elements.nextElement();
715 372 berkley
716 535 jones
      //make sure we aren't querying for any of these
717
      //parameters since the are already in the query
718 342 berkley
      //in one form or another.
719 743 jones
      if (!nextkey.toString().equals("returndoctype") &&
720
         !nextkey.toString().equals("filterdoctype")  &&
721 535 jones
         !nextkey.toString().equals("action")  &&
722
         !nextkey.toString().equals("qformat") &&
723
         !nextkey.toString().equals("anyfield") &&
724 401 berkley
         !nextkey.toString().equals("returnfield") &&
725 535 jones
         !nextkey.toString().equals("owner") &&
726
         !nextkey.toString().equals("site") &&
727
         !nextkey.toString().equals("operator") )
728
      {
729 372 berkley
        //allow for more than value per field name
730
        for(int i=0; i<((String[])nextelement).length; i++)
731
        {
732 743 jones
          if (!((String[])nextelement)[i].equals(""))
733 372 berkley
          {
734
            query.append("<queryterm casesensitive=\"" + casesensitive +"\" " +
735 535 jones
                         "searchmode=\"" + searchmode + "\">" +
736
                         "<value>" +
737 372 berkley
                         //add the query value
738 535 jones
                         ((String[])nextelement)[i] +
739
                         "</value><pathexpr>" +
740
                         //add the path to query by
741 372 berkley
                         nextkey.toString() +
742
                         "</pathexpr></queryterm>");
743
          }
744
        }
745 535 jones
      }
746 342 berkley
    }
747
    query.append("</querygroup></pathquery>");
748 350 berkley
    //append on the end of the xml and return the result as a string
749 342 berkley
    return query.toString();
750
  }
751
752 181 jones
  /**
753
   * format a simple free-text value query as an XML document that conforms
754
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
755
   * structured query engine
756
   *
757
   * @param value the text string to search for in the xml catalog
758
   * @param doctype the type of documents to include in the result set -- use
759
   *        "any" or "ANY" for unfiltered result sets
760
   */
761
   public static String createQuery(String value, String doctype) {
762
     StringBuffer xmlquery = new StringBuffer();
763
     xmlquery.append("<?xml version=\"1.0\"?>\n");
764
     xmlquery.append("<pathquery version=\"1.0\">");
765
766
     if (!doctype.equals("any") && !doctype.equals("ANY")) {
767
       xmlquery.append("<returndoctype>");
768
       xmlquery.append(doctype).append("</returndoctype>");
769
     }
770
771
     xmlquery.append("<querygroup operator=\"UNION\">");
772 350 berkley
     //chad added - 8/14
773
     //the if statement allows a query to gracefully handle a null
774
     //query.  Without this if a nullpointerException is thrown.
775 743 jones
     if (!value.equals(""))
776 350 berkley
     {
777
       xmlquery.append("<queryterm casesensitive=\"false\" ");
778
       xmlquery.append("searchmode=\"contains\">");
779
       xmlquery.append("<value>").append(value).append("</value>");
780
       xmlquery.append("</queryterm>");
781
     }
782 181 jones
     xmlquery.append("</querygroup>");
783
     xmlquery.append("</pathquery>");
784
785
786
     return (xmlquery.toString());
787
   }
788
789
  /**
790
   * format a simple free-text value query as an XML document that conforms
791
   * to the pathquery.dtd and is appropriate for submission to the DBQuery
792
   * structured query engine
793
   *
794
   * @param value the text string to search for in the xml catalog
795
   */
796
   public static String createQuery(String value) {
797
     return createQuery(value, "any");
798
   }
799 441 bojilova
800 570 bojilova
  /**
801
    * Check for "READ" permission on @docid for @user and/or @group
802
    * from DB connection
803
    */
804 1217 tao
  private boolean hasPermission (String user,
805 802 bojilova
                                  String[] groups, String docid )
806 957 tao
                  throws SQLException, Exception
807 570 bojilova
  {
808 802 bojilova
    // Check for READ permission on @docid for @user and/or @groups
809 1217 tao
    //AccessControlList aclobj = new AccessControlList();
810
    //return aclobj.hasPermission("READ", user, groups, docid);
811
    return AccessControlList.hasPermission("READ", user, groups, docid);
812 441 bojilova
  }
813 940 tao
814
  /**
815
    * Get all docIds list for a data packadge
816
    * @param dataPackageDocid, the string in docId field of xml_relation table
817
    */
818
  private Vector getCurrentDocidListForDataPackage(String dataPackageDocid)
819
  {
820 1217 tao
    DBConnection dbConn = null;
821
    int serialNumber = -1;
822 940 tao
    Vector docIdList=new Vector();//return value
823 1217 tao
    PreparedStatement pStmt = null;
824 940 tao
    ResultSet rs=null;
825
    String docIdInSubjectField=null;
826
    String docIdInObjectField=null;
827 1292 tao
828
    // Check the parameter
829
    if (dataPackageDocid == null || dataPackageDocid.equals(""))
830
    {
831
      return docIdList;
832
    }//if
833
834 940 tao
    //the query stirng
835
    String query="SELECT subject, object from xml_relation where docId = ?";
836
    try
837
    {
838 1217 tao
      dbConn=DBConnectionPool.
839
                  getDBConnection("DBQuery.getCurrentDocidListForDataPackage");
840
      serialNumber=dbConn.getCheckOutSerialNumber();
841
      pStmt=dbConn.prepareStatement(query);
842 940 tao
      //bind the value to query
843
      pStmt.setString(1, dataPackageDocid);
844
845
      //excute the query
846
      pStmt.execute();
847
      //get the result set
848
      rs=pStmt.getResultSet();
849
      //process the result
850
      while (rs.next())
851
      {
852
        //In order to get the whole docIds in a data packadge,
853
        //we need to put the docIds of subject and object field in xml_relation
854
        //into the return vector
855
        docIdInSubjectField=rs.getString(1);//the result docId in subject field
856
        docIdInObjectField=rs.getString(2);//the result docId in object field
857
858
        //don't put the duplicate docId into the vector
859
        if (!docIdList.contains(docIdInSubjectField))
860
        {
861
          docIdList.add(docIdInSubjectField);
862
        }
863
864
        //don't put the duplicate docId into the vector
865
        if (!docIdList.contains(docIdInObjectField))
866
        {
867
          docIdList.add(docIdInObjectField);
868
        }
869
      }//while
870
      //close the pStmt
871
      pStmt.close();
872
    }//try
873
    catch (SQLException e)
874
    {
875 1292 tao
      MetaCatUtil.debugMessage("Error in getDocidListForDataPackage: "
876 1096 tao
                            +e.getMessage(), 30);
877 940 tao
    }//catch
878 1217 tao
    finally
879
    {
880
      try
881
      {
882
        pStmt.close();
883
      }//try
884
      catch (SQLException ee)
885
      {
886 1292 tao
        MetaCatUtil.debugMessage("Error in getDocidListForDataPackage: "
887 1217 tao
                            +ee.getMessage(), 30);
888
      }//catch
889
      finally
890
      {
891
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
892
      }//fianlly
893
    }//finally
894 940 tao
    return docIdList;
895
  }//getCurrentDocidListForDataPackadge()
896
897
  /**
898
   * Get all docIds list for a data packadge
899
   * @param dataPackageDocid, the string in docId field of xml_relation table
900
   */
901
  private Vector getOldVersionDocidListForDataPackage(String dataPackageDocid)
902
  {
903 441 bojilova
904 940 tao
    Vector docIdList=new Vector();//return value
905
    Vector tripleList=null;
906
    String xml=null;
907 1292 tao
908
     // Check the parameter
909
    if (dataPackageDocid == null || dataPackageDocid.equals(""))
910
    {
911
      return docIdList;
912
    }//if
913
914
    try
915
    {
916 1217 tao
      //initial a documentImpl object
917
      DocumentImpl packageDocument =
918
                  new DocumentImpl(dataPackageDocid);
919
      //transfer to documentImpl object to string
920
      xml=packageDocument.toString();
921 940 tao
922 1217 tao
      //create a tripcollection object
923
      TripleCollection tripleForPackage = new
924 940 tao
                                     TripleCollection(new StringReader(xml));
925 1217 tao
      //get the vetor of triples
926
      tripleList=tripleForPackage.getCollection();
927 940 tao
928 1217 tao
      for (int i= 0; i<tripleList.size(); i++)
929 940 tao
      {
930 1217 tao
        //put subject docid  into docIdlist without duplicate
931
        if (!docIdList.contains(((Triple)tripleList.elementAt(i)).getSubject()))
932
        {
933
          //put subject docid  into docIdlist
934
          docIdList.add(((Triple)tripleList.get(i)).getSubject());
935
        }
936
        //put object docid into docIdlist without duplicate
937
        if (!docIdList.contains(((Triple)tripleList.elementAt(i)).getObject()))
938
        {
939
          docIdList.add(((Triple)(tripleList.get(i))).getObject());
940
        }
941
      }//for
942 1292 tao
    }//try
943
    catch (Exception e)
944
    {
945
      MetaCatUtil.debugMessage("Error in getOldVersionAllDocumentImpl: "
946
                            +e.getMessage(), 30);
947
    }//catch
948 1217 tao
949 1292 tao
    // return result
950 940 tao
    return docIdList;
951
  }//getDocidListForPackageInXMLRevisions()
952
953
  /**
954
   * Check if the docId is a data packadge id. If the id is a data packadage
955
   *id, it should be store in the docId fields in xml_relation table.
956
   *So we can use a query to get the entries which the docId equals the given
957
   *value. If the result is null. The docId is not a packadge id. Otherwise,
958
   * it is.
959
   * @param docId, the id need to be checked
960
   */
961
  private boolean isDataPackageId(String docId)
962
  {
963
    boolean result=false;
964 1217 tao
    PreparedStatement pStmt = null;
965 940 tao
    ResultSet rs=null;
966
    String query="SELECT docId from xml_relation where docId = ?";
967 1217 tao
    DBConnection dbConn = null;
968
    int serialNumber = -1;
969 940 tao
    try
970
    {
971 1217 tao
      dbConn=DBConnectionPool.
972
                  getDBConnection("DBQuery.isDataPackageId");
973
      serialNumber=dbConn.getCheckOutSerialNumber();
974
      pStmt=dbConn.prepareStatement(query);
975 940 tao
      //bind the value to query
976
      pStmt.setString(1, docId);
977
      //execute the query
978
      pStmt.execute();
979
      rs=pStmt.getResultSet();
980
      //process the result
981
      if (rs.next()) //There are some records for the id in docId fields
982
      {
983
        result=true;//It is a data packadge id
984
      }
985
      pStmt.close();
986
    }//try
987
    catch (SQLException e)
988
    {
989 1217 tao
      util.debugMessage("Error in isDataPackageId: "
990 1096 tao
                            +e.getMessage(), 30);
991 940 tao
    }
992 1217 tao
    finally
993
    {
994
      try
995
      {
996
        pStmt.close();
997
      }//try
998
      catch (SQLException ee)
999
      {
1000
        MetaCatUtil.debugMessage("Error in isDataPackageId: "
1001
                                                        + ee.getMessage(), 30);
1002
      }//catch
1003
      finally
1004
      {
1005
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1006
      }//finally
1007
    }//finally
1008 940 tao
    return result;
1009
  }//isDataPackageId()
1010
1011
  /**
1012 945 tao
   * Check if the user has the permission to export data package
1013
   * @param conn, the connection
1014
   * @param docId, the id need to be checked
1015
   * @param user, the name of user
1016
   * @param groups, the user's group
1017
   */
1018 1217 tao
   private boolean hasPermissionToExportPackage(String docId,
1019 945 tao
                                        String user, String[] groups)
1020
                   throws Exception
1021
   {
1022 1217 tao
     //DocumentImpl doc=new DocumentImpl(conn,docId);
1023
     return DocumentImpl.hasReadPermission(user, groups,docId);
1024 945 tao
   }
1025
1026
  /**
1027 940 tao
   *Get the current Rev for a docid in xml_documents table
1028
   * @param docId, the id need to get version numb
1029
   * If the return value is -5, means no value in rev field for this docid
1030
   */
1031
  private int getCurrentRevFromXMLDoumentsTable(String docId)
1032 1292 tao
                                                throws SQLException
1033 940 tao
  {
1034
    int rev=-5;
1035 1217 tao
    PreparedStatement pStmt = null;
1036 940 tao
    ResultSet rs=null;
1037
    String query="SELECT rev from xml_documents where docId = ?";
1038 1217 tao
    DBConnection dbConn=null;
1039
    int serialNumber = -1;
1040 940 tao
    try
1041
    {
1042 1217 tao
      dbConn=DBConnectionPool.
1043
                  getDBConnection("DBQuery.getCurrentRevFromXMLDocumentsTable");
1044
      serialNumber=dbConn.getCheckOutSerialNumber();
1045
      pStmt=dbConn.prepareStatement(query);
1046 940 tao
      //bind the value to query
1047
      pStmt.setString(1, docId);
1048
      //execute the query
1049
      pStmt.execute();
1050
      rs=pStmt.getResultSet();
1051
      //process the result
1052
      if (rs.next()) //There are some records for rev
1053
      {
1054
        rev=rs.getInt(1);;//It is the version for given docid
1055
      }
1056
      else
1057
      {
1058
        rev=-5;
1059
      }
1060 1292 tao
1061 940 tao
    }//try
1062
    catch (SQLException e)
1063
    {
1064 1292 tao
      MetaCatUtil.debugMessage("Error in getCurrentRevFromXMLDoumentsTable: "
1065 1096 tao
                            +e.getMessage(), 30);
1066 1292 tao
      throw e;
1067 1217 tao
    }//catch
1068
    finally
1069
    {
1070
      try
1071
      {
1072
        pStmt.close();
1073
      }//try
1074
      catch (SQLException ee)
1075
      {
1076
        MetaCatUtil.debugMessage("Error in getCurrentRevFromXMLDoumentsTable: "
1077
                                  +ee.getMessage(), 30);
1078
      }//catch
1079
      finally
1080
      {
1081
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1082
      }//finally
1083
    }//finally
1084 940 tao
    return rev;
1085
  }//getCurrentRevFromXMLDoumentsTable
1086
1087
 /**
1088
   *put a doc into a zip output stream
1089
   *@param docImpl, docmentImpl object which will be sent to zip output stream
1090
   *@param zipOut, zip output stream which the docImpl will be put
1091
   *@param packageZipEntry, the zip entry name for whole package
1092
   */
1093
  private void addDocToZipOutputStream(DocumentImpl docImpl,
1094
                                ZipOutputStream zipOut, String packageZipEntry)
1095
               throws ClassNotFoundException, IOException, SQLException,
1096
                      McdbException, Exception
1097
  {
1098
    byte[] byteString = null;
1099
    ZipEntry zEntry = null;
1100
1101
    byteString = docImpl.toString().getBytes();
1102
    //use docId as the zip entry's name
1103
    zEntry = new ZipEntry(packageZipEntry+"/metadata/"+docImpl.getDocID());
1104
    zEntry.setSize(byteString.length);
1105
    zipOut.putNextEntry(zEntry);
1106
    zipOut.write(byteString, 0, byteString.length);
1107
    zipOut.closeEntry();
1108
1109
  }//addDocToZipOutputStream()
1110
1111
1112
  /**
1113 1292 tao
   * Transfer a docid vetor to a documentImpl vector. The documentImpl vetor
1114
   * only inlcudes current version. If a DocumentImple object
1115
   * couldn't find for a docid, then the String of this docid was added to vetor
1116
   * rather than DocumentImple object.
1117
   * @param docIdList, a vetor hold a docid list for a data package. In docid,
1118
   * there is not version number in it.
1119 940 tao
   */
1120
1121
  private Vector getCurrentAllDocumentImpl( Vector docIdList)
1122
                              throws McdbException,Exception
1123
  {
1124 1217 tao
    //Connection dbConn=null;
1125 940 tao
    Vector documentImplList=new Vector();
1126
    int rev=0;
1127
1128 1292 tao
    // Check the parameter
1129
    if (docIdList.isEmpty())
1130 940 tao
    {
1131 1292 tao
      return documentImplList;
1132
    }//if
1133
1134 940 tao
    //for every docid in vector
1135
    for (int i=0;i<docIdList.size();i++)
1136
    {
1137 1292 tao
      try
1138
      {
1139
        //get newest version for this docId
1140
        rev=getCurrentRevFromXMLDoumentsTable((String)docIdList.elementAt(i));
1141
1142
        // There is no record for this docId in xml_documents table
1143
        if (rev ==-5)
1144
        {
1145
          // Rather than put DocumentImple object, put a String Object(docid)
1146
          // into the documentImplList
1147
          documentImplList.add((String)docIdList.elementAt(i));
1148
          // Skip other code
1149
          continue;
1150
        }
1151 948 tao
1152 1292 tao
        String docidPlusVersion=((String)docIdList.elementAt(i))
1153 948 tao
                        +util.getOption("accNumSeparator")+rev;
1154 1292 tao
1155
1156
        //create new documentImpl object
1157
        DocumentImpl documentImplObject =
1158 1217 tao
                                    new DocumentImpl(docidPlusVersion);
1159 1292 tao
       //add them to vector
1160
        documentImplList.add(documentImplObject);
1161
      }//try
1162
      catch (Exception e)
1163
      {
1164
        MetaCatUtil.debugMessage("Error in getCurrentAllDocumentImpl: "
1165
                            +e.getMessage(), 30);
1166
        // continue the for loop
1167
        continue;
1168
      }
1169 940 tao
    }//for
1170
    return documentImplList;
1171
  }
1172
1173
  /**
1174 1292 tao
   * Transfer a docid vetor to a documentImpl vector. If a DocumentImple object
1175
   * couldn't find for a docid, then the String of this docid was added to vetor
1176
   * rather than DocumentImple object.
1177
   * @param docIdList, a vetor hold a docid list for a data package. In docid,
1178
   *t here is version number in it.
1179 940 tao
   */
1180
  private Vector getOldVersionAllDocumentImpl( Vector docIdList)
1181
  {
1182 1217 tao
    //Connection dbConn=null;
1183 940 tao
    Vector documentImplList=new Vector();
1184
    String siteCode=null;
1185
    String uniqueId=null;
1186
    int rev=0;
1187
1188 1292 tao
    // Check the parameter
1189
    if (docIdList.isEmpty())
1190 940 tao
    {
1191 1292 tao
      return documentImplList;
1192
    }//if
1193
1194 940 tao
    //for every docid in vector
1195
    for (int i=0;i<docIdList.size();i++)
1196
    {
1197
1198 948 tao
        String docidPlusVersion=(String)(docIdList.elementAt(i));
1199 1292 tao
1200
        try
1201
        {
1202
          //create new documentImpl object
1203
          DocumentImpl documentImplObject =
1204 1217 tao
                                    new DocumentImpl(docidPlusVersion);
1205 1292 tao
          //add them to vector
1206
          documentImplList.add(documentImplObject);
1207
        }//try
1208
        catch (McdbDocNotFoundException notFoundE)
1209
        {
1210
          MetaCatUtil.debugMessage("Error in DBQuery.getOldVersionAllDocument"+
1211
                                  "Imple" + notFoundE.getMessage(), 30);
1212
          // Rather than add a DocumentImple object into vetor, a String object
1213
          // - the doicd was added to the vector
1214
          documentImplList.add(docidPlusVersion);
1215
          // Continue the for loop
1216
          continue;
1217
        }//catch
1218
        catch (Exception e)
1219
        {
1220
          MetaCatUtil.debugMessage("Error in DBQuery.getOldVersionAllDocument"+
1221
                                  "Imple" + e.getMessage(), 30);
1222
          // Continue the for loop
1223
          continue;
1224
        }//catch
1225
1226 948 tao
1227 940 tao
    }//for
1228
    return documentImplList;
1229 1292 tao
  }//getOldVersionAllDocumentImple
1230
1231 940 tao
  /**
1232
   *put a data file into a zip output stream
1233
   *@param docImpl, docmentImpl object which will be sent to zip output stream
1234
   *@param zipOut, the zip output stream which the docImpl will be put
1235
   *@param packageZipEntry, the zip entry name for whole package
1236
   */
1237
  private void addDataFileToZipOutputStream(DocumentImpl docImpl,
1238
                                ZipOutputStream zipOut, String packageZipEntry)
1239
               throws ClassNotFoundException, IOException, SQLException,
1240
                      McdbException, Exception
1241
  {
1242
    byte[] byteString = null;
1243
    ZipEntry zEntry = null;
1244
    // this is data file; add file to zip
1245
    String filePath = util.getOption("datafilepath");
1246
    if (!filePath.endsWith("/"))
1247
    {
1248
      filePath += "/";
1249
    }
1250
    String fileName = filePath + docImpl.getDocID();
1251 963 berkley
    zEntry = new ZipEntry(packageZipEntry+"/data/"+docImpl.getDocID());
1252 940 tao
    zipOut.putNextEntry(zEntry);
1253
    FileInputStream fin = null;
1254
    try
1255
    {
1256
      fin = new FileInputStream(fileName);
1257
      byte[] buf = new byte[4 * 1024]; // 4K buffer
1258
      int b = fin.read(buf);
1259
      while (b != -1)
1260
      {
1261
        zipOut.write(buf, 0, b);
1262
        b = fin.read(buf);
1263
      }//while
1264
      zipOut.closeEntry();
1265
    }//try
1266
    catch (IOException ioe)
1267
    {
1268 1096 tao
      util.debugMessage("There is an exception: "+ioe.getMessage(), 30);
1269 940 tao
    }//catch
1270
  }//addDataFileToZipOutputStream()
1271
1272
  /**
1273
   *create a html summary for data package and put it into zip output stream
1274
   *@param docImplList, the documentImpl ojbects in data package
1275
   *@param zipOut, the zip output stream which the html should be put
1276
   *@param packageZipEntry, the zip entry name for whole package
1277
   */
1278
   private void addHtmlSummaryToZipOutputStream(Vector docImplList,
1279
                                ZipOutputStream zipOut, String packageZipEntry)
1280
                                           throws Exception
1281
  {
1282
    StringBuffer htmlDoc = new StringBuffer();
1283
    ZipEntry zEntry = null;
1284
    byte[] byteString=null;
1285
    InputStream source;
1286
    DBTransform xmlToHtml;
1287 1292 tao
1288 940 tao
    //create a DBTransform ojbect
1289 1217 tao
    xmlToHtml = new DBTransform();
1290 940 tao
    //head of html
1291
    htmlDoc.append("<html><head></head><body>");
1292
    for (int i=0; i<docImplList.size(); i++)
1293
    {
1294 1292 tao
      // If this String object, this means it is missed data file
1295
      if ((((docImplList.elementAt(i)).getClass()).toString())
1296
                                             .equals("class java.lang.String"))
1297
      {
1298
1299
        htmlDoc.append("<a href=\"");
1300
        String dataFileid =(String)docImplList.elementAt(i);
1301
        htmlDoc.append("./data/").append(dataFileid).append("\">");
1302
        htmlDoc.append("Data File: ");
1303
        htmlDoc.append(dataFileid).append("</a><br>");
1304
        htmlDoc.append("<br><hr><br>");
1305
1306
      }//if
1307
      else if ((((DocumentImpl)docImplList.elementAt(i)).getDoctype()).
1308 940 tao
                                                         compareTo("BIN")!=0)
1309
      { //this is an xml file so we can transform it.
1310
        //transform each file individually then concatenate all of the
1311
        //transformations together.
1312
1313
        //for metadata xml title
1314
        htmlDoc.append("<h2>");
1315
        htmlDoc.append(((DocumentImpl)docImplList.elementAt(i)).getDocID());
1316
        //htmlDoc.append(".");
1317
        //htmlDoc.append(((DocumentImpl)docImplList.elementAt(i)).getRev());
1318
        htmlDoc.append("</h2>");
1319
        //do the actual transform
1320
        StringWriter docString = new StringWriter();
1321
        xmlToHtml.transformXMLDocument(
1322
                        ((DocumentImpl)docImplList.elementAt(i)).toString(),
1323
           "-//NCEAS//eml-generic//EN", "-//W3C//HTML//EN", "html", docString);
1324
        htmlDoc.append(docString.toString());
1325
        htmlDoc.append("<br><br><hr><br><br>");
1326
      }//if
1327
      else
1328
      { //this is a data file so we should link to it in the html
1329
        htmlDoc.append("<a href=\"");
1330
        String dataFileid =((DocumentImpl)docImplList.elementAt(i)).getDocID();
1331
        htmlDoc.append("./data/").append(dataFileid).append("\">");
1332
        htmlDoc.append("Data File: ");
1333
        htmlDoc.append(dataFileid).append("</a><br>");
1334
        htmlDoc.append("<br><hr><br>");
1335
      }//else
1336
    }//for
1337
    htmlDoc.append("</body></html>");
1338
    byteString = htmlDoc.toString().getBytes();
1339
    zEntry = new ZipEntry(packageZipEntry+"/metadata.html");
1340
    zEntry.setSize(byteString.length);
1341
    zipOut.putNextEntry(zEntry);
1342
    zipOut.write(byteString, 0, byteString.length);
1343
    zipOut.closeEntry();
1344 1217 tao
    //dbConn.close();
1345 940 tao
1346
  }//addHtmlSummaryToZipOutputStream
1347
1348 945 tao
1349
1350 940 tao
  /**
1351
   * put a data packadge into a zip output stream
1352
   * @param docId, which the user want to put into zip output stream
1353
   * @param out, a servletoutput stream which the zip output stream will be put
1354
   * @param user, the username of the user
1355
   * @param groups, the group of the user
1356
   */
1357
  public ZipOutputStream getZippedPackage(String docIdString,
1358 1292 tao
        ServletOutputStream out, String user, String[] groups, String passWord)
1359 940 tao
                    throws ClassNotFoundException, IOException, SQLException,
1360
                      McdbException, NumberFormatException, Exception
1361
  {
1362
    ZipOutputStream zOut = null;
1363
    String elementDocid=null;
1364
    DocumentImpl docImpls=null;
1365 1217 tao
    //Connection dbConn = null;
1366 940 tao
    Vector docIdList=new Vector();
1367 945 tao
    Vector documentImplList=new Vector();
1368
    Vector htmlDocumentImplList=new Vector();
1369 940 tao
    String packageId=null;
1370
    String rootName="package";//the package zip entry name
1371
1372
    String docId=null;
1373
    int version=-5;
1374 1292 tao
    // Docid without revision
1375 940 tao
    docId=MetaCatUtil.getDocIdFromString(docIdString);
1376 1292 tao
    // revision number
1377 940 tao
    version=MetaCatUtil.getVersionFromString(docIdString);
1378
1379
    //check if the reqused docId is a data package id
1380
    if (!isDataPackageId(docId))//if it is not, throw a exception
1381
    {
1382 945 tao
      Exception e = new Exception("The request the doc id " +docIdString+
1383 940 tao
                                    " is not a data package id");
1384
      throw e;
1385
    }
1386 1292 tao
    // Check the permission of user
1387 1217 tao
    else if(!hasPermissionToExportPackage(docId, user, groups))
1388 945 tao
    {
1389 1292 tao
1390 945 tao
      Exception e = new Exception("User " + user + " does not have permission"
1391
                       +" to export the data package " + docIdString);
1392
      throw e;
1393
    }
1394 940 tao
    else //it is a packadge id
1395
    {
1396
      //store the package id
1397
      packageId=docId;
1398 1292 tao
      //get current version in database
1399
      int currentVersion = getCurrentRevFromXMLDoumentsTable(packageId);
1400
      //If it is for current version (-1 means user didn't specify revision)
1401
      if ((version ==-1)||version==currentVersion)
1402 940 tao
      {
1403
        //get current version number
1404 1292 tao
        version=currentVersion;
1405 940 tao
        //get package zip entry name
1406
        //it should be docId.revsion.package
1407
        rootName=packageId+util.getOption("accNumSeparator")+version+
1408
                                  util.getOption("accNumSeparator")+"package";
1409
        //get the whole id list for data packadge
1410
        docIdList=getCurrentDocidListForDataPackage(packageId);
1411
        //get the whole documentImple object
1412
        documentImplList=getCurrentAllDocumentImpl(docIdList);
1413
1414
      }//if
1415 1292 tao
      else if (version > currentVersion || version < -1)
1416
      {
1417
        throw new Exception ("The user specified docid: "+docId+"."+version
1418
                                              +" doesn't exist");
1419
      }//else if
1420 940 tao
      else  //for an old version
1421
      {
1422
1423
        rootName=docIdString+util.getOption("accNumSeparator")+"package";
1424
        //get the whole id list for data packadge
1425
        docIdList=getOldVersionDocidListForDataPackage(docIdString);
1426
1427
        //get the whole documentImple object
1428
        documentImplList=getOldVersionAllDocumentImpl(docIdList);
1429
      }//else
1430
1431 1292 tao
      // Make sure documentImplist is not empty
1432
      if (documentImplList.isEmpty())
1433
      {
1434
        throw new Exception ("Couldn't find component for data package: "
1435
                                              + packageId);
1436
      }//if
1437 940 tao
1438 1292 tao
1439
       zOut = new ZipOutputStream(out);
1440 940 tao
      //put every element into zip output stream
1441
      for (int i=0; i < documentImplList.size(); i++ )
1442
      {
1443 1292 tao
        // if the object in the vetor is String, this means we couldn't find
1444
        // the document locally, we need find it remote
1445
       if ((((documentImplList.elementAt(i)).getClass()).toString())
1446
                                             .equals("class java.lang.String"))
1447
        {
1448
          // Get String object from vetor
1449
          String documentId = (String) documentImplList.elementAt(i);
1450
          MetaCatUtil.debugMessage("docid: "+documentId, 30);
1451
          // Get doicd without revision
1452
          String docidWithoutRevision =
1453
                                     MetaCatUtil.getDocIdFromString(documentId);
1454
          MetaCatUtil.debugMessage("docidWithoutRevsion: "
1455
                                                     +docidWithoutRevision, 30);
1456
          // Get revision
1457
          String revision = MetaCatUtil.getRevisionStringFromString(documentId);
1458
          MetaCatUtil.debugMessage("revsion from docIdentifier: "+revision, 30);
1459
          // Zip entry string
1460
          String zipEntryPath = rootName+"/data/";
1461
          // Create a RemoteDocument object
1462
          RemoteDocument remoteDoc =
1463
                          new RemoteDocument(docidWithoutRevision,revision,user,
1464
                                                     passWord, zipEntryPath);
1465
          // Here we only read data file from remote metacat
1466
          String docType = remoteDoc.getDocType();
1467
          if (docType!=null)
1468
          {
1469
            if (docType.equals("BIN"))
1470
            {
1471
              // Put remote document to zip output
1472
              remoteDoc.readDocumentFromRemoteServerByZip(zOut);
1473
              // Add String object to htmlDocumentImplList
1474
              String elementInHtmlList = remoteDoc.getDocIdWithoutRevsion()+
1475
               MetaCatUtil.getOption("accNumSeparator")+remoteDoc.getRevision();
1476
              htmlDocumentImplList.add(elementInHtmlList);
1477
            }//if
1478
          }//if
1479
1480
        }//if
1481
        else
1482
        {
1483
          //create a docmentImpls object (represent xml doc) base on the docId
1484
          docImpls=(DocumentImpl)documentImplList.elementAt(i);
1485
          //checking if the user has the permission to read the documents
1486
          if (docImpls.hasReadPermission(user,groups,docImpls.getDocID()))
1487
          {
1488 948 tao
            //if the docImpls is metadata
1489 1292 tao
            if ((docImpls.getDoctype()).compareTo("BIN")!=0)
1490
            {
1491 948 tao
              //add metadata into zip output stream
1492
              addDocToZipOutputStream(docImpls, zOut, rootName);
1493
              //add the documentImpl into the vetor which will be used in html
1494
              htmlDocumentImplList.add(docImpls);
1495 953 tao
1496 1292 tao
            }//if
1497
            else
1498
            {
1499
              //it is data file
1500
              addDataFileToZipOutputStream(docImpls, zOut, rootName);
1501
              htmlDocumentImplList.add(docImpls);
1502
            }//else
1503 948 tao
          }//if
1504 1292 tao
        }//else
1505 940 tao
      }//for
1506
1507
      //add html summary file
1508 945 tao
      addHtmlSummaryToZipOutputStream(htmlDocumentImplList, zOut, rootName);
1509 940 tao
      zOut.finish(); //terminate the zip file
1510 1217 tao
      //dbConn.close();
1511 940 tao
      return zOut;
1512
    }//else
1513
  }//getZippedPackage()
1514
1515 155 jones
}