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 4080 daigle
import edu.ucsb.nceas.metacat.service.PropertyService;
35
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
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 618 bojilova
  private String sitecode = null;
48 459 bojilova
  private String sep = null;
49 779 bojilova
  private String docid = null;
50
  private String rev = null;
51 2246 sgarg
52 4080 daigle
    /**
53
	 * Construct an AccessionNumber
54
	 */
55
	private AccessionNumber() throws AccessionNumberException {
56
		try {
57 4212 daigle
			this.sitecode = PropertyService.getProperty("document.sitecode");
58
			this.sep = PropertyService.getProperty("document.accNumSeparator");
59 4080 daigle
		} catch (PropertyNotFoundException pnfe) {
60
			throw new AccessionNumberException("Could not retrieve property "
61
					+ "in constructor: " + pnfe.getMessage());
62
		}
63
	}
64
65 2246 sgarg
  /**
66 4080 daigle
	 * NEW - WHEN CLIENT ALWAYS PROVIDE ACCESSION NUMBER INCLUDING REV IN IT
67
	 * Construct an AccessionNumber
68
	 *
69
	 * @param conn
70
	 *            the db connection to read Accession number from
71
	 * @param accnum
72
	 *            the accession number to be checked for validness
73
	 */
74 2246 sgarg
  public AccessionNumber (String accnum, String action)
75 954 tao
           throws AccessionNumberException, SQLException, NumberFormatException
76
 {
77 1215 tao
    this();
78 779 bojilova
79
    this.rev = null;
80
    this.docid = accnum;
81
    if ( accnum != null ) {
82
      int firstIndex = accnum.indexOf(this.sep);
83
      int lastIndex = accnum.lastIndexOf(this.sep);
84
      if ( firstIndex != lastIndex ) {
85
        //this docid contains a revision number
86
        this.rev = accnum.substring(lastIndex + 1);
87
        this.docid = accnum.substring(0, lastIndex);
88
      }
89
    }
90 2246 sgarg
91 779 bojilova
    // INSERT
92
    if ( action.equals("INSERT")) {
93
94 2253 sgarg
        if(rev != null){
95
            try {
96
                Integer.parseInt(rev);
97
            }
98
            catch (java.lang.NumberFormatException e) {
99
                throw new AccessionNumberException(
100
                    "Revision number is required");
101
            }
102
        }
103
104 779 bojilova
      // check accession number for validness
105
      if ( docid == null ) {
106 2253 sgarg
        throw new AccessionNumberException("Accession number is required");
107 779 bojilova
108
      // rev is not provided; throw an exception to prevent the insertion
109
      } else if ( rev == null ) {
110
        throw new AccessionNumberException
111 2253 sgarg
                  ("Revision number is required");
112 779 bojilova
113
      // docid is used; throw an exception to prevent the insertion
114
      } else if ( accNumberUsed(docid) ) {
115
        throw new AccessionNumberException
116 2253 sgarg
                  ("Accession number " + docid + " is already in use");
117 2246 sgarg
118 779 bojilova
      // rev is <> 1; throw an exception to prevent the insertion
119 1054 tao
      } /*else if ( !rev.equals("1")) {
120 2253 sgarg
        throw new AccessionNumberException("Revision number must be 1");
121 1054 tao
      }*/
122 2246 sgarg
123 779 bojilova
    // UPDATE or DELETE
124
    } else if ( action.equals("UPDATE") || action.equals("DELETE")) {
125
      String l_rev = "";
126
127 2246 sgarg
      int reversionNumber = 1;
128
129
      if(rev != null){
130 2253 sgarg
          try{
131
              reversionNumber = Integer.parseInt(rev);
132
          } catch (java.lang.NumberFormatException e){
133
              throw new AccessionNumberException(
134
                      "Revision number is required");
135
          }
136 2246 sgarg
      }
137
138 779 bojilova
      // Accession# is not provided; throw an exception to prevent the action
139
      if ( docid == null ) {
140 2253 sgarg
        throw new AccessionNumberException("Accession number is required");
141 779 bojilova
142
      // rev is not provided; throw an exception to prevent the action
143
      } else if ( rev == null ) {
144
        throw new AccessionNumberException
145 2253 sgarg
                  ("Revision number is required");
146 779 bojilova
147
      // Accession# is not current (not in xml_documents); throw an exception
148
      } else if ( !accNumberIsCurrent(docid) ) {
149
        throw new AccessionNumberException
150
                  ("Document not found for Accession number " + docid);
151
152 954 tao
      //Revision number is less than or equal the recent one; throw a exception
153 779 bojilova
      } else if ( action.equals("UPDATE") &&
154 954 tao
                  reversionNumber <= getLastRevisionNumber(docid) ) {
155 779 bojilova
        throw new AccessionNumberException
156 954 tao
                 ("Next revision number couldn't be less than or equal "
157
                                              + getLastRevisionNumber(docid));
158 779 bojilova
159
      // Revision number is not the recent one; throw an exception
160 2246 sgarg
      } else if ( action.equals("DELETE") &&
161 779 bojilova
                  !rev.equals(l_rev = getLastRevision(docid)) ) {
162
        throw new AccessionNumberException
163
                  ("Last revision number is "+ l_rev);
164
      }
165
    }
166
  }
