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-05-04 09:16:43 -0700 (Fri, 04 May 2001) $'
12
 * '$Revision: 735 $'
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
/**
35
 * (on insert of XML document)
36
 * Generates a unique Accession Number or if provided check it 
37
 * for uniqueness and register it into the db connection 
38
 * (on update or delete of XML document)
39
 * Check for existance of provided Accession Number
40
 * 
41
 */
42
public class AccessionNumber  {
43
  
44
  private Connection conn = null;
45
  private String sitecode = null;
46
  private String sep = null;
47
    
48
  /** 
49
   * Construct an AccessionNumber 
50
   */
51
  public AccessionNumber () 
52
         throws SQLException, ClassNotFoundException  
53
  {
54
    MetaCatUtil util = new MetaCatUtil();
55

    
56
    this.sitecode = util.getOption("sitecode");
57
    this.sep = util.getOption("accNumSeparator");
58

    
59
    // Open a connection to the database
60
    this.conn = util.openDBConnection();
61
  }  
62

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

    
72
    this.sitecode = util.getOption("sitecode");
73
    this.sep = util.getOption("accNumSeparator");
74
    this.conn = conn;
75
  }
76

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

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

    
104
        // get a new docid
105
        if ( docid == null ) {
106
          String sitecode = getSitecode();
107
          String uniqueid = getUniqueID();
108

    
109
          return sitecode + sep + uniqueid;
110

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

    
124
      // UPDATE or DELETE
125
      } else if ( action.equals("UPDATE") || action.equals("DELETE")) {
126

    
127
        // Accession# is not provided; throw an exception to prevent the action
128
        if ( docid == null ) {
129
          throw new AccessionNumberException("Accession number is required.");
130

    
131
        // Accession# is not current (not in xml_documents); throw an exception
132
        } else if ( !accNumberIsCurrent(docid) ) {
133
          throw new AccessionNumberException
134
          ("Document not found for Accession number " + docid);
135

    
136
        // Revision number is not the recent one; throw an exception
137
        } else if ( !rev.equals(getLastRevision(docid)) ) {
138
          throw new AccessionNumberException
139
          ("Revision number must be the recent.");
140

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

    
163
  // get Unique ID from DB sequence
164
  private String getUniqueID () throws SQLException
165
  {
166
    String uniqueid;
167
    
168
    try {
169
      PreparedStatement pstmt;
170
      pstmt = conn.prepareStatement
171
              ("SELECT accnum_uniqueid_seq.nextval FROM dual");
172
      pstmt.execute();
173

    
174
      ResultSet rs = pstmt.getResultSet();
175
      boolean hasRow = rs.next();
176
      uniqueid = rs.getString(1);
177
      pstmt.close();
178
      
179
    } catch (SQLException e) {
180
      throw new 
181
      SQLException("Error on AccessionNumber.getUniqueID(): "+e.getMessage());
182
    }
183

    
184
    return uniqueid;
185
  }
186

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

    
241
  // get the recent revision number for docid
242
  private String getLastRevision(String docid) throws SQLException
243
  {
244
    String rev = "";
245
    
246
    try {
247
      PreparedStatement pstmt;
248
      pstmt = conn.prepareStatement
249
              ("SELECT rev FROM xml_documents WHERE docid='" + docid + "'");
250
      pstmt.execute();
251

    
252
      ResultSet rs = pstmt.getResultSet();
253
      boolean hasRow = rs.next();
254
      rev = rs.getString(1);
255
      pstmt.close();
256
      
257
    } catch (SQLException e) {
258
      throw new SQLException(
259
      "Error on AccessionNumber.getLastRevision(): " + e.getMessage());
260
    }
261

    
262
    return rev;
263
  }
264

    
265
}
(2-2/43)