Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements utility methods like:
4
 *             1/ Reding all doctypes from db connection
5
 *             2/ Reading DTD or Schema file from Metacat catalog system
6
 *             3/ Reading Lore type Data Guide from db connection
7
 *  Copyright: 2000 Regents of the University of California and the
8
 *             National Center for Ecological Analysis and Synthesis
9
 *    Authors: Jivka Bojilova
10
 * 
11
 *   '$Author: leinfelder $'
12
 *     '$Date: 2012-01-17 12:06:51 -0800 (Tue, 17 Jan 2012) $'
13
 * '$Revision: 6912 $'
14
 *
15
 * This program is free software; you can redistribute it and/or modify
16
 * it under the terms of the GNU General Public License as published by
17
 * the Free Software Foundation; either version 2 of the License, or
18
 * (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program; if not, write to the Free Software
27
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28
 */
29

    
30
package edu.ucsb.nceas.metacat;
31

    
32
import java.sql.SQLException;
33
import java.sql.PreparedStatement;
34
import java.sql.ResultSet;
35

    
36
import java.io.BufferedInputStream;
37
import java.io.InputStream;
38
import java.io.IOException;
39
import java.net.URL;
40
import java.net.MalformedURLException;
41

    
42
import java.util.Enumeration;
43
import java.util.Vector;
44

    
45
import org.apache.log4j.Logger;
46

    
47
import edu.ucsb.nceas.metacat.database.DBConnection;
48
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
49
import edu.ucsb.nceas.metacat.properties.PropertyService;
50
import edu.ucsb.nceas.metacat.util.DocumentUtil;
51
import edu.ucsb.nceas.metacat.util.SystemUtil;
52
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
53

    
54
/**
55
 * A suite of utility classes for querying DB
56
 */
57
public class DBUtil {
58

    
59
  //private Connection	conn = null;
60
  private static Logger logMetacat = Logger.getLogger(DBUtil.class);
61
  private static final int MAXMUM = -2;
62
  public static final int NONEEXIST = -1;
63

    
64
  /**
65
   * main routine used for testing.
66
   * <p>
67
   * Usage: java DBUtil <-dt|-dg>
68
   *
69
   * @param -dt for selecting all doctypes
70
   *        -dg for selecting DataGuide
71
   */
72
  static public void main(String[] args) {
73
     
74
     if (args.length < 1)
75
     {
76
        System.err.println("Wrong number of arguments!!!");
77
        System.err.println("USAGE: java DBUtil <-dt | -ds [doctype] | -dl user>");
78
        return;
79
     } else {
80
        try {
81
                    
82
          // Open a connection to the database
83
          //Connection dbconn = util.openDBConnection();
84

    
85
          DBUtil dbutil = new DBUtil();
86
          
87
          if ( args[0].equals("-dt") ) {
88
            String doctypes = dbutil.readDoctypes();
89
            System.out.println(doctypes);
90
          } else if ( args[0].equals("-ds") ) {
91
            String doctype = null;
92
            if ( args.length == 2 ) { doctype = args[1]; }
93
            String dtdschema = dbutil.readDTDSchema(doctype);
94
            System.out.println(dtdschema);
95
          } else if ( args[0].equals("-dl") ) {
96
            String scope = "";
97
            if ( args.length == 2 ) { scope = args[1]; }
98
            String docid = dbutil.getMaxDocid(scope);
99
            System.out.println(docid);
100
          } else {
101
            System.err.println(
102
            "USAGE: java DBUtil <-dt | -ds [doctype] | -dg [doctype]>");
103
          }  
104

    
105
        } catch (Exception e) {
106
          //System.err.println("error in DBUtil.main");
107
          //System.err.println(e.getMessage());
108
          e.printStackTrace(System.err);
109
        }
110
     }
111
  }
112
  
113
  /**
114
   * Construct an instance of the utility class
115
   */
116
  public DBUtil() {
117
    //this.conn = conn;
118
  }
119

    
120
  /**
121
   * read all doctypes from db connection in XML format
122
   * select all Public Id from xml_catalog table
123
   */
124
  public String readDoctypes()
125
        throws SQLException  {
126

    
127
    Vector<String> doctypeList = new Vector<String>();
128
    DBConnection dbConn = null;
129
    int serialNumber = -1;
130
    PreparedStatement pstmt = null;
131
    try {
132

    
133
      dbConn=DBConnectionPool.
134
                  getDBConnection("DBUtil.readDoctypes");
135
      serialNumber=dbConn.getCheckOutSerialNumber();
136
      pstmt =
137
        dbConn.prepareStatement("SELECT public_id FROM xml_catalog " +
138
                              "WHERE entry_type = 'DTD'");
139

    
140
      pstmt.execute();
141
      ResultSet rs = pstmt.getResultSet();
142
      boolean tableHasRows = rs.next();
143
      while (tableHasRows) {
144
           doctypeList.addElement(rs.getString(1));
145
           tableHasRows = rs.next();
146
      }
147
      
148
      pstmt.close();
149

    
150
    } catch (SQLException e) {
151
      throw new SQLException("DBUtil.readDoctypes - SQL error: " + e.getMessage());
152
    }
153
    finally
154
    {
155
      try
156
      {
157
        pstmt.close();
158
      }//try
159
      finally
160
      {
161
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
162
      }//finally
163
    }//finally
164
       
165

    
166
    return formatToXML(doctypeList, "doctype");
167
  }
168

    
169
  /**
170
   * read DTD or Schema file from Metacat's XML catalog system
171
   */
172
  public String readDTDSchema(String doctype)
173
        throws SQLException, MalformedURLException, IOException, PropertyNotFoundException
174
  {
175
    String systemID = null;
176
    PreparedStatement pstmt = null;
177
    StringBuffer cbuff = new StringBuffer();
178
    DBConnection dbConn = null;
179
    int serialNumber = -1;
180
    // get doctype's System ID from db catalog
181
    try {
182
    
183
      dbConn=DBConnectionPool.
184
                  getDBConnection("DBUtil.readDTDSchema");
185
      serialNumber=dbConn.getCheckOutSerialNumber();
186
      pstmt = dbConn.prepareStatement("SELECT system_id " + 
187
                                    "FROM xml_catalog " +
188
                                    "WHERE entry_type in ('DTD','Schema') " +
189
                                    "AND public_id LIKE ?");
190
      pstmt.setString(1, doctype);
191
      pstmt.execute();
192
      ResultSet rs = pstmt.getResultSet();
193
      boolean hasRow = rs.next();
194
      if (hasRow) {
195
        systemID = rs.getString(1);
196
        // system id may not have server url on front.  Add it if not.
197
        if (!systemID.startsWith("http://")) {
198
        	systemID = SystemUtil.getContextURL() + systemID;
199
        }
200
      } else {
201
        throw new SQLException("DBUtil.readDTDSchema - Non-registered doctype: " + doctype);
202
      }
203
      pstmt.close();
204

    
205
    } catch (SQLException e) {
206
      throw new SQLException("DBUtil.readDTDSchema - " + e.getMessage());
207
    }
208
    finally
209
    {
210
      try
211
      {
212
        pstmt.close();
213
      }//try
214
      finally
215
      {
216
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
217
      }//finally
218
    }//finally
219

    
220
    // read from URL stream as specified by the System ID.
221
    try {
222
      // open a connection to this URL and return an InputStream
223
      // for reading from that connection
224
      InputStream istream = new URL(systemID).openStream();
225
      // create a buffering character-input stream
226
      // that uses a default-sized input buffer
227
      BufferedInputStream in = new BufferedInputStream(istream);
228

    
229
      // read the input and write into the string buffer
230
	    int inputByte;
231
	    while ( (inputByte = in.read()) != -1 ) {
232
        cbuff.append((char)inputByte);
233
	    }
234

    
235
      // the input stream must be closed
236
	    in.close();
237
	    
238
    } catch (MalformedURLException e) {
239
    	throw new MalformedURLException("DBUtil.readDTDSchema - Malformed URL Error: " + e.getMessage());
240
    } catch (IOException e) {
241
    	throw new IOException("DBUtil.readDTDSchema - I/O error: " + e.getMessage());
242
    } catch (SecurityException e) {
243
    	throw new IOException("DBUtil.readDTDSchema - Security error: " + e.getMessage());
244
    }
245
    
246
   return cbuff.toString();
247
  }
248

    
249
//  /**
250
//   * format the DataGuide ResultSet to XML
251
//   */
252
//  private String formatToXML(Vector resultset) {
253
//  
254
//    String currPath = null;
255
//    String currElement = null;
256
//    String prevElement = null;
257
//    StringBuffer result = new StringBuffer();
258
//    Enumeration<String> rs = resultset.elements(); 
259
//    Stack st = new Stack();
260
//    int i = 0;
261
//
262
//    result.append("<?xml version=\"1.0\"?>\n");
263
//    result.append("<resultset>\n"); 
264
//    
265
//    while (rs.hasMoreElements()) {
266
//        currPath = (String)rs.nextElement();
267
//        while ( !In(prevElement, currPath) ) {
268
//            currElement = (String)st.pop();
269
//            result.append(pad(" ",i--) + "</" + currElement + ">\n");
270
//            if ( st.empty() ) 
271
//                prevElement = null;
272
//            else    
273
//                prevElement = (String)st.peek();
274
//        }    
275
//        currElement = getElementFromPath(currPath);
276
//        st.push(currElement);
277
//        result.append(pad(" ",++i) + "<" + currElement + ">\n");
278
//        prevElement = currElement;
279
//    }
280
//    while ( !st.empty() ) {
281
//        prevElement = (String)st.pop();
282
//        result.append(pad(" ",i--) + "</" + prevElement + ">\n");
283
//    }    
284
//    result.append("</resultset>\n"); 
285
//
286
//    return result.toString();
287
//  }
288

    
289
//  /**
290
//   * check if element is in path like /elem1/elem2/elemn3
291
//   */
292
//  private boolean In(String element, String path) {
293
//    
294
//    if ( element == null ) return true;
295
//    return ( path.indexOf(element) != -1 );
296
//  }
297
//
298
//  /**
299
//   * get last element from path like /elem1/elem2/elemn3
300
//   */
301
//  private String getElementFromPath(String path) {
302
//    
303
//    return ( path.substring(path.lastIndexOf("/")+1) );
304
//  }
305
//
306
//  /**
307
//   * repeates the str n-times
308
//   */
309
//  private String pad(String str, int n) {
310
//    
311
//    String result = "";
312
//    for ( int i = 0; i < n; i++ )
313
//        result = result.concat(str);
314
//        
315
//    return result;    
316
//  }
317

    
318
  /**
319
   * format the ResultSet to XML
320
   */
321
  private String formatToXML(Vector<String> resultset, String tag) {
322
  
323
    String val = null;
324
    StringBuffer result = new StringBuffer();
325
    Enumeration<String> rs = resultset.elements(); 
326

    
327
    result.append("<?xml version=\"1.0\"?>\n");
328
    result.append("<resultset>\n"); 
329
    while (rs.hasMoreElements()) {
330
        val = rs.nextElement();
331
        result.append("   <" + tag + ">" + val + "</" + tag + ">\n");
332
    }
333
    result.append("</resultset>\n"); 
334
    
335
    return result.toString();
336
  }
337

    
338
  /**
339
   * get the latest Accession Number from a particular scope
340
   */
341
  public String getMaxDocid(String scope)
342
        throws SQLException  {
343

    
344
    String accnum = null;
345
    String sep = ".";
346
    try {
347
    	PropertyService.getProperty("document.accNumSeparator");
348
    } catch (PropertyNotFoundException pnfe) {
349
    	logMetacat.error("DBUtil.getMaxDocid - could not get property " + 
350
    			"'accNumSeparator'.  setting to '.': " + pnfe.getMessage());  	
351
    }
352
    PreparedStatement pstmt = null;
353
    DBConnection dbConn = null;
354
    int serialNumber = -1;
355
    try {
356
        dbConn=DBConnectionPool.
357
                  getDBConnection("DBUtil.getMaxDocid");
358
        serialNumber=dbConn.getCheckOutSerialNumber();
359
        pstmt =
360
        dbConn.prepareStatement(
361
            "SELECT docid, max(rev) FROM " +
362
            "( " +
363
                "SELECT docid, rev " + 
364
                "FROM xml_documents " +
365
                "WHERE docid LIKE ? " +
366
            "UNION " + 
367
                "SELECT docid, rev " + 
368
                "FROM xml_revisions " +
369
                "WHERE docid LIKE ?" +
370
            ") subquery GROUP BY docid"
371
            );
372

    
373
      pstmt.setString(1,scope + sep + "%");
374
      pstmt.setString(2,scope + sep + "%");
375
      pstmt.execute();
376
      ResultSet rs = pstmt.getResultSet();
377
      
378
      long max = 0;
379
      String temp = null;
380
      
381
      while(rs.next()){
382
    	  temp = rs.getString(1);
383
    	  if(temp != null){
384
    		  temp = temp.substring(temp.indexOf(scope) + scope.length() + 1);
385
    		  try {
386
    			  long localid = Long.parseLong(temp);
387
    			  if (localid > max) {
388
    				  max = localid;
389
    				  accnum = rs.getString(1) + sep + rs.getString(2);
390
    			  }
391
    		  } catch (NumberFormatException nfe){
392
    			  // ignore the exception as it is possible that the  
393
    			  // localid in the identifier is not an integer 
394
    		  }
395
    	  }
396
      }
397
      
398
      pstmt.close();
399

    
400
    } catch (SQLException e) {
401
      throw new SQLException("DBUtil.getMaxDocid(). " + e.getMessage());
402
    }
403
    finally
404
    {
405
      try
406
      {
407
        pstmt.close();
408
      }//try
409
      finally
410
      {
411
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
412
      }//finally
413
    }//finally
414

    
415
    return accnum;
416
  }
417
  
418
  /**
419
   * return true if the given docid is registered in either the xml_documents
420
   * or xml_revisions table
421
   */
422
  public boolean idExists(String docid)
423
    throws SQLException
424
  {
425
    Vector<String> v = getAllDocids(null);
426
    for(int i=0; i<v.size(); i++)
427
    {
428
      String id = (String)v.elementAt(i);
429
      if(id.trim().equals(docid.trim()))
430
      {
431
        return true;
432
      }
433
    }
434
    return false;
435
  }
436
  
437
  /**
438
   * return all docids with a given doctype
439
   */
440
  public static Vector<String> getAllDocidsByType(String doctype, boolean includeRevs, int serverLocation) throws SQLException {
441
		Vector<String> resultVector = new Vector<String>();
442
		String sep = ".";
443
	    try {
444
	    	PropertyService.getProperty("document.accNumSeparator");
445
	    } catch (PropertyNotFoundException pnfe) {
446
	    	logMetacat.error("DBUtil.getAllDocidsByType - could not get property " + 
447
	    			"'accNumSeparator'.  setting to '.': " + pnfe.getMessage());  	
448
	    }
449
		PreparedStatement pstmt = null;
450
		DBConnection dbConn = null;
451
		int serialNumber = -1;
452
		try {
453
			dbConn = DBConnectionPool.getDBConnection("DBUtil.getAllDocidsByType");
454
			serialNumber = dbConn.getCheckOutSerialNumber();
455
			StringBuffer sb = new StringBuffer();
456

    
457
			sb.append("SELECT docid, rev FROM " + "( " + "SELECT docid, rev "
458
					+ "FROM xml_documents ");
459
			sb.append("WHERE true ");
460
			if (doctype != null) {
461
				sb.append("AND doctype LIKE ? ");
462
			}
463
			if (serverLocation > 0) {
464
				sb.append("AND server_location = ' " + serverLocation + "' ");
465
			}
466
			
467
			if (includeRevs) {
468
				sb.append("UNION " + "SELECT docid, rev " + "FROM xml_revisions ");
469
				sb.append("WHERE true ");
470
				if (doctype != null) {
471
					sb.append("AND doctype LIKE ?");
472
				}
473
				if (serverLocation > 0) {
474
					sb.append("AND server_location = ' " + serverLocation + "' ");
475
				}
476
			}
477
			sb.append(") subquery GROUP BY docid, rev");
478
			pstmt = dbConn.prepareStatement(sb.toString());
479

    
480
			if (doctype != null) {
481
				pstmt.setString(1, doctype);
482
				if (includeRevs) {
483
					pstmt.setString(2, doctype);
484
				}
485
			}
486
			pstmt.execute();
487
			ResultSet rs = pstmt.getResultSet();
488

    
489
			String id = null;
490
			String rev = null;
491
			while (rs.next()) {
492
				id = rs.getString(1);
493
				rev = rs.getString(2);
494
				if (id != null) {
495
					resultVector.addElement(id + sep + rev);
496
				}
497
			}
498

    
499
			pstmt.close();
500

    
501
		} catch (SQLException e) {
502
			throw new SQLException("DBUtil.getAllDocidsByType(). " + e.getMessage());
503
		} finally {
504
			try {
505
				pstmt.close();
506
			}// try
507
			finally {
508
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
509
			}// finally
510
		}// finally
511

    
512
		return resultVector;
513
	}
514
  
515
  /**
516
   * get the latest Accession Number from a particular scope
517
   */
518
  public static Vector<String> getAllDocids(String scope)
519
        throws SQLException  {
520
    Vector<String> resultVector = new Vector<String>();
521
//    String accnum = null;
522
    String sep = ".";
523
    try {
524
    	PropertyService.getProperty("document.accNumSeparator");
525
    } catch (PropertyNotFoundException pnfe) {
526
    	logMetacat.error("could not get property 'accNumSeparator'.  setting to '.': " 
527
    			+ pnfe.getMessage());  	
528
    }
529
    PreparedStatement pstmt = null;
530
    DBConnection dbConn = null;
531
    int serialNumber = -1;
532
    try 
533
    {
534
      dbConn=DBConnectionPool.
535
                getDBConnection("DBUtil.getAllDocids");
536
      serialNumber=dbConn.getCheckOutSerialNumber();
537
      StringBuffer sb = new StringBuffer();
538
      
539
      sb.append("SELECT docid, rev FROM " +
540
                "( " +
541
                "SELECT docid, rev " + 
542
                "FROM xml_documents ");
543
      if(scope != null)
544
      {
545
        sb.append("WHERE docid LIKE ? ");
546
      }
547
      sb.append("UNION " + 
548
                "SELECT docid, rev " + 
549
                "FROM xml_revisions ");
550
      if(scope != null)
551
      {
552
        sb.append("WHERE docid LIKE ?");
553
      }
554
      sb.append(") subquery GROUP BY docid, rev");
555
      pstmt = dbConn.prepareStatement(sb.toString());
556

    
557
      if(scope != null)
558
      {
559
        pstmt.setString(1,scope + sep + "%");
560
        pstmt.setString(2,scope + sep + "%");
561
      }
562
      pstmt.execute();
563
      ResultSet rs = pstmt.getResultSet();
564
      
565
//      long max = 0;
566
      String id = null;
567
      String rev = null;
568
      while(rs.next()){
569
    	  id = rs.getString(1);
570
        rev = rs.getString(2);
571
    	  if(id != null){
572
    		  //temp = temp.substring(id.indexOf(scope) + scope.length() + 1);
573
          resultVector.addElement(id + sep + rev);
574
        }
575
      }
576
      
577
      pstmt.close();
578

    
579
    } catch (SQLException e) {
580
      throw new SQLException("DBUtil.getAllDocids - SQL error:  " + e.getMessage());
581
    }
582
    finally
583
    {
584
      try
585
      {
586
        pstmt.close();
587
      }//try
588
      finally
589
      {
590
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
591
      }//finally
592
    }//finally
593

    
594
    return resultVector;
595
  }
596
  
597
  /**
598
   * To a given docid, found a dataset docid which contains the the given docid
599
   * This will be done by searching xml_relation table
600
   * If couldn't find, null will be return
601
   * @param givenDocId, the docid which we want to find
602
   */
603
  public static String findDataSetDocIdForGivenDocument(String givenDocId)
604
  {
605
    // Prepared statement for sql
606
    PreparedStatement pStmt = null;
607
    // Result set
608
    ResultSet resultSet = null;
609
    // String to store the data set docid
610
    String dataSetDocId = null;
611
    // DBConnection will be checkout
612
    DBConnection dbConn = null;
613
    int serialNumber = -1;
614
    // String to store the sql command
615
    String sqlCommand = null;
616
    try
617
    {
618
      // Checkout DBConnection from pool
619
      dbConn=DBConnectionPool.
620
                  getDBConnection("DBUtil.findDataSetDocIdForGivenDocument");
621
      serialNumber=dbConn.getCheckOutSerialNumber();
622
      // SQL command to chose a docid from xm_relation table
623
      sqlCommand = "select docid from xml_relation where object like ? or " 
624
                                                    + "subject like ?";
625
      // Prepared statement
626
      pStmt = dbConn.prepareStatement(sqlCommand);
627
      // Bind variable
628
      pStmt.setString(1, givenDocId);
629
      pStmt.setString(2, givenDocId);
630
      // Execute prepared statement
631
      pStmt.execute();
632
      // Get result set
633
      resultSet = pStmt.getResultSet();
634
      
635
      // There has record
636
      if (resultSet.next())
637
      {
638
        // Put the docid into dataSetDocid
639
        dataSetDocId = resultSet.getString(1);
640
        return dataSetDocId;
641
      }//if
642
      else
643
      {
644
        // No record in xml_relation table for given doicd, null returned
645
        return dataSetDocId;
646
      }//else
647
    
648
    }//try
649
    catch ( SQLException e)
650
    {
651
      // Print out exception
652
      logMetacat.error("DBUtil.findDataSetDocIdForGivenDocument - " +
653
    		  "SQL error: " + e.getMessage());
654
      // return null
655
      return dataSetDocId;
656
     
657
    }//catch
658
    finally
659
    {
660
      try
661
      {
662
        // Close result set
663
        resultSet.close();
664
        // Close preparedStatement
665
        pStmt.close();
666
      }//try
667
      catch ( SQLException e)
668
      {
669
        // Print out exception
670
    	  logMetacat.error("DBUtil.findDataSetDocIdForGivenDocument - " +
671
    			  "error closing db resources: "  + e.getMessage());
672
     
673
      }//catch
674
      finally
675
      {
676
        // Return DBConnection to the pool
677
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
678
      }//finally
679
    }//finally
680
        
681
  }//findDataSetDocIdForGivenDocument
682
  
683
  /**
684
   * Method to get current revision and doctype for a given docid
685
   * The output will look like "rev;doctype"
686
   * @param givenDocId, the docid which we want 
687
   */
688
  public String getCurrentRevisionAndDocTypeForGivenDocument(String givenDocId)
689
                                                 throws SQLException
690
  {
691
    // DBConection for JDBC
692
    DBConnection dbConn = null;
693
    int serialNumber = -1;
694
    // Prepared Statement
695
    PreparedStatement pstmt = null;
696
    // String to store a docid without rev
697
    String docIdWithoutRevision = null;
698
    // SQL command
699
    String sqlCommand = null;
700
    // Result set
701
    ResultSet rs = null;
702
    // String to store the revision
703
    String revision = null;
704
    // String to store the doctype
705
    String docType = null;
706
    
707
    // Get docid without rev
708
    docIdWithoutRevision = DocumentUtil.getDocIdFromString(givenDocId);
709
    // SQL command is:
710
    sqlCommand = "select rev, doctype from xml_documents where docid like ?";
711
    
712
    try
713
    {
714
      // Check out the connection
715
      dbConn=DBConnectionPool.
716
         getDBConnection("DBUtil.getCurrentRevisionAndDocTypeForGivenDocument");
717
      serialNumber=dbConn.getCheckOutSerialNumber();
718
      
719
      // Prepare the sql command
720
      pstmt = dbConn.prepareStatement(sqlCommand);
721
      // Bin variable
722
      pstmt.setString(1, docIdWithoutRevision);
723
      // Execute the prepared statement
724
      pstmt.execute();
725
      // Get result set
726
      rs = pstmt.getResultSet();
727
      // If there is some record
728
      if (rs.next())
729
      {
730
        revision = rs.getString(1);
731
        docType = rs.getString(2);
732
      }//if
733
      else
734
      {
735
        //search xml_revision table
736
        Vector<Integer> revisionList = getRevListFromRevisionTable(docIdWithoutRevision);
737
        if(revisionList == null || revisionList.isEmpty())
738
        {
739
          // No record, throw a exception
740
          throw new 
741
                SQLException("DBUtil.getCurrentRevisionAndDocTypeForGivenDocument - " + 
742
                    "There is no record for given docid: " + givenDocId);
743
        }
744
        else
745
        {
746
          int maxRev = getMaxmumNumber(revisionList);
747
          if(maxRev == MAXMUM)
748
          {
749
            throw new 
750
            SQLException("DBUtil.getCurrentRevisionAndDocTypeForGivenDocument - " + 
751
                "There is no record for given docid: " + givenDocId);
752
          }
753
          revision = (new Integer(maxRev)).toString();
754
          sqlCommand = "select doctype from xml_revisions where docid like '"+docIdWithoutRevision+"' and rev="+maxRev;
755
          pstmt = dbConn.prepareStatement(sqlCommand);
756
          // Execute the prepared statement
757
          pstmt.execute();
758
          // Get result set
759
          rs = pstmt.getResultSet();
760
          // If there is some record
761
          if (rs.next())
762
          {
763
            docType = rs.getString(1);
764
          }//if
765
        }
766
       
767
      }//else
768
        
769
    }
770
    finally
771
    {
772
      try
773
      {
774
        // Close result set
775
        rs.close();
776
        // Close preparedStatement
777
        pstmt.close();
778
      }//try
779
      catch ( SQLException e)
780
      {
781
        // Print out exception
782
    	  logMetacat.error("DBUtil.getCurrentRevisionAndDocTypeForGivenDocument - " + 
783
    			  "Error closing db resources: " + e.getMessage());
784
     
785
      }//catch
786
      finally
787
      {
788
        // Return DBConnection to the pool
789
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
790
      }//finally
791
    }
792
    return revision+";"+docType;
793
  }//getCurrentRevisionAndDocTypeForGivenDocument
794
  
795
  /*
796
   * Gets the maxium number in a given vector.
797
   */
798
  private static int getMaxmumNumber(Vector<Integer>list)
799
  {
800
    Integer max = null;
801
    if(list != null)
802
    {
803
      for(int i=0; i<list.size(); i++)
804
      {
805
        if(i ==0)
806
        {
807
          max = list.elementAt(i);
808
        }
809
        else
810
        {
811
          if(max == null)
812
          {
813
            max = list.elementAt(i);
814
          }
815
          else
816
          {
817
            Integer current = list.elementAt(i);
818
            if(current != null && current.intValue() > max.intValue())
819
            {
820
              max = current;
821
            }
822
          }
823
        }
824
      }
825
    }
826
    if(max != null)
827
    {
828
      return max.intValue();
829
    }
830
    else
831
    {
832
      return MAXMUM;
833
    }
834
  }
835
 
836
  /**
837
   * Method to return max rev number in xml_revision for given docid.
838
   * @param docId
839
   * @return integer that holds max revision number
840
   * @throws SQLException
841
   */
842
  public static int getMaxRevFromRevisionTable(String docIdWithoutRev) throws SQLException
843
  {
844
	  int rev = NONEEXIST;
845
	  
846
	  Vector<Integer> revList = getRevListFromRevisionTable(docIdWithoutRev);
847
	  
848
	  for (Integer currentRev : revList) {
849
		  if (currentRev > rev) {
850
			  rev = currentRev;
851
		  }
852
	  }
853
	  
854
	  return rev;
855
  }
856
  
857
  /**
858
   * Method to return a rev list in xml_revision for given docid.
859
   * @param docId
860
   * @return is a vector which contains Integer object
861
   * @throws SQLException
862
   */
863
  public static Vector<Integer> getRevListFromRevisionTable(String docIdWithoutRev) throws SQLException
864
  {
865
      Vector<Integer> list = new Vector<Integer>();
866
      int rev = 1;
867
      PreparedStatement pStmt = null;
868
      DBConnection dbConn = null;
869
      int serialNumber = -1;
870
      // get rid of rev
871
      //docId = MetacatUtil.getDocIdFromString(docId);
872
      try {
873
          //check out DBConnection
874
          dbConn = DBConnectionPool
875
                  .getDBConnection("getRevListFromRevisionTable");
876
          serialNumber = dbConn.getCheckOutSerialNumber();
877

    
878
          pStmt = dbConn
879
                  .prepareStatement("SELECT rev FROM xml_revisions WHERE docid = ? ORDER BY rev ASC");
880
          pStmt.setString(1, docIdWithoutRev);
881
          pStmt.execute();
882

    
883
          ResultSet rs = pStmt.getResultSet();
884
          boolean hasRow = rs.next();
885
          while (hasRow) {
886
              rev = rs.getInt(1);
887
              logMetacat.info("DBUtil.getRevListFromRevisionTable - rev: " + rev + 
888
            		  " is added to list for docid: " + docIdWithoutRev);
889
              list.add(new Integer(rev));
890
              hasRow = rs.next();
891
              
892
          }
893
          pStmt.close();
894
      }//try
895
      finally {
896
          try {
897
              pStmt.close();
898
          } catch (Exception ee) {
899
        	  logMetacat.error("DBUtil.getRevListFromRevisionTable - Error closing " + 
900
        			  "prepared statement: " + ee.getMessage());
901
          } finally {
902
              DBConnectionPool.returnDBConnection(dbConn, serialNumber);
903
          }
904
      }//finally
905

    
906
      return list;
907
  }//getLatestRevisionNumber
908
  
909
  /**
910
   * Get last revision number from database for a docid If couldn't find an
911
   * entry, -1 will return The return value is integer because we want compare
912
   * it to there new one
913
   *
914
   * @param docid
915
   *            <sitecode>. <uniqueid>part of Accession Number
916
   */
917
  public static int getLatestRevisionInDocumentTable(String docIdWithoutRev) throws SQLException
918
  {
919
      int rev = 1;
920
      PreparedStatement pStmt = null;
921
      DBConnection dbConn = null;
922
      int serialNumber = -1;
923
      try {
924
          //check out DBConnection
925
          dbConn = DBConnectionPool
926
                  .getDBConnection("DBUtil.getLatestRevisionInDocumentTable");
927
          serialNumber = dbConn.getCheckOutSerialNumber();
928

    
929
          pStmt = dbConn
930
                  .prepareStatement("SELECT rev FROM xml_documents WHERE docid = ?");
931
          pStmt.setString(1, docIdWithoutRev);
932
          pStmt.execute();
933

    
934
          ResultSet rs = pStmt.getResultSet();
935
          boolean hasRow = rs.next();
936
          if (hasRow) {
937
              rev = rs.getInt(1);
938
              pStmt.close();
939
          } else {
940
              rev = NONEEXIST;
941
              pStmt.close();
942
          }
943
      }//try
944
      finally {
945
          try {
946
              pStmt.close();
947
          } catch (Exception ee) {
948
        	  logMetacat.error("DBUtil.getLatestRevisionInDocumentTable - Error closing " + 
949
        			  " prepared statement: " + ee.getMessage());
950
          } finally {
951
              DBConnectionPool.returnDBConnection(dbConn, serialNumber);
952
          }
953
      }//finally
954

    
955
      return rev;
956
  }
957
  
958
  
959
}
(22-22/64)