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
 *
9
 *   '$Author: jones $'
10
 *     '$Date: 2000-06-26 21:31:07 -0700 (Mon, 26 Jun 2000) $'
11
 * '$Revision: 204 $'
12
 */
13

    
14
package edu.ucsb.nceas.metacat;
15

    
16
import java.net.*;
17
import java.sql.*;
18

    
19
/**
20
 * A class that generates an Accession Number and will check a submitted
21
 * accession number for uniqueness and register it into the db connection
22
 */
23
public class AccessionNumber  {
24
    
25
    /**
26
     * Get an accession number from the user, check it for uniqueness 
27
     * and register it into new db connection. If no accession number is
28
     * provided by the user, generate one from the database and return it.
29
     *
30
     * @param accNumber - accession # if provided or null if not
31
     * @param action - INSERT, UPDATE or DELETE.
32
     * When "INSERT" and accession # provided is not unique, get next one.
33
     * If it is unique, use it.
34
     * When "INSERT" and accession # is null, get a new one.
35
     * When "UPDATE", accession # is required. 
36
     * When "DELETE", accession # is required. 
37
     */
38
    public static String generate (String accNumber, String action) 
39
        throws AccessionNumberException, SQLException, ClassNotFoundException
40
    {
41
        
42
        String globalName = null;
43
        String localId = null;
44
        
45
        // Open a connection to the database
46
        MetaCatUtil   util = new MetaCatUtil();
47

    
48
        String defaultGlobalName = util.getOption("defaultGlobalName");
49
        String sep = util.getOption("accNumberSeparator");
50

    
51
        try {
52
            // Open a new connection to the database
53
            Connection conn = util.openDBConnection();
54
            conn.setAutoCommit(true);
55

    
56
            // split the acc # in 2 parts - global name & local id
57
            if ( accNumber != null ) {
58
                globalName = getGlobalName(accNumber, sep);
59
                localId = getLocalId(accNumber, sep);
60
            }    
61

    
62
            // register unique acc #
63
            if ( action.equals("INSERT")) {
64
                if ( accNumber == null )
65
                  return put(conn, defaultGlobalName, null, sep);
66
                else
67
                  return put(conn, globalName, localId, sep);
68
            } else if ( action.equals("UPDATE") || action.equals("DELETE")) {
69
                if ( accNumber == null ) {
70
                  throw (new AccessionNumberException("Accession number is " +
71
                         "required."));
72
                } else if (!accNumberIsCurrent(conn, accNumber)) {
73
                  throw (new AccessionNumberException("Document " +
74
                         "not found for accession #: " + accNumber));
75
                } else {
76
                  return (globalName + sep + localId);
77
                }
78
            }
79
 
80
            conn.close();        
81

    
82
        } catch (StringIndexOutOfBoundsException siobe) {
83
            MetaCatUtil.debugMessage(
84
                       "Error on AccessionNumber.generate(): " + 
85
                       siobe.getMessage());
86
            throw (new AccessionNumberException("Accession number invalid, " +
87
                   "expecting character \'" + sep + "'."));
88
        } catch (SQLException e) {
89
            System.err.println(
90
                       "Error on AccessionNumber.genAccessionNumber(): " + 
91
                       e.getMessage());
92
            throw e;
93
        }    
94
        
95
        throw (new AccessionNumberException("Fatal Error in " +
96
               "accession number generation: "));
97
    }    
98

    
99
    /** put unique accession # into db connection */
100
    private static String put (Connection conn, String globalName, 
101
                String localId, String sep) 
102
                throws SQLException
103
    {
104
        
105
        Integer l = null;
106
        try {
107
            if ( localId == null ) 
108
                l = new Integer(get(conn, globalName) + 1); 
109
            else if ( accNumberUsed(conn, globalName, localId) )
110
                l = new Integer(get(conn, globalName) + 1); 
111
            else
112
                l = new Integer(localId); 
113

    
114
            // insert globalName & l
115
            PreparedStatement pstmt;
116
            pstmt = conn.prepareStatement(
117
                    "INSERT INTO xml_acc_numbers (global_name, local_id) " + 
118
                    "VALUES (?, ?)");
119
            pstmt.setString(1,globalName);
120
            pstmt.setString(2,l.toString());
121
            pstmt.execute();
122
            
123
            pstmt.close();
124
            
125
        } catch (SQLException e) {
126
            System.err.println(
127
                   "Error on AccessionNumber.put(conn, globalName, localId): " 
128
                   + e.getMessage());
129
            throw e;
130
        }    
131
        return globalName + sep + l;
132
    }
133

    
134
    /** check for existence of Accesssion Number xml_acc_numbers table */
135
    private static boolean accNumberUsed(Connection conn, String globalName, 
136
                String localId) throws SQLException {
137
        
138
      boolean hasAccNumber = false;
139
        
140
      try {
141
        PreparedStatement pstmt;
142
        pstmt = conn.prepareStatement(
143
                "SELECT 'x' FROM xml_acc_numbers " + 
144
                "WHERE global_name LIKE ? AND local_id = ?");
145
        pstmt.setString(1,globalName);
146
        pstmt.setString(2,localId);
147
        pstmt.execute();
148
        ResultSet rs = pstmt.getResultSet();
149
        hasAccNumber = rs.next();
150
        pstmt.close();
151
            
152
      } catch (SQLException e) {
153
        System.err.println("Error on AccessionNumber.unique(globalName, " +
154
                           "localId): " + e.getMessage());
155
        throw e;
156
      }    
157
        
158
      return hasAccNumber;
159
    }    
160
    
161
    /** check for existence of Accesssion Number in xml_documents table */
162
    private static boolean accNumberIsCurrent(
163
                Connection conn, String accNumber) throws SQLException {
164
        
165
      boolean hasCurrentAccNumber = false;
166
        
167
      try {
168
        PreparedStatement pstmt;
169
        pstmt = conn.prepareStatement(
170
                "SELECT 'x' FROM xml_documents " + 
171
                "WHERE docid LIKE ?");
172
        pstmt.setString(1, accNumber);
173
        pstmt.execute();
174
        ResultSet rs = pstmt.getResultSet();
175
        hasCurrentAccNumber = rs.next();
176
        pstmt.close();
177
            
178
      } catch (SQLException e) {
179
        System.err.println(
180
          "Error on AccessionNumber.accNumberIsCurrent(globalName, " +
181
          "localId): " + e.getMessage());
182
        throw e;
183
      }    
184
      return hasCurrentAccNumber;
185
    }    
186

    
187
    /** get the last in order local ID by a given global name */
188
    private static int get (Connection conn, String globalName) 
189
                throws SQLException
190
    {
191
        try {
192
            PreparedStatement pstmt;
193
            pstmt = conn.prepareStatement(
194
                    "SELECT max(local_id) FROM xml_acc_numbers " + 
195
                    "WHERE global_name LIKE ?");
196
            pstmt.setString(1,globalName);
197
            pstmt.execute();
198
            ResultSet rs = pstmt.getResultSet();
199
            boolean hasLocalId = rs.next();
200

    
201
            if (hasLocalId)
202
                return rs.getInt(1);
203

    
204
            pstmt.close();
205
        } catch (SQLException e) {
206
            System.err.println(
207
                   "Error on AccessionNumber.get(): " + e.getMessage());
208
            throw e;
209
        }    
210
        
211
        return 0;
212
    }
213

    
214
    
215
    // get the global part of the accession number
216
    private static String getGlobalName (String accNumber, String sep) 
217
        throws StringIndexOutOfBoundsException {
218
        
219
        return accNumber.substring(0, accNumber.lastIndexOf(sep));
220
    }    
221

    
222
    // get the local part of the accession number
223
    private static String getLocalId (String accNumber, String sep)
224
        throws StringIndexOutOfBoundsException {
225

    
226
        return accNumber.substring(accNumber.lastIndexOf(sep)+1);
227
    }    
228
}
229

    
230
/**
231
 * '$Log$
232
 * 'Revision 1.9  2000/06/26 10:35:04  jones
233
 * 'Merged in substantial changes to DBWriter and associated classes and to
234
 * 'the MetaCatServlet in order to accomodate the new UPDATE and DELETE
235
 * 'functions.  The command line tools and the parameters for the
236
 * 'servlet have changed substantially.
237
 * '
238
 * 'Revision 1.8.2.5  2000/06/26 08:38:01  jones
239
 * 'Added DELETE feature to DBWriter.  Now takes an action "DELETE" and a
240
 * 'docid and will move the record from the xml_documents table to the
241
 * 'xml_revisions table.
242
 * 'Modified option parsing to support option symbols on command line.
243
 * '
244
 * 'Revision 1.8.2.4  2000/06/25 23:11:40  jones
245
 * 'Documentation update
246
 * '
247
 * 'Revision 1.8.2.3  2000/06/25 23:08:31  jones
248
 * 'Minor change to excpetion handling
249
 * ''
250
 */
(1-1/25)