Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2010 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author: jones $'
7
 *     '$Date: 2010-02-03 17:58:12 -0900 (Wed, 03 Feb 2010) $'
8
 * '$Revision: 5211 $'
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 */
24

    
25
package edu.ucsb.nceas.metacat;
26

    
27
import java.sql.PreparedStatement;
28
import java.sql.ResultSet;
29
import java.sql.SQLException;
30

    
31
import org.apache.log4j.Logger;
32

    
33
import edu.ucsb.nceas.metacat.database.DBConnection;
34
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
35

    
36
/**
37
 * Manage the relationship between Metacat local identifiers (LocalIDs) that are
38
 * codified as the (docid, rev) pair with globally uniqe string identifiers
39
 * (GUIDs) that are opaque strings.  This class provides methods to manage these
40
 * identifiers, and to search for and look up LocalIDs based on their GUID and
41
 * vice versa. IdentifierManager is a singleton.
42
 * 
43
 * @author Matthew Jones
44
 */
45
public class IdentifierManager {
46
    
47
    /**
48
     * The single instance of the manager that is always returned.
49
     */
50
    private static IdentifierManager self = null;
51
    private Logger logMetacat = Logger.getLogger(EventLog.class);
52

    
53
    /**
54
     * A private constructor that initializes the class when getInstance() is
55
     * called.
56
     */
57
    private IdentifierManager()
58
    {
59
    }
60

    
61
    /**
62
     * Return the single instance of the manager after initializing it if it
63
     * wasn't previously initialized.
64
     * 
65
     * @return the single IdentifierManager instance
66
     */
67
    public static IdentifierManager getInstance()
68
    {
69
        if (self == null) {
70
            self = new IdentifierManager();
71
        }
72
        return self;
73
    }
74
    
75
    /**
76
     * Lookup a GUID from the database, and return the associated LocalID. If
77
     * the identifier is not found, throw an exception.
78
     * 
79
     * @param guid the global identifier to look up
80
     * @return String containing the corresponding LocalId
81
     * @throws McdbDocNotFoundException if the identifier is not found
82
     */
83
    public String getLocalId(String guid) throws McdbDocNotFoundException
84
    {
85
        String db_guid = "";
86
        String docid = "";
87
        int rev = 0;
88
        
89
        String query = "select guid, docid, rev from identifier where guid = ?";
90
        
91
        DBConnection dbConn = null;
92
        int serialNumber = -1;
93
        try {
94
            // Get a database connection from the pool
95
            dbConn = DBConnectionPool.getDBConnection("Identifier.getLocalId");
96
            serialNumber = dbConn.getCheckOutSerialNumber();
97
            
98
            // Execute the insert statement
99
            PreparedStatement stmt = dbConn.prepareStatement(query);
100
            stmt.setString(1, guid);
101
            ResultSet rs = stmt.executeQuery();
102
            if (rs.next()) {
103
                db_guid = rs.getString(1);
104
                docid = rs.getString(2);
105
                rev = rs.getInt(3);
106
                assert(db_guid.equals(guid));
107
            } else {
108
                throw new McdbDocNotFoundException("Document not found:" + guid);
109
            }
110
            stmt.close();
111
        } catch (SQLException e) {
112
            logMetacat.error("Error while looking up the local identifier: " 
113
                    + e.getMessage());
114
        } finally {
115
            // Return database connection to the pool
116
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
117
        }
118
        return docid + "." + rev;
119
    }
120
    
121
    /**
122
     * Determine if an identifier exists already, returning true if so.
123
     * 
124
     * @param guid the global identifier to look up
125
     * @return boolean true if the identifier exists
126
     */
127
    public boolean identifierExists(String guid)
128
    {
129
        boolean idExists = false;
130
        try {
131
            String id = getLocalId(guid);
132
            if (id != null) {
133
                idExists = true;
134
            }
135
        } catch (McdbDocNotFoundException e) {
136
            idExists = false;
137
        }
138
        return idExists;
139
    }
140
    
141
    /**
142
     * Create a mapping between two identifiers, one representing an 
143
     * unconstrained, globally unique string (guid), and one a localId 
144
     * in the Metacat docid format (scope.id.revision). 
145
     * This mapping allows one to find the global id (guid) from the localId.
146
     * 
147
     * @param guid the global string identifier to be mapped
148
     * @param localId the local identifier to be mapped
149
     */
150
    public void createMapping(String guid, String localId)
151
    {   
152
        int serialNumber = -1;
153
        DBConnection dbConn = null;
154
        try {
155

    
156
            // Parse the localId into scope and rev parts
157
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
158
            String docid = acc.getDocid();
159
            int rev = (new Integer(acc.getRev()).intValue());
160

    
161
            // Get a database connection from the pool
162
            dbConn = 
163
                DBConnectionPool.getDBConnection("Identifier.createMapping");
164
            serialNumber = dbConn.getCheckOutSerialNumber();
165

    
166
            // Execute the insert statement
167
            String query = "insert into identifier (guid, docid, rev) values (?, ?, ?)";            
168
            PreparedStatement stmt = dbConn.prepareStatement(query);
169
            stmt.setString(1, guid);
170
            stmt.setString(2, docid);
171
            stmt.setInt(3, rev);
172
            int rows = stmt.executeUpdate();
173

    
174
            stmt.close();
175
        } catch (SQLException e) {
176
            logMetacat.error("SQL error while creating a mapping to the local identifier: " 
177
                    + e.getMessage());
178
        } catch (NumberFormatException e) {
179
            logMetacat.error("NumberFormat error while creating a mapping to the local identifier: " 
180
                    + e.getMessage());
181
        } catch (AccessionNumberException e) {
182
            logMetacat.error("AccessionNumber error while creating a mapping to the local identifier: " 
183
                    + e.getMessage());
184
        } finally {
185
            // Return database connection to the pool
186
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
187
        }
188
    }
189
}
(37-37/62)