Project

General

Profile

1 145 bojilova
/**
2 203 jones
 *  '$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 349 jones
 *    Release: @release@
9 145 bojilova
 *
10 203 jones
 *   '$Author$'
11
 *     '$Date$'
12
 * '$Revision$'
13 669 jones
 *
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 145 bojilova
 */
28
29
package edu.ucsb.nceas.metacat;
30
31 2768 jones
import java.sql.PreparedStatement;
32
import java.sql.ResultSet;
33
import java.sql.SQLException;
34 145 bojilova
35 777 bojilova
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
36 747 bojilova
37 147 bojilova
/**
38 459 bojilova
 * (on insert of XML document)
39 2246 sgarg
 * Generates a unique Accession Number or if provided check it
40
 * for uniqueness and register it into the db connection
41 459 bojilova
 * (on update or delete of XML document)
42
 * Check for existance of provided Accession Number
43 2246 sgarg
 *
44 147 bojilova
 */
45 145 bojilova
public class AccessionNumber  {
46 2246 sgarg
47 777 bojilova
  private static final AbstractDatabase dbAdapter = MetaCatUtil.dbAdapter;
48 747 bojilova
49 618 bojilova
  private String sitecode = null;
50 459 bojilova
  private String sep = null;
51 779 bojilova
  private String docid = null;
52
  private String rev = null;
53 2246 sgarg
54
  /**
55
   * Construct an AccessionNumber
56 459 bojilova
   */
57 2768 jones
  private AccessionNumber ()
58 734 bojilova
  {
59 779 bojilova
    this.sitecode = MetaCatUtil.getOption("sitecode");
60
    this.sep = MetaCatUtil.getOption("accNumSeparator");
61 459 bojilova
  }
62 160 bojilova
63 779 bojilova
  /** 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 2246 sgarg
  public AccessionNumber (String accnum, String action)
70 954 tao
           throws AccessionNumberException, SQLException, NumberFormatException
71
 {
72 1215 tao
    this();
73 779 bojilova
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 2246 sgarg
86 779 bojilova
    // INSERT
87
    if ( action.equals("INSERT")) {
88
89 2253 sgarg
        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 779 bojilova
      // check accession number for validness
100
      if ( docid == null ) {
101 2253 sgarg
        throw new AccessionNumberException("Accession number is required");
102 779 bojilova
103
      // rev is not provided; throw an exception to prevent the insertion
104
      } else if ( rev == null ) {
105
        throw new AccessionNumberException
106 2253 sgarg
                  ("Revision number is required");
107 779 bojilova
108
      // docid is used; throw an exception to prevent the insertion
109
      } else if ( accNumberUsed(docid) ) {
110
        throw new AccessionNumberException
111 2253 sgarg
                  ("Accession number " + docid + " is already in use");
112 2246 sgarg
113 779 bojilova
      // rev is <> 1; throw an exception to prevent the insertion
114 1054 tao
      } /*else if ( !rev.equals("1")) {
115 2253 sgarg
        throw new AccessionNumberException("Revision number must be 1");
116 1054 tao
      }*/
117 2246 sgarg
118 779 bojilova
    // UPDATE or DELETE
119
    } else if ( action.equals("UPDATE") || action.equals("DELETE")) {
120
      String l_rev = "";
121
122 2246 sgarg
      int reversionNumber = 1;
123
124
      if(rev != null){
125 2253 sgarg
          try{
126
              reversionNumber = Integer.parseInt(rev);
127
          } catch (java.lang.NumberFormatException e){
128
              throw new AccessionNumberException(
129
                      "Revision number is required");
130
          }
131 2246 sgarg
      }
132
133 779 bojilova
      // Accession# is not provided; throw an exception to prevent the action
134
      if ( docid == null ) {
135 2253 sgarg
        throw new AccessionNumberException("Accession number is required");
136 779 bojilova
137
      // rev is not provided; throw an exception to prevent the action
138
      } else if ( rev == null ) {
139
        throw new AccessionNumberException
140 2253 sgarg
                  ("Revision number is required");
141 779 bojilova
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 954 tao
      //Revision number is less than or equal the recent one; throw a exception
148 779 bojilova
      } else if ( action.equals("UPDATE") &&
149 954 tao
                  reversionNumber <= getLastRevisionNumber(docid) ) {
150 779 bojilova
        throw new AccessionNumberException
151 954 tao
                 ("Next revision number couldn't be less than or equal "
152
                                              + getLastRevisionNumber(docid));
153 779 bojilova
154
      // Revision number is not the recent one; throw an exception
155 2246 sgarg
      } else if ( action.equals("DELETE") &&
156 779 bojilova
                  !rev.equals(l_rev = getLastRevision(docid)) ) {
157
        throw new AccessionNumberException
158
                  ("Last revision number is "+ l_rev);
159
      }
160
    }
161
  }
162
163 459 bojilova
  /** check for existence of Accesssion Number xml_acc_numbers table */
164 2164 tao
  public static boolean accNumberUsed ( String accNumber )
