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