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
 *
9
 *   '$Author: jones $'
10
 *     '$Date: 2006-11-10 10:25:38 -0800 (Fri, 10 Nov 2006) $'
11
 * '$Revision: 3077 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27

    
28
package edu.ucsb.nceas.metacat;
29

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
121
      int reversionNumber = 1;
122

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

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

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

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

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

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

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

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

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

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

    
197
    return hasAccNumber;
198
  }
199

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

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

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

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

    
231
    return hasCurrentAccNumber;
232
  }
233

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

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

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

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

    
264
    return rev;
265
  }
266

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

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

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

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

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

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

    
309
    return this.docid;
310
  }
311

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

    
320
}
(6-6/66)