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
 *    Release: @release@
9
 *
10
 *   '$Author: bojilova $'
11
 *     '$Date: 2001-06-04 13:47:18 -0700 (Mon, 04 Jun 2001) $'
12
 * '$Revision: 770 $'
13
 *
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
 */
28

    
29
package edu.ucsb.nceas.metacat;
30

    
31
import java.net.*;
32
import java.sql.*;
33

    
34
import edu.ucsb.nceas.dbadapter.DBAdapter;
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 DBAdapter dbAdapter = MetaCatUtil.dbAdapter;
47

    
48
  private Connection conn = null;
49
  private String sitecode = null;
50
  private String sep = null;
51
    
52
  /** 
53
   * Construct an AccessionNumber 
54
   */
55
  public AccessionNumber () 
56
         throws SQLException, ClassNotFoundException  
57
  {
58
    MetaCatUtil util = new MetaCatUtil();
59

    
60
    this.sitecode = util.getOption("sitecode");
61
    this.sep = util.getOption("accNumSeparator");
62

    
63
    // Open a connection to the database
64
    this.conn = util.openDBConnection();
65
  }  
66

    
67
  /** 
68
   * Construct an AccessionNumber
69
   *
70
   * @param conn the db connection to read from and write Accession# to
71
   */
72
  public AccessionNumber (Connection conn) 
73
  {
74
    MetaCatUtil util = new MetaCatUtil();
75

    
76
    this.sitecode = util.getOption("sitecode");
77
    this.sep = util.getOption("accNumSeparator");
78
    this.conn = conn;
79
  }
80

    
81
  /**
82
   * Generate an Accession Number of form <sidecode>.<uniqueid>.<revisionid>
83
   * where <revisionid> is always 1.
84
   *
85
   * @param docid <sitecode>.<uniqueid> part of Accession Number
86
   * @param action INSERT, UPDATE or DELETE action
87
   */
88
  public String generate(String docid, String action) 
89
                throws AccessionNumberException, SQLException 
90
  {
91
    return generate(docid, "1", action);
92
  }
93

    
94
  /**
95
   * Generate an Accession Number of form <sidecode>.<uniqueid>.<revisionid>
96
   *
97
   * @param docid <sitecode>.<uniqueid> part of Accession Number
98
   * @param rev <revisionid> of Accession Number
99
   * @param action INSERT, UPDATE or DELETE action
100
   */
101
  public String generate(String docid, String rev, String action) 
102
                throws AccessionNumberException, SQLException 
103
  {
104
    try {
105
      // INSERT
106
      if ( action.equals("INSERT")) {
107

    
108
        // get a new docid
109
        if ( docid == null ) {
110
          String sitecode = getSitecode();
111
          String uniqueid = getUniqueID(sitecode);
112

    
113
          return sitecode + sep + uniqueid;
114

    
115
        // docid is used; throw an exception to prevent the insertion
116
        } else if ( accNumberUsed(docid) ) {
117
          throw new AccessionNumberException
118
                    ("Accession number " + docid + " is already in use.");
119
        // rev is <> 1; throw an exception to prevent the insertion
120
        } else if ( !rev.equals("1") ) {
121
          throw new AccessionNumberException
122
                    ("Revision number must be 1.");
123
        // docid is not used and rev=1; return it
124
        } else {
125
          return docid;
126
        }
127

    
128
      // UPDATE or DELETE
129
      } else if ( action.equals("UPDATE") || action.equals("DELETE")) {
130

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

    
135
        // Accession# is not current (not in xml_documents); throw an exception
136
        } else if ( !accNumberIsCurrent(docid) ) {
137
          throw new AccessionNumberException
138
          ("Document not found for Accession number " + docid);
139

    
140
        // Revision number is not the recent one; throw an exception
141
        } else if ( !rev.equals(getLastRevision(docid)) ) {
142
          throw new AccessionNumberException
143
          ("Revision number must be the recent.");
144

    
145
        // Accession# is current (present in xml_documents); return it
146
        } else {
147
          return docid;
148
        }
149
      }
150
 
151
    } catch (SQLException e) {
152
      throw new SQLException
153
      ("Error on AccessionNumber.generate(): " + e.getMessage());
154
    }    