165 576 bojilova
                  throws SQLException {
166 2246 sgarg
167 459 bojilova
    boolean hasAccNumber = false;
168 1215 tao
    DBConnection conn = null;
169
    int serialNumber = -1;
170 2246 sgarg
171 459 bojilova
    try {
172 1215 tao
      PreparedStatement pstmt = null;
173
      //check out DBConnection
174
      conn=DBConnectionPool.getDBConnection("AccessionNumber.accNumberUsed");
175
      serialNumber=conn.getCheckOutSerialNumber();
176 459 bojilova
      pstmt = conn.prepareStatement(
177 2246 sgarg
                "SELECT 'x' FROM xml_documents " +
178 770 bojilova
                "WHERE docid = ? " +
179 576 bojilova
                "UNION " +
180
                "SELECT 'x' FROM xml_revisions " +
181 770 bojilova
                "WHERE docid = ?");
182 576 bojilova
      pstmt.setString(1,accNumber);
183
      pstmt.setString(2,accNumber);
184 459 bojilova
      pstmt.execute();
185
      ResultSet rs = pstmt.getResultSet();
186
      hasAccNumber = rs.next();
187
      pstmt.close();
188 2246 sgarg
189 459 bojilova
    } catch (SQLException e) {
190 576 bojilova
      throw new SQLException
191
      ("Error on AccessionNumber.accNumberUsed(accNumber): " + e.getMessage());
192 1215 tao
    }
193
    finally
194
    {
195
      DBConnectionPool.returnDBConnection(conn, serialNumber);
196
    }
197 2246 sgarg
198 459 bojilova
    return hasAccNumber;
199 2246 sgarg
  }
200
201 734 bojilova
  // check for existence of Accesssion Number in xml_documents table
202 459 bojilova
  private boolean accNumberIsCurrent(String accNumber) throws SQLException {
203 2246 sgarg
204 459 bojilova
    boolean hasCurrentAccNumber = false;
205 1215 tao
    DBConnection conn = null;
206
    int serialNumber = -1;
207 2246 sgarg
208 459 bojilova
    try {
209 1215 tao
      PreparedStatement pstmt = null;
210
      //check out DBConnection
211
      conn=DBConnectionPool.getDBConnection("AccessionNumber.accNumberIsCurre");
212
      serialNumber=conn.getCheckOutSerialNumber();
213 459 bojilova
      pstmt = conn.prepareStatement(
214 2246 sgarg
                "SELECT 'x' FROM xml_documents " +
215 770 bojilova
                "WHERE docid = ?");
216 459 bojilova
      pstmt.setString(1, accNumber);
217
      pstmt.execute();
218
      ResultSet rs = pstmt.getResultSet();
219
      hasCurrentAccNumber = rs.next();
220
      pstmt.close();
221 2246 sgarg
222 459 bojilova
    } catch (SQLException e) {
223
      throw new SQLException(
224
          "Error on AccessionNumber.accNumberIsCurrent(String accNumber): " +
225
          e.getMessage());
226 1215 tao
    }
227
    finally
228
    {
229
      DBConnectionPool.returnDBConnection(conn, serialNumber);
230
    }
231 2246 sgarg
232 459 bojilova
    return hasCurrentAccNumber;
233 2246 sgarg
  }
234 203 jones
235 734 bojilova
  // get the recent revision number for docid
236
  private String getLastRevision(String docid) throws SQLException
237
  {
238
    String rev = "";
239 1215 tao
    DBConnection conn = null;
240
    int serialNumber = -1;
241 2246 sgarg
242 734 bojilova
    try {
243 1215 tao
      PreparedStatement pstmt = null;
244
      //check out DBConnection
245
      conn=DBConnectionPool.getDBConnection("AccessionNumber.getLastRevision");
246
      serialNumber=conn.getCheckOutSerialNumber();
247 734 bojilova
      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 2246 sgarg
256 734 bojilova
    } catch (SQLException e) {
257
      throw new SQLException(
258
      "Error on AccessionNumber.getLastRevision(): " + e.getMessage());
259
    }
260 1215 tao
    finally
261
    {
262
      DBConnectionPool.returnDBConnection(conn,serialNumber);
263
    }
264 734 bojilova
265
    return rev;
266
  }
267 2246 sgarg
268 954 tao
  /**
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 1215 tao
    DBConnection conn =null;
277
    int serialNumber = -1;
278 2246 sgarg
279 954 tao
    try {
280 1215 tao
      PreparedStatement pStmt = null;
281
      //check out DBConnection
282
      conn=DBConnectionPool.getDBConnection("AccessionNumber.getLastRevisionN");
283
      serialNumber=conn.getCheckOutSerialNumber();
284 2246 sgarg
285 954 tao
      pStmt = conn.prepareStatement
286
              ("SELECT rev FROM xml_documents WHERE docid='" + docId + "'");
287
      pStmt.execute();
288 734 bojilova
289 954 tao
      ResultSet rs = pStmt.getResultSet();
290
      boolean hasRow = rs.next();
291
      rev = rs.getInt(1);
292
      pStmt.close();
293 2246 sgarg
294 954 tao
    } catch (SQLException e) {
295
      throw new SQLException(
296
      "Error on AccessionNumber.getLastRevision(): " + e.getMessage());
297
    }
298 1215 tao
    finally
299
    {
300
      DBConnectionPool.returnDBConnection(conn,serialNumber);
301
    }
302 954 tao
    return rev;
303
  }
304 2246 sgarg
305 779 bojilova
  /**
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 2246 sgarg
321 203 jones
}