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 349 jones
 *    Release: @release@
9 145 bojilova
 *
10 203 jones
 *   '$Author$'
11
 *     '$Date$'
12
 * '$Revision$'
13 669 jones
 *
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 145 bojilova
 */
28
29
package edu.ucsb.nceas.metacat;
30
31
import java.net.*;
32
import java.sql.*;
33
34 147 bojilova
/**
35 459 bojilova
 * (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 147 bojilova
 */
42 145 bojilova
public class AccessionNumber  {
43 459 bojilova
44
  private Connection conn = null;
45 618 bojilova
  private String sitecode = null;
46 459 bojilova
  private String sep = null;
47 145 bojilova
48 459 bojilova
  /**
49
   * Construct an AccessionNumber
50
   */
51
  public AccessionNumber ()
52
         throws SQLException, ClassNotFoundException  {
53 145 bojilova
54 459 bojilova
    MetaCatUtil util = new MetaCatUtil();
55
56 618 bojilova
    this.sitecode = util.getOption("sitecode");
57
    this.sep = util.getOption("accNumSeparator");
58 459 bojilova
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 160 bojilova
70 459 bojilova
    MetaCatUtil util = new MetaCatUtil();
71 160 bojilova
72 618 bojilova
    this.sitecode = util.getOption("sitecode");
73
    this.sep = util.getOption("accNumSeparator");
74 459 bojilova
    this.conn = conn;
75 160 bojilova
76 459 bojilova
  }
77 160 bojilova
78 459 bojilova
  /**
79 576 bojilova
   * Generate an Accession Number of form <sidecode>.<createdate>
80
   */
81
  public String generate(String accNumber, String action)
82
                throws AccessionNumberException, SQLException
83
  {
84
    try {
85
      // INSERT
86
      if ( action.equals("INSERT")) {
87
88
        // get a new Accession#
89
        if ( accNumber == null ) {
90 618 bojilova
          String sitecode = getSitecode();
91
          String uniqueid = getUniqueID();
92 576 bojilova
93 618 bojilova
          return sitecode + sep + uniqueid;
94
95 576 bojilova
        // Accession# is not used; return it
96
        } else if ( !accNumberUsed(accNumber) ) {
97
          return accNumber;
98
99
        // Accession# is used; throw an exception to prevent the insertion
100
        } else {
101
          throw new AccessionNumberException
102
                    ("Accession number " + accNumber + " is already in use.");
103
        }
104
105
      // UPDATE or DELETE
106
      } else if ( action.equals("UPDATE") || action.equals("DELETE")) {
107
108
        // Accession# is not provided; throw an exception to prevent the action
109
        if ( accNumber == null ) {
110
          throw new AccessionNumberException("Accession number is required.");
111
112
        // Accession# is not current (not in xml_documents); throw an exception
113
        } else if ( !accNumberIsCurrent(accNumber) ) {
114
          throw new AccessionNumberException
115
          ("Document not found for Accession number " + accNumber);
116
117
        // Accession# is current (present in xml_documents); return it
118
        } else {
119
          return accNumber;
120
        }
121
      }
122
123
    } catch (SQLException e) {
124
      throw new SQLException
125
      ("Error on AccessionNumber.generate(accNumber, action): "+e.getMessage());
126
    }
127
128
    // never comes here
129
    throw new
130
    AccessionNumberException("Fatal Error in accession number generation.");
131
  }
132
133 618 bojilova
  // get local sitecode
134
  private String getSitecode()
135 576 bojilova
  {
136 618 bojilova
    return this.sitecode;
137 576 bojilova
  }
138
139 618 bojilova
  // get Unique ID from DB sequence
140
  private String getUniqueID () throws SQLException
141 576 bojilova
  {
142 618 bojilova
    String uniqueid;
143 576 bojilova
144
    try {
145
      PreparedStatement pstmt;
146
      pstmt = conn.prepareStatement
147 618 bojilova
              ("SELECT accnum_uniqueid_seq.nextval FROM dual");
148 576 bojilova
      pstmt.execute();
149
150
      ResultSet rs = pstmt.getResultSet();
151
      boolean hasRow = rs.next();
152 618 bojilova
      uniqueid = rs.getString(1);
153 576 bojilova
      pstmt.close();
154
155
    } catch (SQLException e) {
156
      throw new
157 618 bojilova
      SQLException("Error on AccessionNumber.getUniqueID(): "+e.getMessage());
158 576 bojilova
    }
159
160 618 bojilova
    return uniqueid;
161 576 bojilova
  }
162
163 459 bojilova
  /** check for existence of Accesssion Number xml_acc_numbers table */
164 582 berkley
  public boolean accNumberUsed ( String accNumber )
165 576 bojilova
                  throws SQLException {
166 145 bojilova
167 459 bojilova
    boolean hasAccNumber = false;
168 145 bojilova
169 459 bojilova
    try {
170
      PreparedStatement pstmt;
171
      pstmt = conn.prepareStatement(
172 576 bojilova
                "SELECT 'x' FROM xml_documents " +
173
                "WHERE docid LIKE ? " +
174
                "UNION " +
175
                "SELECT 'x' FROM xml_revisions " +
176
                "WHERE docid LIKE ?");
177
      pstmt.setString(1,accNumber);
178
      pstmt.setString(2,accNumber);
179 459 bojilova
      pstmt.execute();
180
      ResultSet rs = pstmt.getResultSet();
181
      hasAccNumber = rs.next();
182
      pstmt.close();
183 145 bojilova
184 459 bojilova
    } catch (SQLException e) {
185 576 bojilova
      throw new SQLException
186
      ("Error on AccessionNumber.accNumberUsed(accNumber): " + e.getMessage());
187 459 bojilova
    }
188 145 bojilova
189 459 bojilova
    return hasAccNumber;
190
  }
191 145 bojilova
192 459 bojilova
  /** check for existence of Accesssion Number in xml_documents table */
193
  private boolean accNumberIsCurrent(String accNumber) throws SQLException {
194 203 jones
195 459 bojilova
    boolean hasCurrentAccNumber = false;
196 203 jones
197 459 bojilova
    try {
198
      PreparedStatement pstmt;
199
      pstmt = conn.prepareStatement(
200 203 jones
                "SELECT 'x' FROM xml_documents " +
201
                "WHERE docid LIKE ?");
202 459 bojilova
      pstmt.setString(1, accNumber);
203
      pstmt.execute();
204
      ResultSet rs = pstmt.getResultSet();
205
      hasCurrentAccNumber = rs.next();
206
      pstmt.close();
207 203 jones
208 459 bojilova
    } catch (SQLException e) {
209
      throw new SQLException(
210
          "Error on AccessionNumber.accNumberIsCurrent(String accNumber): " +
211
          e.getMessage());
212 203 jones
    }
213 459 bojilova
214
    return hasCurrentAccNumber;
215
  }
216 203 jones
217
}