167
168 459 bojilova
  /** check for existence of Accesssion Number xml_acc_numbers table */
169 2164 tao
  public static boolean accNumberUsed ( String accNumber )
170 576 bojilova
                  throws SQLException {
171 2246 sgarg
172 459 bojilova
    boolean hasAccNumber = false;
173 1215 tao
    DBConnection conn = null;
174
    int serialNumber = -1;
175 2246 sgarg
176 459 bojilova
    try {
177 1215 tao
      PreparedStatement pstmt = null;
178
      //check out DBConnection
179
      conn=DBConnectionPool.getDBConnection("AccessionNumber.accNumberUsed");
180
      serialNumber=conn.getCheckOutSerialNumber();
181 459 bojilova
      pstmt = conn.prepareStatement(
182 2246 sgarg
                "SELECT 'x' FROM xml_documents " +
183 770 bojilova
                "WHERE docid = ? " +
184 576 bojilova
                "UNION " +
185
                "SELECT 'x' FROM xml_revisions " +
186 770 bojilova
                "WHERE docid = ?");
187 576 bojilova
      pstmt.setString(1,accNumber);
188
      pstmt.setString(2,accNumber);
189 459 bojilova
      pstmt.execute();
190
      ResultSet rs = pstmt.getResultSet();
191
      hasAccNumber = rs.next();
192
      pstmt.close();
193 2246 sgarg
194 459 bojilova
    } catch (SQLException e) {
195 576 bojilova
      throw new SQLException
196
      ("Error on AccessionNumber.accNumberUsed(accNumber): " + e.getMessage());
197 1215 tao
    }
198
    finally
199
    {
200
      DBConnectionPool.returnDBConnection(conn, serialNumber);
201
    }
202 2246 sgarg
203 459 bojilova
    return hasAccNumber;
204 2246 sgarg
  }
205
206 734 bojilova
  // check for existence of Accesssion Number in xml_documents table
207 459 bojilova
  private boolean accNumberIsCurrent(String accNumber) throws SQLException {
208 2246 sgarg
209 459 bojilova
    boolean hasCurrentAccNumber = false;
210 1215 tao
    DBConnection conn = null;
211
    int serialNumber = -1;
212 2246 sgarg
213 459 bojilova
    try {
214 1215 tao
      PreparedStatement pstmt = null;
215
      //check out DBConnection
216
      conn=DBConnectionPool.getDBConnection("AccessionNumber.accNumberIsCurre");
217
      serialNumber=conn.getCheckOutSerialNumber();
218 459 bojilova
      pstmt = conn.prepareStatement(
219 2246 sgarg
                "SELECT 'x' FROM xml_documents " +
220 770 bojilova
                "WHERE docid = ?");
221 459 bojilova
      pstmt.setString(1, accNumber);
222
      pstmt.execute();
223
      ResultSet rs = pstmt.getResultSet();
224
      hasCurrentAccNumber = rs.next();
225
      pstmt.close();
226 2246 sgarg
227 459 bojilova
    } catch (SQLException e) {
228
      throw new SQLException(
229
          "Error on AccessionNumber.accNumberIsCurrent(String accNumber): " +
230
          e.getMessage());
231 1215 tao
    }
232
    finally
233
    {
234
      DBConnectionPool.returnDBConnection(conn, serialNumber);
235
    }
236 2246 sgarg
237 459 bojilova
    return hasCurrentAccNumber;
238 2246 sgarg
  }
