Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A class that gets Accession Number, check for uniqueness
4
 *             and register it into db
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Jivka Bojilova, Matt Jones
8
 *    Release: @release@
9
 *
10
 *   '$Author: jones $'
11
 *     '$Date: 2005-11-18 16:44:23 -0800 (Fri, 18 Nov 2005) $'
12
 * '$Revision: 2768 $'
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
 */
28

    
29
package edu.ucsb.nceas.metacat;
30

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

    
35
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
36

    
37
/**
38
 * (on insert of XML document)
39
 * Generates a unique Accession Number or if provided check it
40
 * for uniqueness and register it into the db connection
41
 * (on update or delete of XML document)
42
 * Check for existance of provided Accession Number
43
 *
44
 */
45
public class AccessionNumber  {
46

    
47
  private static final AbstractDatabase dbAdapter = MetaCatUtil.dbAdapter;
48

    
49
  private String sitecode = null;
50
  private String sep = null;
51
  private String docid = null;
52
  private String rev = null;
53

    
54
  /**
55
   * Construct an AccessionNumber
56
   */
57
  private AccessionNumber ()
58
  {
59
    this.sitecode = MetaCatUtil.getOption("sitecode");
60
    this.sep = MetaCatUtil.getOption("accNumSeparator");
61
  }
62

    
63
  /** NEW - WHEN CLIENT ALWAYS PROVIDE ACCESSION NUMBER INCLUDING REV IN IT
64
   * Construct an AccessionNumber
65
   *
66
   * @param conn the db connection to read Accession number from
67
   * @param accnum the accession number to be checked for validness
68
   */
69
  public AccessionNumber (String accnum, String action)
70
           throws AccessionNumberException, SQLException, NumberFormatException
71
 {
72
    this();
73

    
74
    this.rev = null;
75
    this.docid = accnum;
76
    if ( accnum != null ) {
77
      int firstIndex = accnum.indexOf(this.sep);
78
      int lastIndex = accnum.lastIndexOf(this.sep);
79
      if ( firstIndex != lastIndex ) {
80
        //this docid contains a revision number
81
        this.rev = accnum.substring(lastIndex + 1);
82
        this.docid = accnum.substring(0, lastIndex);
83
      }
84
    }
85

    
86
    // INSERT
87
    if ( action.equals("INSERT")) {
88

    
89
        if(rev != null){
90
            try {
91
                Integer.parseInt(rev);
92
            }
93
            catch (java.lang.NumberFormatException e) {
94
                throw new AccessionNumberException(
95
                    "Revision number is required");
96
            }
97
        }
98

    
99
      // check accession number for validness
100
      if ( docid == null ) {
101
        throw new AccessionNumberException("Accession number is required");
102

    
103
      // rev is not provided; throw an exception to prevent the insertion
104
      } else if ( rev == null ) {
105
        throw new AccessionNumberException
106
                  ("Revision number is required");
107

    
108
      // docid is used; throw an exception to prevent the insertion
109
      } else if ( accNumberUsed(docid) ) {
110
        throw new AccessionNumberException
111
                  ("Accession number " + docid + " is already in use");
112

    
113
      // rev is <> 1; throw an exception to prevent the insertion
114
      } /*else if ( !rev.equals("1")) {
115
        throw new AccessionNumberException("Revision number must be 1");
116
      }*/
117

    
118
    // UPDATE or DELETE
119
    } else if ( action.equals("UPDATE") || action.equals("DELETE")) {
120
      String l_rev = "";
121

    
122
      int reversionNumber = 1;
123

    
124
      if(rev != null){
125
          try{
126
              reversionNumber = Integer.parseInt(rev);
127
          } catch (java.lang.NumberFormatException e){
128
              throw new AccessionNumberException(
129
                      "Revision number is required");
130
          }
131
      }
132

    
133
      // Accession# is not provided; throw an exception to prevent the action
134
      if ( docid == null ) {
135
        throw new AccessionNumberException("Accession number is required");
136

    
137
      // rev is not provided; throw an exception to prevent the action
138
      } else if ( rev == null ) {
139
        throw new AccessionNumberException
140
                  ("Revision number is required");
141

    
142
      // Accession# is not current (not in xml_documents); throw an exception
143
      } else if ( !accNumberIsCurrent(docid) ) {
144
        throw new AccessionNumberException
145
                  ("Document not found for Accession number " + docid);
146

    
147
      //Revision number is less than or equal the recent one; throw a exception
148
      } else if ( action.equals("UPDATE") &&
149
                  reversionNumber <= getLastRevisionNumber(docid) ) {
150
        throw new AccessionNumberException
151
                 ("Next revision number couldn't be less than or equal "
152
                                              + getLastRevisionNumber(docid));
153

    
154
      // Revision number is not the recent one; throw an exception
155
      } else if ( action.equals("DELETE") &&
156
                  !rev.equals(l_rev = getLastRevision(docid)) ) {
157
        throw new AccessionNumberException
158
                  ("Last revision number is "+ l_rev);
159
      }
160
    }
161
  }
162

    
163
  /** check for existence of Accesssion Number xml_acc_numbers table */
164
  public static boolean accNumberUsed ( String accNumber )
165
                  throws SQLException {
166

    
167
    boolean hasAccNumber = false;
168
    DBConnection conn = null;
169
    int serialNumber = -1;
170

    
171
    try {
172
      PreparedStatement pstmt = null;
173
      //check out DBConnection
174
      conn=DBConnectionPool.getDBConnection("AccessionNumber.accNumberUsed");
175
      serialNumber=conn.getCheckOutSerialNumber();
176
      pstmt = conn.prepareStatement(
177
                "SELECT 'x' FROM xml_documents " +
178
                "WHERE docid = ? " +
179
                "UNION " +
180
                "SELECT 'x' FROM xml_revisions " +
181
                "WHERE docid = ?");
182
      pstmt.setString(1,accNumber);
183
      pstmt.setString(2,accNumber);
184
      pstmt.execute();
185
      ResultSet rs = pstmt.getResultSet();
186
      hasAccNumber = rs.next();
187
      pstmt.close();
188

    
189
    } catch (SQLException e) {
190
      throw new SQLException
191
      ("Error on AccessionNumber.accNumberUsed(accNumber): " + e.getMessage());
192
    }
193
    finally
194
    {
195
      DBConnectionPool.returnDBConnection(conn, serialNumber);
196
    }
197

    
198
    return hasAccNumber;
199
  }
200

    
201
  // check for existence of Accesssion Number in xml_documents table
202
  private boolean accNumberIsCurrent(String accNumber) throws SQLException {
203

    
204
    boolean hasCurrentAccNumber = false;
205
    DBConnection conn = null;
206
    int serialNumber = -1;
207

    
208
    try {
209
      PreparedStatement pstmt = null;
210
      //check out DBConnection
211
      conn=DBConnectionPool.getDBConnection("AccessionNumber.accNumberIsCurre");
212
      serialNumber=conn.getCheckOutSerialNumber();
213
      pstmt = conn.prepareStatement(
214
                "SELECT 'x' FROM xml_documents " +
215
                "WHERE docid = ?");
216
      pstmt.setString(1, accNumber);
217
      pstmt.execute();
218
      ResultSet rs = pstmt.getResultSet();
219
      hasCurrentAccNumber = rs.next();
220
      pstmt.close();
221

    
222
    } catch (SQLException e) {
223
      throw new SQLException(
224
          "Error on AccessionNumber.accNumberIsCurrent(String accNumber): " +
225
          e.getMessage());
226
    }
227
    finally
228
    {
229
      DBConnectionPool.returnDBConnection(conn, serialNumber);
230
    }
231

    
232
    return hasCurrentAccNumber;
233
  }
234

    
235
  // get the recent revision number for docid
236
  private String getLastRevision(String docid) throws SQLException
237
  {
238
    String rev = "";
239
    DBConnection conn = null;
240
    int serialNumber = -1;
241

    
242
    try {
243
      PreparedStatement pstmt = null;
244
      //check out DBConnection
245
      conn=DBConnectionPool.getDBConnection("AccessionNumber.getLastRevision");
246
      serialNumber=conn.getCheckOutSerialNumber();
247
      pstmt = conn.prepareStatement
248
              ("SELECT rev FROM xml_documents WHERE docid='" + docid + "'");
249
      pstmt.execute();
250

    
251
      ResultSet rs = pstmt.getResultSet();
252
      boolean hasRow = rs.next();
253
      rev = rs.getString(1);
254
      pstmt.close();
255

    
256
    } catch (SQLException e) {
257
      throw new SQLException(
258
      "Error on AccessionNumber.getLastRevision(): " + e.getMessage());
259
    }
260
    finally
261
    {
262
      DBConnectionPool.returnDBConnection(conn,serialNumber);
263
    }
264

    
265
    return rev;
266
  }
267

    
268
  /**
269
    * Get last revision number from database for a docid
270
    * The return value is integer because we want compare it to there new one
271
    * @param docid <sitecode>.<uniqueid> part of Accession Number
272
    */
273
  private int getLastRevisionNumber(String docId) throws SQLException
274
  {
275
    int rev = 1;
276
    DBConnection conn =null;
277
    int serialNumber = -1;
278

    
279
    try {
280
      PreparedStatement pStmt = null;
281
      //check out DBConnection
282
      conn=DBConnectionPool.getDBConnection("AccessionNumber.getLastRevisionN");
283
      serialNumber=conn.getCheckOutSerialNumber();
284

    
285
      pStmt = conn.prepareStatement
286
              ("SELECT rev FROM xml_documents WHERE docid='" + docId + "'");
287
      pStmt.execute();
288

    
289
      ResultSet rs = pStmt.getResultSet();
290
      boolean hasRow = rs.next();
291
      rev = rs.getInt(1);
292
      pStmt.close();
293

    
294
    } catch (SQLException e) {
295
      throw new SQLException(
296
      "Error on AccessionNumber.getLastRevision(): " + e.getMessage());
297
    }
298
    finally
299
    {
300
      DBConnectionPool.returnDBConnection(conn,serialNumber);
301
    }
302
    return rev;
303
  }
304

    
305
  /**
306
   * returns the docid encoded in this accession number
307
   */
308
  public String getDocid() {
309

    
310
    return this.docid;
311
  }
312

    
313
  /**
314
   * returns the revision number encoded in this accession number
315
   */
316
  public String getRev()
317
  {
318
    return this.rev;
319
  }
320

    
321
}
(6-6/64)