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-02-17 16:54:39 -0800 (Fri, 17 Feb 2012) $'
13
 * '$Revision: 7015 $'
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 on all servers
439
   */
440
  public static Vector<String> getAllDocidsByType(String doctype, boolean includeRevs) throws SQLException {
441
	  return getAllDocidsByType(doctype, includeRevs, -1);
442
  }
443
  
444
  /**
445
   * return all docids with a given doctype for a given server
446
   */
447
  public static Vector<String> getAllDocidsByType(String doctype, boolean includeRevs, int serverLocation) throws SQLException {
448
		Vector<String> resultVector = new Vector<String>();
449
		String sep = ".";
450
	    try {
451
	    	PropertyService.getProperty("document.accNumSeparator");
452
	    } catch (PropertyNotFoundException pnfe) {
453
	    	logMetacat.error("DBUtil.getAllDocidsByType - could not get property " + 
454
	    			"'accNumSeparator'.  setting to '.': " + pnfe.getMessage());  	
455
	    }
456
		PreparedStatement pstmt = null;
457
		DBConnection dbConn = null;
458
		int serialNumber = -1;
459
		try {
460
			dbConn = DBConnectionPool.getDBConnection("DBUtil.getAllDocidsByType");
461
			serialNumber = dbConn.getCheckOutSerialNumber();
462
			StringBuffer sb = new StringBuffer();
463

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

    
487
			if (doctype != null) {
488
				pstmt.setString(1, doctype);
489
				if (includeRevs) {
490
					pstmt.setString(2, doctype);
491
				}
492
			}
493
			pstmt.execute();
494
			ResultSet rs = pstmt.getResultSet();
495

    
496
			String id = null;
497
			String rev = null;
498
			while (rs.next()) {
499
				id = rs.getString(1);
500
				rev = rs.getString(2);
501
				if (id != null) {
502
					resultVector.addElement(id + sep + rev);
503
				}
504
			}
505

    
506
			pstmt.close();
507

    
508
		} catch (SQLException e) {
509
			throw new SQLException("DBUtil.getAllDocidsByType(). " + e.getMessage());
510
		} finally {
511
			try {
512
				pstmt.close();
513
			}// try
514
			finally {
515
				DBConnectionPool.returnDBConnection(dbConn, serialNumber);
516
			}// finally
517
		}// finally
518

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

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

    
586
    } catch (SQLException e) {
587
      throw new SQLException("DBUtil.getAllDocids - SQL error:  " + e.getMessage());
588
    }
589
    finally
590
    {
591
      try
592
      {
593
        pstmt.close();
594
      }//try
595
      finally
596
      {
597
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
598
      }//finally
599
    }//finally
600

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

    
885
          pStmt = dbConn
886
                  .prepareStatement("SELECT rev FROM xml_revisions WHERE docid = ? ORDER BY rev ASC");
887
          pStmt.setString(1, docIdWithoutRev);
888
          pStmt.execute();
889

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

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

    
936
          pStmt = dbConn
937
                  .prepareStatement("SELECT rev FROM xml_documents WHERE docid = ?");
938
          pStmt.setString(1, docIdWithoutRev);
939
          pStmt.execute();
940

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

    
962
      return rev;
963
  }
964
  
965
  
966
}
(22-22/64)