155
 
156
    // never comes here
157
    throw new
158
    AccessionNumberException("Fatal Error in accession number generation.");
159
  }
160
  
161
  // get local sitecode
162
  private String getSitecode()
163
  {
164
    return this.sitecode;
165
  }
166

    
167
  // get Unique ID from DB sequence
168
  private String getUniqueID (String sitecode) throws SQLException
169
  {
170
    String uniqueid;
171
    String sysdate = dbAdapter.getDateTimeFunction();
172
    
173
    try {
174
      PreparedStatement pstmt;
175
      pstmt = conn.prepareStatement
176
              ("INSERT INTO accession_number (site_code, date_created) " +
177
               "VALUES (?, " + sysdate + ")");
178
      pstmt.setString(1, sitecode);
179
      pstmt.execute();
180
      pstmt.close();
181
      
182
      uniqueid = "" + dbAdapter.getUniqueID(conn, "accession_number");
183

    
184
    } catch (SQLException e) {
185
      throw new 
186
      SQLException("Error on AccessionNumber.getUniqueID(): "+e.getMessage());
187
    }
188

    
189
    return uniqueid;
190
  }
191

    
192
  /** check for existence of Accesssion Number xml_acc_numbers table */
193
  public boolean accNumberUsed ( String accNumber )
194
                  throws SQLException {
195
        
196
    boolean hasAccNumber = false;
197
        
198
    try {
199
      PreparedStatement pstmt;
200
      pstmt = conn.prepareStatement(
201
                "SELECT 'x' FROM xml_documents " + 
202
                "WHERE docid = ? " +
203
                "UNION " +
204
                "SELECT 'x' FROM xml_revisions " +
205
                "WHERE docid = ?");
206
      pstmt.setString(1,accNumber);
207
      pstmt.setString(2,accNumber);
208
      pstmt.execute();
209
      ResultSet rs = pstmt.getResultSet();
210
      hasAccNumber = rs.next();
211
      pstmt.close();
212
            
213
    } catch (SQLException e) {
214
      throw new SQLException
215
      ("Error on AccessionNumber.accNumberUsed(accNumber): " + e.getMessage());
216
    }    
217
        
218
    return hasAccNumber;
219
  }    
220
    
221
  // check for existence of Accesssion Number in xml_documents table
222
  private boolean accNumberIsCurrent(String accNumber) throws SQLException {
223
        
224
    boolean hasCurrentAccNumber = false;
225
        
226
    try {
227
      PreparedStatement pstmt;
228
      pstmt = conn.prepareStatement(
229
                "SELECT 'x' FROM xml_documents " + 
230
                "WHERE docid = ?");
231
      pstmt.setString(1, accNumber);
232
      pstmt.execute();
233
      ResultSet rs = pstmt.getResultSet();
234
      hasCurrentAccNumber = rs.next();
235
      pstmt.close();
236
            
237
    } catch (SQLException e) {
238
      throw new SQLException(
239
          "Error on AccessionNumber.accNumberIsCurrent(String accNumber): " +
240
          e.getMessage());
241
    }    
242
  
243
    return hasCurrentAccNumber;
244
  }    
245

    
246
  // get the recent revision number for docid
247
  private String getLastRevision(String docid) throws SQLException
248
  {
249
    String rev = "";
250
    
251
    try {
252
      PreparedStatement pstmt;
253
      pstmt = conn.prepareStatement
254
              ("SELECT rev FROM xml_documents WHERE docid='" + docid + "'");
255
      pstmt.execute();
256

    
257
      ResultSet rs = pstmt.getResultSet();
258
      boolean hasRow = rs.next();
259
      rev = rs.getString(1);
260
      pstmt.close();
261
      
262
    } catch (SQLException e) {
263
      throw new SQLException(
264
      "Error on AccessionNumber.getLastRevision(): " + e.getMessage());
265
    }
266

    
267
    return rev;
268
  }
269

    
270
}
(2-2/43)