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