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