239 203 jones
240 734 bojilova
  // get the recent revision number for docid
241
  private String getLastRevision(String docid) throws SQLException
242
  {
243
    String rev = "";
244 1215 tao
    DBConnection conn = null;
245
    int serialNumber = -1;
246 2246 sgarg
247 734 bojilova
    try {
248 1215 tao
      PreparedStatement pstmt = null;
249
      //check out DBConnection
250
      conn=DBConnectionPool.getDBConnection("AccessionNumber.getLastRevision");
251
      serialNumber=conn.getCheckOutSerialNumber();
252 734 bojilova
      pstmt = conn.prepareStatement
253
              ("SELECT rev FROM xml_documents WHERE docid='" + docid + "'");
254
      pstmt.execute();
255
256
      ResultSet rs = pstmt.getResultSet();
257
      boolean hasRow = rs.next();
258
      rev = rs.getString(1);
259
      pstmt.close();
260 2246 sgarg
261 734 bojilova
    } catch (SQLException e) {
262
      throw new SQLException(
263
      "Error on AccessionNumber.getLastRevision(): " + e.getMessage());
264
    }
265 1215 tao
    finally
266
    {
267
      DBConnectionPool.returnDBConnection(conn,serialNumber);
268
    }
269 734 bojilova
270
    return rev;
271
  }
272 2246 sgarg
273 954 tao
  /**
274
    * Get last revision number from database for a docid
275
    * The return value is integer because we want compare it to there new one
276
    * @param docid <sitecode>.<uniqueid> part of Accession Number
277
    */
278
  private int getLastRevisionNumber(String docId) throws SQLException
279
  {
280
    int rev = 1;
281 1215 tao
    DBConnection conn =null;
282
    int serialNumber = -1;
283 2246 sgarg
284 954 tao
    try {
285 1215 tao
      PreparedStatement pStmt = null;
286
      //check out DBConnection
287
      conn=DBConnectionPool.getDBConnection("AccessionNumber.getLastRevisionN");
288
      serialNumber=conn.getCheckOutSerialNumber();
289 2246 sgarg
290 954 tao
      pStmt = conn.prepareStatement
291
              ("SELECT rev FROM xml_documents WHERE docid='" + docId + "'");
292
      pStmt.execute();
293 734 bojilova
294 954 tao
      ResultSet rs = pStmt.getResultSet();
295
      boolean hasRow = rs.next();
296
      rev = rs.getInt(1);
297
      pStmt.close();
298 2246 sgarg
299 954 tao
    } catch (SQLException e) {
300
      throw new SQLException(
301
      "Error on AccessionNumber.getLastRevision(): " + e.getMessage());
302
    }
303 1215 tao
    finally
304
    {
305
      DBConnectionPool.returnDBConnection(conn,serialNumber);
306
    }
307 954 tao
    return rev;
308
  }
309 2246 sgarg
310 779 bojilova
  /**
311
   * returns the docid encoded in this accession number
312
   */
313
  public String getDocid() {
314
315
    return this.docid;
316
  }
317
318
  /**
319
   * returns the revision number encoded in this accession number
320
   */
321
  public String getRev()
322
  {
323
    return this.rev;
324
  }
325 2246 sgarg
326 203 jones
}