Project

General

Profile

1 5282 jones
/**
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 6384 cjones
import java.math.BigInteger;
28 5282 jones
import java.sql.PreparedStatement;
29
import java.sql.ResultSet;
30
import java.sql.SQLException;
31 5895 berkley
import java.sql.Timestamp;
32 6107 leinfelder
import java.util.ArrayList;
33
import java.util.Date;
34
import java.util.Hashtable;
35
import java.util.List;
36
import java.util.Vector;
37 5282 jones
38
import org.apache.log4j.Logger;
39 6124 cjones
import org.dataone.client.ObjectFormatCache;
40 7010 cjones
import org.dataone.service.exceptions.BaseException;
41 6904 cjones
import org.dataone.service.exceptions.InvalidSystemMetadata;
42 6366 leinfelder
import org.dataone.service.types.v1.AccessPolicy;
43
import org.dataone.service.types.v1.AccessRule;
44
import org.dataone.service.types.v1.Checksum;
45
import org.dataone.service.types.v1.Identifier;
46
import org.dataone.service.types.v1.NodeReference;
47
import org.dataone.service.types.v1.ObjectFormatIdentifier;
48
import org.dataone.service.types.v1.ObjectInfo;
49
import org.dataone.service.types.v1.ObjectList;
50
import org.dataone.service.types.v1.Permission;
51
import org.dataone.service.types.v1.Replica;
52
import org.dataone.service.types.v1.ReplicationPolicy;
53
import org.dataone.service.types.v1.ReplicationStatus;
54
import org.dataone.service.types.v1.Subject;
55
import org.dataone.service.types.v1.SystemMetadata;
56 5282 jones
57 6108 leinfelder
import edu.ucsb.nceas.metacat.accesscontrol.XMLAccessAccess;
58 5282 jones
import edu.ucsb.nceas.metacat.database.DBConnection;
59
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
60 7438 leinfelder
import edu.ucsb.nceas.metacat.database.DatabaseService;
61 5887 berkley
import edu.ucsb.nceas.metacat.properties.PropertyService;
62 6108 leinfelder
import edu.ucsb.nceas.metacat.shared.AccessException;
63 6299 leinfelder
import edu.ucsb.nceas.metacat.shared.ServiceException;
64 5286 jones
import edu.ucsb.nceas.metacat.util.DocumentUtil;
65 6299 leinfelder
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
66 7475 leinfelder
import edu.ucsb.nceas.utilities.access.AccessControlInterface;
67
import edu.ucsb.nceas.utilities.access.XMLAccessDAO;
68 5282 jones
69
/**
70
 * Manage the relationship between Metacat local identifiers (LocalIDs) that are
71 6099 leinfelder
 * codified as the (docid, rev) pair with globally unique string identifiers
72 5282 jones
 * (GUIDs) that are opaque strings.  This class provides methods to manage these
73
 * identifiers, and to search for and look up LocalIDs based on their GUID and
74
 * vice versa. IdentifierManager is a singleton.
75
 *
76
 * @author Matthew Jones
77
 */
78
public class IdentifierManager {
79
80 5334 berkley
    public static final String TYPE_SYSTEM_METADATA = "systemmetadata";
81
    public static final String TYPE_IDENTIFIER = "identifier";
82
83 5282 jones
    /**
84
     * The single instance of the manager that is always returned.
85
     */
86
    private static IdentifierManager self = null;
87 6099 leinfelder
    private Logger logMetacat = Logger.getLogger(IdentifierManager.class);
88 5282 jones
89
    /**
90
     * A private constructor that initializes the class when getInstance() is
91
     * called.
92
     */
93 6099 leinfelder
    private IdentifierManager() {}
94 5282 jones
95
    /**
96
     * Return the single instance of the manager after initializing it if it
97
     * wasn't previously initialized.
98
     *
99
     * @return the single IdentifierManager instance
100
     */
101
    public static IdentifierManager getInstance()
102
    {
103
        if (self == null) {
104
            self = new IdentifierManager();
105
        }
106
        return self;
107
    }
108
109 6097 leinfelder
    public SystemMetadata asSystemMetadata(Date dateUploaded, String rightsHolder,
110
            String checksum, String checksumAlgorithm, String originMemberNode,
111
            String authoritativeMemberNode, Date dateModified, String submitter,
112 6561 leinfelder
            String guid, String fmtidStr, BigInteger size, BigInteger serialVersion) {
113 6097 leinfelder
        SystemMetadata sysMeta = new SystemMetadata();
114
115
        Identifier sysMetaId = new Identifier();
116
        sysMetaId.setValue(guid);
117
        sysMeta.setIdentifier(sysMetaId);
118
        sysMeta.setDateUploaded(dateUploaded);
119
        Subject rightsHolderSubject = new Subject();
120
        rightsHolderSubject.setValue(rightsHolder);
121
        sysMeta.setRightsHolder(rightsHolderSubject);
122
        Checksum checksumObject = new Checksum();
123
        checksumObject.setValue(checksum);
124 6397 leinfelder
        checksumObject.setAlgorithm(checksumAlgorithm);
125 6097 leinfelder
        sysMeta.setChecksum(checksumObject);
126
        NodeReference omn = new NodeReference();
127
        omn.setValue(originMemberNode);
128
        sysMeta.setOriginMemberNode(omn);
129
        NodeReference amn = new NodeReference();
130
        amn.setValue(authoritativeMemberNode);
131
        sysMeta.setAuthoritativeMemberNode(amn);
132
        sysMeta.setDateSysMetadataModified(dateModified);
133
        Subject submitterSubject = new Subject();
134
        submitterSubject.setValue(submitter);
135
        sysMeta.setSubmitter(submitterSubject);
136 7010 cjones
        ObjectFormatIdentifier fmtid = null;
137 6124 cjones
        try {
138 7010 cjones
        	ObjectFormatIdentifier formatId = new ObjectFormatIdentifier();
139
        	formatId.setValue(fmtidStr);
140
        	fmtid = ObjectFormatCache.getInstance().getFormat(formatId).getFormatId();
141 6561 leinfelder
        	sysMeta.setFormatId(fmtid);
142 7010 cjones
143
        } catch (BaseException nfe) {
144
            logMetacat.error("The objectFormat " + fmtidStr +
145 6384 cjones
          	" is not registered. Setting the default format id.");
146 7010 cjones
            fmtid = new ObjectFormatIdentifier();
147
            fmtid.setValue("application/octet-stream");
148
            sysMeta.setFormatId(fmtid);
149
150 6124 cjones
        }
151 6097 leinfelder
        sysMeta.setSize(size);
152 6561 leinfelder
        sysMeta.setSerialVersion(serialVersion);
153 6097 leinfelder
154
        return sysMeta;
155
    }
156
157 5282 jones
    /**
158 5895 berkley
     * return a hash of all of the info that is in the systemmetadata table
159
     * @param localId
160
     * @return
161
     */
162
    public Hashtable<String, String> getSystemMetadataInfo(String localId)
163
    throws McdbDocNotFoundException
164
    {
165
        try
166
        {
167
            AccessionNumber acc = new AccessionNumber(localId, "NONE");
168
            localId = acc.getDocid();
169
        }
170
        catch(Exception e)
171
        {
172
            //do nothing. just try the localId as it is
173
        }
174
        Hashtable<String, String> h = new Hashtable<String, String>();
175
        String sql = "select guid, date_uploaded, rights_holder, checksum, checksum_algorithm, " +
176 5944 berkley
          "origin_member_node, authoritive_member_node, date_modified, submitter, object_format, size " +
177 5895 berkley
          "from systemmetadata where docid = ?";
178
        DBConnection dbConn = null;
179
        int serialNumber = -1;
180
        try
181
        {
182
            // Get a database connection from the pool
183
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getDocumentInfo");
184
            serialNumber = dbConn.getCheckOutSerialNumber();
185
186
            // Execute the insert statement
187
            PreparedStatement stmt = dbConn.prepareStatement(sql);
188
            stmt.setString(1, localId);
189
            ResultSet rs = stmt.executeQuery();
190
            if (rs.next())
191
            {
192
                String guid = rs.getString(1);
193
                Timestamp dateUploaded = rs.getTimestamp(2);
194
                String rightsHolder = rs.getString(3);
195
                String checksum = rs.getString(4);
196
                String checksumAlgorithm = rs.getString(5);
197
                String originMemberNode = rs.getString(6);
198
                String authoritativeMemberNode = rs.getString(7);
199
                Timestamp dateModified = rs.getTimestamp(8);
200
                String submitter = rs.getString(9);
201 5917 berkley
                String objectFormat = rs.getString(10);
202
                long size = new Long(rs.getString(11)).longValue();
203 5895 berkley
204
                h.put("guid", guid);
205
                h.put("date_uploaded", new Long(dateUploaded.getTime()).toString());
206
                h.put("rights_holder", rightsHolder);
207
                h.put("checksum", checksum);
208
                h.put("checksum_algorithm", checksumAlgorithm);
209
                h.put("origin_member_node", originMemberNode);
210
                h.put("authoritative_member_node", authoritativeMemberNode);
211
                h.put("date_modified", new Long(dateModified.getTime()).toString());
212
                h.put("submitter", submitter);
213 5917 berkley
                h.put("object_format", objectFormat);
214
                h.put("size", new Long(size).toString());
215 5895 berkley
216
                stmt.close();
217
            }
218
            else
219
            {
220
                stmt.close();
221
                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
222
                throw new McdbDocNotFoundException("2Could not find document " + localId);
223
            }
224
225
        }
226
        catch (SQLException e)
227
        {
228
            e.printStackTrace();
229
            logMetacat.error("Error while getting system metadata info for localid " + localId + " : "
230
                    + e.getMessage());
231
        }
232
        finally
233
        {
234
            // Return database connection to the pool
235
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
236
        }
237
        return h;
238
    }
239
240
    /**
241 6097 leinfelder
     * return a hash of all of the info that is in the systemmetadata table
242 6099 leinfelder
     * @param guid
243 6097 leinfelder
     * @return
244 6108 leinfelder
     * @throws McdbDocNotFoundException
245 6097 leinfelder
     */
246 6099 leinfelder
    public SystemMetadata getSystemMetadata(String guid)
247 6097 leinfelder
    	throws McdbDocNotFoundException
248
    {
249 6099 leinfelder
250 6097 leinfelder
        SystemMetadata sysMeta = new SystemMetadata();
251
        String sql = "select guid, date_uploaded, rights_holder, checksum, checksum_algorithm, " +
252 6375 leinfelder
          "origin_member_node, authoritive_member_node, date_modified, submitter, object_format, size, " +
253 7428 leinfelder
          "replication_allowed, number_replicas, obsoletes, obsoleted_by, serial_version, archived " +
254 6099 leinfelder
          "from systemmetadata where guid = ?";
255 6097 leinfelder
        DBConnection dbConn = null;
256
        int serialNumber = -1;
257 6533 cjones
        Boolean replicationAllowed = new Boolean(false);
258
        BigInteger numberOfReplicas = new BigInteger("-1");
259 6561 leinfelder
        BigInteger serialVersion = new BigInteger("-1");
260 7428 leinfelder
        Boolean archived = new Boolean(false);
261 6561 leinfelder
262 6097 leinfelder
        try
263
        {
264
            // Get a database connection from the pool
265
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getSystemMetadata");
266
            serialNumber = dbConn.getCheckOutSerialNumber();
267
268
            // Execute the statement
269
            PreparedStatement stmt = dbConn.prepareStatement(sql);
270 6099 leinfelder
            stmt.setString(1, guid);
271 6097 leinfelder
            ResultSet rs = stmt.executeQuery();
272
            if (rs.next())
273
            {
274
                Timestamp dateUploaded = rs.getTimestamp(2);
275
                String rightsHolder = rs.getString(3);
276
                String checksum = rs.getString(4);
277
                String checksumAlgorithm = rs.getString(5);
278
                String originMemberNode = rs.getString(6);
279
                String authoritativeMemberNode = rs.getString(7);
280
                Timestamp dateModified = rs.getTimestamp(8);
281
                String submitter = rs.getString(9);
282 6296 cjones
                String fmtidStr = rs.getString(10);
283 6384 cjones
                BigInteger size = new BigInteger(rs.getString(11));
284 6535 cjones
                replicationAllowed = new Boolean(rs.getBoolean(12));
285 6533 cjones
                numberOfReplicas = new BigInteger(rs.getString(13));
286
                String obsoletes = rs.getString(14);
287
                String obsoletedBy = rs.getString(15);
288 6561 leinfelder
                serialVersion = new BigInteger(rs.getString(16));
289 7428 leinfelder
                archived = new Boolean(rs.getBoolean(17));
290 6375 leinfelder
291 6097 leinfelder
                Identifier sysMetaId = new Identifier();
292
                sysMetaId.setValue(guid);
293
                sysMeta.setIdentifier(sysMetaId);
294 6561 leinfelder
                sysMeta.setSerialVersion(serialVersion);
295 6097 leinfelder
                sysMeta.setDateUploaded(dateUploaded);
296
                Subject rightsHolderSubject = new Subject();
297
                rightsHolderSubject.setValue(rightsHolder);
298
                sysMeta.setRightsHolder(rightsHolderSubject);
299
                Checksum checksumObject = new Checksum();
300
                checksumObject.setValue(checksum);
301 6397 leinfelder
                checksumObject.setAlgorithm(checksumAlgorithm);
302 6097 leinfelder
                sysMeta.setChecksum(checksumObject);
303 6519 leinfelder
                if (originMemberNode != null) {
304
	                NodeReference omn = new NodeReference();
305
	                omn.setValue(originMemberNode);
306
	                sysMeta.setOriginMemberNode(omn);
307
                }
308
                if (authoritativeMemberNode != null) {
309
	                NodeReference amn = new NodeReference();
310
	                amn.setValue(authoritativeMemberNode);
311
	                sysMeta.setAuthoritativeMemberNode(amn);
312
                }
313 6097 leinfelder
                sysMeta.setDateSysMetadataModified(dateModified);
314
                Subject submitterSubject = new Subject();
315
                submitterSubject.setValue(submitter);
316
                sysMeta.setSubmitter(submitterSubject);
317 7023 leinfelder
                ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
318
                fmtid.setValue(fmtidStr);
319
            	sysMeta.setFormatId(fmtid);
320 6097 leinfelder
                sysMeta.setSize(size);
321 6423 leinfelder
                if (obsoletes != null) {
322
	                Identifier obsoletesId = new Identifier();
323
	                obsoletesId.setValue(obsoletes);
324
	                sysMeta.setObsoletes(obsoletesId);
325
                }
326
                if (obsoletedBy != null) {
327
		            Identifier obsoletedById = new Identifier();
328
		            obsoletedById.setValue(obsoletedBy);
329
		            sysMeta.setObsoletedBy(obsoletedById);
330
                }
331 7428 leinfelder
                sysMeta.setArchived(archived);
332 6097 leinfelder
                stmt.close();
333
            }
334
            else
335
            {
336
                stmt.close();
337
                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
338 6099 leinfelder
                throw new McdbDocNotFoundException("Could not find " + guid);
339 6097 leinfelder
            }
340
341
        }
342
        catch (SQLException e)
343
        {
344
            e.printStackTrace();
345 6099 leinfelder
            logMetacat.error("Error while getting system metadata for guid " + guid + " : "
346 6097 leinfelder
                    + e.getMessage());
347
        }
348
        finally
349
        {
350
            // Return database connection to the pool
351
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
352
        }
353 6377 leinfelder
354 6533 cjones
        // populate the replication policy
355 6107 leinfelder
        ReplicationPolicy replicationPolicy = new ReplicationPolicy();
356 6533 cjones
        if ( numberOfReplicas != null  && numberOfReplicas.intValue() != -1 ) {
357
            replicationPolicy.setNumberReplicas(numberOfReplicas.intValue());
358
359
        }
360
361
        if ( replicationAllowed != null ) {
362
            replicationPolicy.setReplicationAllowed(replicationAllowed);
363
364
        }
365 6107 leinfelder
        replicationPolicy.setBlockedMemberNodeList(getReplicationPolicy(guid, "blocked"));
366
        replicationPolicy.setPreferredMemberNodeList(getReplicationPolicy(guid, "preferred"));
367 6533 cjones
		    sysMeta.setReplicationPolicy(replicationPolicy);
368 6107 leinfelder
369 6533 cjones
		    // look up replication status
370
		    sysMeta.setReplicaList(getReplicationStatus(guid));
371 6108 leinfelder
372 6533 cjones
		    // look up access policy
373
		    try {
374
		    	sysMeta.setAccessPolicy(getAccessPolicy(guid));
375
		    } catch (AccessException e) {
376
		    	throw new McdbDocNotFoundException(e);
377
		    }
378 6107 leinfelder
379 6097 leinfelder
        return sysMeta;
380
    }
381
382
383 6107 leinfelder
    private List<NodeReference> getReplicationPolicy(String guid, String policy)
384
		throws McdbDocNotFoundException {
385
386
		List<NodeReference> nodes = new ArrayList<NodeReference>();
387
		String sql = "select guid, policy, member_node " +
388 7392 leinfelder
			"from smReplicationPolicy where guid = ? and policy = ?";
389 6107 leinfelder
	    DBConnection dbConn = null;
390
	    int serialNumber = -1;
391
	    try {
392
	        // Get a database connection from the pool
393
	        dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getReplicationPolicy");
394
	        serialNumber = dbConn.getCheckOutSerialNumber();
395
396
	        // Execute the statement
397
	        PreparedStatement stmt = dbConn.prepareStatement(sql);
398
	        stmt.setString(1, guid);
399
	        stmt.setString(2, policy);
400
	        ResultSet rs = stmt.executeQuery();
401
	        while (rs.next())
402
	        {
403
	            String memberNode = rs.getString(3);
404
	            NodeReference node = new NodeReference();
405
	            node.setValue(memberNode);
406
	            nodes.add(node);
407
408
	        }
409
	        stmt.close();
410
411
	    } catch (SQLException e) {
412
	        logMetacat.error("Error while getting system metadata replication policy for guid " + guid, e);
413
	    }
414
	    finally {
415
	        // Return database connection to the pool
416
	        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
417
	    }
418
419
	    return nodes;
420
	}
421 6097 leinfelder
422 6107 leinfelder
    private List<Replica> getReplicationStatus(String guid) throws McdbDocNotFoundException {
423
424
		List<Replica> replicas = new ArrayList<Replica>();
425
		String sql = "select guid, member_node, status, date_verified " +
426 7392 leinfelder
			"from smReplicationStatus where guid = ?";
427 6107 leinfelder
	    DBConnection dbConn = null;
428
	    int serialNumber = -1;
429
	    try {
430
	        // Get a database connection from the pool
431
	        dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getReplicas");
432
	        serialNumber = dbConn.getCheckOutSerialNumber();
433
434
	        // Execute the statement
435
	        PreparedStatement stmt = dbConn.prepareStatement(sql);
436
	        stmt.setString(1, guid);
437
	        ResultSet rs = stmt.executeQuery();
438
	        while (rs.next())
439
	        {
440
	            String memberNode = rs.getString(2);
441
	            String status = rs.getString(3);
442 7399 cjones
	            java.sql.Timestamp verified = rs.getTimestamp(4);
443 6107 leinfelder
444
	            Replica replica = new Replica();
445
	            NodeReference node = new NodeReference();
446
	            node.setValue(memberNode);
447
	            replica.setReplicaMemberNode(node);
448 6454 leinfelder
	            replica.setReplicationStatus(ReplicationStatus.valueOf(status));
449 6107 leinfelder
	            replica.setReplicaVerified(new Date(verified.getTime()));
450
	            replicas.add(replica);
451
	        }
452
	        stmt.close();
453
454
	    } catch (SQLException e) {
455
	        logMetacat.error("Error while getting system metadata replication policy for guid " + guid, e);
456
	    }
457
	    finally {
458
	        // Return database connection to the pool
459
	        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
460
	    }
461
462
	    return replicas;
463
	}
464
465 5378 berkley
466
    /**
467
     * return the newest rev for a given localId
468
     * @param localId
469
     * @return
470
     */
471
    public int getLatestRevForLocalId(String localId)
472
        throws McdbDocNotFoundException
473
    {
474 5798 berkley
        try
475
        {
476
            AccessionNumber acc = new AccessionNumber(localId, "NONE");
477
            localId = acc.getDocid();
478
        }
479
        catch(Exception e)
480
        {
481
            //do nothing. just try the localId as it is
482
        }
483 5378 berkley
        int rev = 0;
484 6595 leinfelder
        String sql = "select rev from xml_documents where docid like ? ";
485 5378 berkley
        DBConnection dbConn = null;
486
        int serialNumber = -1;
487
        try
488
        {
489
            // Get a database connection from the pool
490
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getLatestRevForLocalId");
491
            serialNumber = dbConn.getCheckOutSerialNumber();
492
493
            // Execute the insert statement
494
            PreparedStatement stmt = dbConn.prepareStatement(sql);
495 6595 leinfelder
            stmt.setString(1, localId);
496 5378 berkley
            ResultSet rs = stmt.executeQuery();
497
            if (rs.next())
498
            {
499
                rev = rs.getInt(1);
500
                stmt.close();
501
            }
502
            else
503
            {
504
                stmt.close();
505
                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
506 5798 berkley
                throw new McdbDocNotFoundException("While trying to get the latest rev, could not find document " + localId);
507 5378 berkley
            }
508
        }
509
        catch (SQLException e)
510
        {
511
            logMetacat.error("Error while looking up the guid: "
512
                    + e.getMessage());
513
        }
514
        finally
515
        {
516
            // Return database connection to the pool
517
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
518
        }
519
        return rev;
520
    }
521
522
    /**
523 5377 berkley
     * return all local ids in the object store that do not have associated
524 6099 leinfelder
     * system metadata
525 5377 berkley
     */
526 7168 leinfelder
    public List<String> getLocalIdsWithNoSystemMetadata(boolean includeRevisions, int serverLocation)
527 5377 berkley
    {
528
        Vector<String> ids = new Vector<String>();
529 6099 leinfelder
        String sql = "select docid, rev from xml_documents " +
530
        		"where docid not in " +
531 6720 leinfelder
        		"(select docid from identifier where guid in (select guid from systemmetadata))";
532 7168 leinfelder
        if (serverLocation > 0) {
533
        	sql = sql + " and server_location = ? ";
534
        }
535 6704 leinfelder
536 6745 leinfelder
        String revisionSql = "select docid, rev from xml_revisions " +
537 6704 leinfelder
				"where docid not in " +
538 6720 leinfelder
				"(select docid from identifier where guid in (select guid from systemmetadata))";
539 7168 leinfelder
        if (serverLocation > 0) {
540
        	revisionSql = revisionSql + " and server_location = ? ";
541
        }
542 6704 leinfelder
543
        if (includeRevisions) {
544
        	sql = sql + " UNION ALL " + revisionSql;
545
        }
546
547 5377 berkley
        DBConnection dbConn = null;
548
        int serialNumber = -1;
549
        try
550
        {
551
            // Get a database connection from the pool
552
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getLocalIdsWithNoSystemMetadata");
553
            serialNumber = dbConn.getCheckOutSerialNumber();
554
555
            // Execute the insert statement
556
            PreparedStatement stmt = dbConn.prepareStatement(sql);
557 7168 leinfelder
            // set params based on what we have in the query string
558
            if (serverLocation > 0) {
559
            	stmt.setInt(1, serverLocation);
560
            	if (includeRevisions) {
561
            		stmt.setInt(2, serverLocation);
562
            	}
563
            }
564 5377 berkley
            ResultSet rs = stmt.executeQuery();
565
            while (rs.next())
566
            {
567
                String localid = rs.getString(1);
568 5798 berkley
                String rev = rs.getString(2);
569
                localid += "." + rev;
570 6099 leinfelder
                logMetacat.debug("id to add SM for: " + localid);
571 5377 berkley
                ids.add(localid);
572
            }
573
            stmt.close();
574
        }
575
        catch (SQLException e)
576
        {
577
            logMetacat.error("Error while looking up the guid: "
578
                    + e.getMessage());
579
        }
580
        finally
581
        {
582
            // Return database connection to the pool
583
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
584
        }
585
586
        return ids;
587
    }
588
589
    /**
590
     * return a listing of all local ids in the object store
591
     * @return a list of all local ids in metacat
592
     */
593
    public List<String> getAllLocalIds()
594 6416 rnahf
    // seems to be an unnecessary and restrictive throw -rnahf 13-Sep-2011
595
    //    throws Exception
596 5377 berkley
    {
597
        Vector<String> ids = new Vector<String>();
598
        String sql = "select docid from xml_documents";
599
        DBConnection dbConn = null;
600
        int serialNumber = -1;
601
        try
602
        {
603
            // Get a database connection from the pool
604
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getAllLocalIds");
605
            serialNumber = dbConn.getCheckOutSerialNumber();
606
607
            // Execute the insert statement
608
            PreparedStatement stmt = dbConn.prepareStatement(sql);
609
            ResultSet rs = stmt.executeQuery();
610
            while (rs.next())
611
            {
612
                String localid = rs.getString(1);
613
                ids.add(localid);
614
            }
615
            stmt.close();
616
        }
617
        catch (SQLException e)
618
        {
619
            logMetacat.error("Error while looking up the guid: "
620
                    + e.getMessage());
621
        }
622
        finally
623
        {
624
            // Return database connection to the pool
625
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
626
        }
627
        return ids;
628
    }
629
630 6416 rnahf
631 6118 leinfelder
    /**
632 6416 rnahf
     * return a listing of all guids in the object store
633
     * @return a list of all GUIDs in metacat
634
     */
635 7187 leinfelder
    public List<String> getAllSystemMetadataGUIDs()
636 6416 rnahf
    {
637
        Vector<String> guids = new Vector<String>();
638 7187 leinfelder
        String sql = "select guid from systemmetadata";
639 6416 rnahf
        DBConnection dbConn = null;
640
        int serialNumber = -1;
641
        try
642
        {
643
            // Get a database connection from the pool
644
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getAllGUIDs");
645
            serialNumber = dbConn.getCheckOutSerialNumber();
646
647
            // Execute the insert statement
648
            PreparedStatement stmt = dbConn.prepareStatement(sql);
649
            ResultSet rs = stmt.executeQuery();
650
            while (rs.next())
651
            {
652
                String guid = rs.getString(1);
653
                guids.add(guid);
654
            }
655
            stmt.close();
656
        }
657
        catch (SQLException e)
658
        {
659
            logMetacat.error("Error while retrieving the guid: "
660
                    + e.getMessage());
661
        }
662
        finally
663
        {
664
            // Return database connection to the pool
665
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
666
        }
667
        return guids;
668
    }
669
670
671
672
    /**
673 6118 leinfelder
     * returns a list of system metadata-only guids since the given date
674
     * @return a list of system ids in metacat that do not correspond to objects
675
     * TODO: need to check which server they are on
676
     */
677
    public List<String> getUpdatedSystemMetadataIds(Date since)
678
       throws Exception
679
    {
680
        List<String> ids = new Vector<String>();
681
        String sql =
682
        	"select guid from " + TYPE_SYSTEM_METADATA +
683
        	" where guid not in " +
684
        	" (select guid from " + TYPE_IDENTIFIER + ") " +
685
        	" and date_modified > ?";
686
        DBConnection dbConn = null;
687
        int serialNumber = -1;
688
        try
689
        {
690
            // Get a database connection from the pool
691
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getUpdatedSystemMetadataIds");
692
            serialNumber = dbConn.getCheckOutSerialNumber();
693 6099 leinfelder
694 6118 leinfelder
            // Execute the insert statement
695
            PreparedStatement stmt = dbConn.prepareStatement(sql);
696
            stmt.setDate(1, new java.sql.Date(since.getTime()));
697
            ResultSet rs = stmt.executeQuery();
698
            while (rs.next())
699
            {
700
                String guid = rs.getString(1);
701
                ids.add(guid);
702
            }
703
            stmt.close();
704
        }
705
        catch (SQLException e)
706
        {
707
            logMetacat.error("Error while looking up the updated guids: "
708
                    + e.getMessage());
709
        }
710
        finally
711
        {
712
            // Return database connection to the pool
713
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
714
        }
715
        return ids;
716
    }
717 5282 jones
718 6459 leinfelder
    /**
719
     * returns a list of system metadata-only guids since the given date
720
     * @return a list of system ids in metacat that do not correspond to objects
721
     * TODO: need to check which server they are on
722
     */
723
    public Date getLastModifiedDate() throws Exception {
724
        Date maxDate = null;
725 6118 leinfelder
726 6459 leinfelder
        List<String> ids = new Vector<String>();
727
        String sql =
728
        	"select max(date_modified) from " + TYPE_SYSTEM_METADATA;
729
        DBConnection dbConn = null;
730
        int serialNumber = -1;
731
        try
732
        {
733
            // Get a database connection from the pool
734
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getLastModifiedDate");
735
            serialNumber = dbConn.getCheckOutSerialNumber();
736
737
            // Execute the insert statement
738
            PreparedStatement stmt = dbConn.prepareStatement(sql);
739
            ResultSet rs = stmt.executeQuery();
740
            if (rs.next()) {
741
            	maxDate = rs.getDate(1);
742
            }
743
            stmt.close();
744
        }
745
        catch (SQLException e)
746
        {
747
            logMetacat.error("Error while looking up the latest update date: "
748
                    + e.getMessage());
749
        }
750
        finally
751
        {
752
            // Return database connection to the pool
753
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
754
        }
755
        return maxDate;
756
    }
757
758 6118 leinfelder
759 5282 jones
    /**
760
     * Determine if an identifier exists already, returning true if so.
761 7045 leinfelder
     * NOTE: looks in the identifier and system metadata table for a match
762
     * (in that order)
763 5282 jones
     *
764
     * @param guid the global identifier to look up
765
     * @return boolean true if the identifier exists
766
     */
767
    public boolean identifierExists(String guid)
768
    {
769
        boolean idExists = false;
770
        try {
771
            String id = getLocalId(guid);
772
            if (id != null) {
773
                idExists = true;
774
            }
775
        } catch (McdbDocNotFoundException e) {
776 6123 leinfelder
        	// try system metadata only
777
        	try {
778 6416 rnahf
        		idExists = systemMetadataExists(guid);
779 6454 leinfelder
            } catch (Exception e2) {
780 6123 leinfelder
            	idExists = false;
781
            }
782 5282 jones
        }
783
        return idExists;
784
    }
785
786
    /**
787 7045 leinfelder
     * Determine if an identifier mapping exists already,
788
     * returning true if so.
789 5282 jones
     *
790 7045 leinfelder
     * @param guid the global identifier to look up
791
     * @return boolean true if the identifier exists
792
     */
793
    public boolean mappingExists(String guid)
794
    {
795
        boolean idExists = false;
796
        try {
797
            String id = getLocalId(guid);
798
            if (id != null) {
799
                idExists = true;
800
            }
801
        } catch (McdbDocNotFoundException e) {
802
        	// nope!
803
        }
804
        return idExists;
805
    }
806
807
    /**
808
     *
809 5453 berkley
     * @param guid
810
     * @param rev
811
     * @return
812
     */
813
    public String generateLocalId(String guid, int rev)
814
    {
815
        return generateLocalId(guid, rev, false);
816
    }
817 5286 jones
818
    /**
819
     * Given a global identifier (guid), create a suitable local identifier that
820
     * follows Metacat's docid semantics and format (scope.id.rev), and create
821
     * a mapping between these two identifiers.  This effectively reserves both
822
     * the global and the local identifier, as they will now be present in the
823 7070 leinfelder
     * identifier mapping table.
824
     *
825
     * REMOVED feature: If the incoming guid has the syntax of a
826 5286 jones
     * Metacat docid (scope.id.rev), then simply use it.
827 7070 leinfelder
     * WHY: because "test.1.001" becomes "test.1.1" which is not correct for DataONE
828
     * identifier use (those revision numbers are just chartacters and should not be interpreted)
829 5286 jones
     *
830
     * @param guid the global string identifier
831
     * @param rev the revision number to be used in the localId
832
     * @return String containing the localId to be used for Metacat operations
833
     */
834 5453 berkley
    public String generateLocalId(String guid, int rev, boolean isSystemMetadata)
835 5286 jones
    {
836
        String localId = "";
837
        boolean conformsToDocidFormat = false;
838
839 7070 leinfelder
        // BRL -- do not allow Metacat-conforming IDs to be used:
840
        // test.1.001 becomes test.1.1 which is NOT correct for DataONE identifiers
841 5286 jones
        // Check if the guid passed in is already in docid (scope.id.rev) format
842 7070 leinfelder
//        try {
843
//            AccessionNumber acc = new AccessionNumber(guid, "NONE");
844
//            if (new Integer(acc.getRev()).intValue() > 0) {
845
//                conformsToDocidFormat = true;
846
//            }
847
//        } catch (NumberFormatException e) {
848
//            // No action needed, simply detecting invalid AccessionNumbers
849
//        } catch (AccessionNumberException e) {
850
//            // No action needed, simply detecting invalid AccessionNumbers
851
//        } catch (SQLException e) {
852
//            // No action needed, simply detecting invalid AccessionNumbers
853
//        }
854 5286 jones
855
        if (conformsToDocidFormat) {
856
            // if it conforms, use it for both guid and localId
857
            localId = guid;
858
        } else {
859
            // if not, then generate a new unique localId
860
            localId = DocumentUtil.generateDocumentId(rev);
861
        }
862
863
        // Register this new pair in the identifier mapping table
864 6099 leinfelder
        logMetacat.debug("creating mapping in generateLocalId");
865 5453 berkley
        if(!isSystemMetadata)
866
        { //don't do this if we're generating for system metadata
867
            createMapping(guid, localId);
868
        }
869 5286 jones
870
        return localId;
871
    }
872 5322 berkley
873
    /**
874
     * given a local identifer, look up the guid.  Throw McdbDocNotFoundException
875 5452 berkley
     * if the docid, rev is not found in the identifiers or systemmetadata tables
876 5322 berkley
     *
877
     * @param docid the docid to look up
878
     * @param rev the revision of the docid to look up
879
     * @return String containing the mapped guid
880
     * @throws McdbDocNotFoundException if the docid, rev is not found
881
     */
882
    public String getGUID(String docid, int rev)
883
      throws McdbDocNotFoundException
884
    {
885 6099 leinfelder
        logMetacat.debug("getting guid for " + docid);
886 5322 berkley
        String query = "select guid from identifier where docid = ? and rev = ?";
887
        String guid = null;
888
889
        DBConnection dbConn = null;
890
        int serialNumber = -1;
891
        try {
892
            // Get a database connection from the pool
893 5377 berkley
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getGUID");
894 5322 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
895
896
            // Execute the insert statement
897
            PreparedStatement stmt = dbConn.prepareStatement(query);
898
            stmt.setString(1, docid);
899
            stmt.setInt(2, rev);
900
            ResultSet rs = stmt.executeQuery();
901 5451 berkley
            if (rs.next())
902
            {
903 5322 berkley
                guid = rs.getString(1);
904 5451 berkley
            }
905
            else
906
            {
907 6104 leinfelder
            	throw new McdbDocNotFoundException("No guid registered for docid " + docid + "." + rev);
908 5322 berkley
            }
909 5451 berkley
910 5322 berkley
        } catch (SQLException e) {
911
            logMetacat.error("Error while looking up the guid: "
912
                    + e.getMessage());
913
        } finally {
914
            // Return database connection to the pool
915
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
916
        }
917
918
        return guid;
919
    }
920 5333 berkley
921 6454 leinfelder
    public boolean systemMetadataExists(String guid) {
922 6123 leinfelder
		logMetacat.debug("looking up system metadata for guid " + guid);
923
		boolean exists = false;
924 6337 leinfelder
		String query = "select guid from systemmetadata where guid = ?";
925 6123 leinfelder
926
		DBConnection dbConn = null;
927
		int serialNumber = -1;
928
		try {
929
			// Get a database connection from the pool
930
			dbConn = DBConnectionPool.getDBConnection("IdentifierManager.systemMetadataExisits");
931
			serialNumber = dbConn.getCheckOutSerialNumber();
932
933
			// Execute the insert statement
934
			PreparedStatement stmt = dbConn.prepareStatement(query);
935
			stmt.setString(1, guid);
936
			ResultSet rs = stmt.executeQuery();
937
			if (rs.next()) {
938
				exists = true;
939
			}
940
941
		} catch (SQLException e) {
942
			logMetacat.error("Error while looking up the system metadata: "
943
					+ e.getMessage());
944
		} finally {
945
			// Return database connection to the pool
946
			DBConnectionPool.returnDBConnection(dbConn, serialNumber);
947
		}
948
949
		return exists;
950
	}
951
952 5333 berkley
    /**
953 5887 berkley
     * creates a system metadata mapping and adds additional fields from sysmeta
954
     * to the table for quick searching.
955
     *
956
     * @param guid the id to insert
957
     * @param localId the systemMetadata object to get the local id for
958 6108 leinfelder
     * @throws McdbDocNotFoundException
959 6892 cjones
     * @throws SQLException
960 6904 cjones
     * @throws InvalidSystemMetadata
961 5887 berkley
     */
962 7188 leinfelder
    public void insertOrUpdateSystemMetadata(SystemMetadata sysmeta)
963 6904 cjones
        throws McdbDocNotFoundException, SQLException, InvalidSystemMetadata {
964 6277 leinfelder
    	String guid = sysmeta.getIdentifier().getValue();
965 7188 leinfelder
966
    	 // Get a database connection from the pool
967
        DBConnection dbConn = DBConnectionPool.getDBConnection("IdentifierManager.insertSystemMetadata");
968
        int serialNumber = dbConn.getCheckOutSerialNumber();
969 6892 cjones
970 7188 leinfelder
        try {
971
        	// use a single transaction for it all
972
        	dbConn.setAutoCommit(false);
973
974
	    	// insert the record if needed
975
        	if (!IdentifierManager.getInstance().systemMetadataExists(guid)) {
976
    	        insertSystemMetadata(guid, dbConn);
977
			}
978
	        // update with the values
979
	        updateSystemMetadata(sysmeta, dbConn);
980
981
	        // commit if we got here with no errors
982
	        dbConn.commit();
983
        } catch (Exception e) {
984
            e.printStackTrace();
985
            logMetacat.error("Error while creating " + TYPE_SYSTEM_METADATA + " record: " + guid, e );
986
            dbConn.rollback();
987
        } finally {
988
            // Return database connection to the pool
989
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
990
        }
991
992
993 5887 berkley
    }
994 6099 leinfelder
995 5887 berkley
996
    /**
997 6079 leinfelder
     * update a mapping
998
     * @param guid
999
     * @param localId
1000
     */
1001
    public void updateMapping(String guid, String localId)
1002
    {
1003
1004 6099 leinfelder
        logMetacat.debug("$$$$$$$$$$$$$$ updating mapping table");
1005 5350 berkley
        int serialNumber = -1;
1006
        DBConnection dbConn = null;
1007
        try {
1008
            // Parse the localId into scope and rev parts
1009
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
1010
            String docid = acc.getDocid();
1011
            int rev = 1;
1012
            if(acc.getRev() != null)
1013
            {
1014
              rev = (new Integer(acc.getRev()).intValue());
1015
            }
1016
1017
            // Get a database connection from the pool
1018
            dbConn =
1019 6079 leinfelder
                DBConnectionPool.getDBConnection("IdentifierManager.updateMapping");
1020 5350 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
1021
1022 6099 leinfelder
            // Execute the update statement
1023 6595 leinfelder
            String query = "update " + TYPE_IDENTIFIER + " set (docid, rev) = (?, ?) where guid = ?";
1024 5350 berkley
            PreparedStatement stmt = dbConn.prepareStatement(query);
1025
            stmt.setString(1, docid);
1026
            stmt.setInt(2, rev);
1027 6595 leinfelder
            stmt.setString(3, guid);
1028 5350 berkley
            int rows = stmt.executeUpdate();
1029
1030
            stmt.close();
1031
        } catch (SQLException e) {
1032
            e.printStackTrace();
1033 6079 leinfelder
            logMetacat.error("SQL error while updating a mapping identifier: "
1034 5350 berkley
                    + e.getMessage());
1035
        } catch (NumberFormatException e) {
1036
            e.printStackTrace();
1037 6079 leinfelder
            logMetacat.error("NumberFormat error while updating a mapping identifier: "
1038 5350 berkley
                    + e.getMessage());
1039
        } catch (AccessionNumberException e) {
1040
            e.printStackTrace();
1041 6079 leinfelder
            logMetacat.error("AccessionNumber error while updating a mapping identifier: "
1042 5350 berkley
                    + e.getMessage());
1043
        } finally {
1044
            // Return database connection to the pool
1045
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1046
        }
1047 6099 leinfelder
        logMetacat.debug("done updating mapping");
1048 5350 berkley
    }
1049 6099 leinfelder
1050
    private void updateSystemMetadataFields(long dateUploaded, String rightsHolder,
1051 6892 cjones
        String checksum, String checksumAlgorithm, String originMemberNode,
1052
        String authoritativeMemberNode, long modifiedDate, String submitter,
1053
        String guid, String objectFormat, BigInteger size, boolean archived,
1054
        boolean replicationAllowed, int numberReplicas, String obsoletes,
1055 7188 leinfelder
        String obsoletedBy, BigInteger serialVersion, DBConnection dbConn) throws SQLException  {
1056
1057
        // Execute the insert statement
1058
        String query = "update " + TYPE_SYSTEM_METADATA +
1059
            " set (date_uploaded, rights_holder, checksum, checksum_algorithm, " +
1060
            "origin_member_node, authoritive_member_node, date_modified, " +
1061
            "submitter, object_format, size, archived, replication_allowed, number_replicas, " +
1062
            "obsoletes, obsoleted_by, serial_version) " +
1063
            "= (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) where guid = ?";
1064
        PreparedStatement stmt = dbConn.prepareStatement(query);
1065 6892 cjones
1066 7188 leinfelder
        //data values
1067
        stmt.setTimestamp(1, new java.sql.Timestamp(dateUploaded));
1068
        stmt.setString(2, rightsHolder);
1069
        stmt.setString(3, checksum);
1070
        stmt.setString(4, checksumAlgorithm);
1071
        stmt.setString(5, originMemberNode);
1072
        stmt.setString(6, authoritativeMemberNode);
1073
        stmt.setTimestamp(7, new java.sql.Timestamp(modifiedDate));
1074
        stmt.setString(8, submitter);
1075
        stmt.setString(9, objectFormat);
1076
        stmt.setString(10, size.toString());
1077
        stmt.setBoolean(11, archived);
1078
        stmt.setBoolean(12, replicationAllowed);
1079
        stmt.setInt(13, numberReplicas);
1080
        stmt.setString(14, obsoletes);
1081
        stmt.setString(15, obsoletedBy);
1082
        stmt.setString(16, serialVersion.toString());
1083
1084
        //where clause
1085
        stmt.setString(17, guid);
1086
        logMetacat.debug("stmt: " + stmt.toString());
1087
        //execute
1088
        int rows = stmt.executeUpdate();
1089
1090
        stmt.close();
1091
1092
    }
1093
1094
    private void insertReplicationPolicy(String guid, String policy, List<String> memberNodes, DBConnection dbConn) throws SQLException
1095
    {
1096
1097
        // remove existing values first
1098 7392 leinfelder
        String delete = "delete from smReplicationPolicy " +
1099 7188 leinfelder
        "where guid = ? and policy = ?";
1100
        PreparedStatement stmt = dbConn.prepareStatement(delete);
1101
        //data values
1102
        stmt.setString(1, guid);
1103
        stmt.setString(2, policy);
1104
        //execute
1105
        int deletedCount = stmt.executeUpdate();
1106
        stmt.close();
1107 5957 berkley
1108 7188 leinfelder
        for (String memberNode: memberNodes) {
1109 5887 berkley
            // Execute the insert statement
1110 7392 leinfelder
            String insert = "insert into smReplicationPolicy " +
1111 7188 leinfelder
                "(guid, policy, member_node) " +
1112
                "values (?, ?, ?)";
1113
            PreparedStatement insertStatement = dbConn.prepareStatement(insert);
1114 5887 berkley
1115
            //data values
1116 7188 leinfelder
            insertStatement.setString(1, guid);
1117
            insertStatement.setString(2, policy);
1118
            insertStatement.setString(3, memberNode);
1119
1120 7392 leinfelder
            logMetacat.debug("smReplicationPolicy sql: " + insertStatement.toString());
1121 6375 leinfelder
1122 5887 berkley
            //execute
1123 7188 leinfelder
            int rows = insertStatement.executeUpdate();
1124
            insertStatement.close();
1125 5887 berkley
        }
1126 7188 leinfelder
1127 5887 berkley
    }
1128
1129 7188 leinfelder
    private void insertReplicationStatus(String guid, List<Replica> replicas, DBConnection dbConn) throws SQLException {
1130
1131
        // remove existing values first
1132 7392 leinfelder
        String delete = "delete from smReplicationStatus " +
1133 7188 leinfelder
        "where guid = ?";
1134
        PreparedStatement stmt = dbConn.prepareStatement(delete);
1135
        //data values
1136
        stmt.setString(1, guid);
1137
        //execute
1138
        int deletedCount = stmt.executeUpdate();
1139
        stmt.close();
1140 6107 leinfelder
1141 7188 leinfelder
        if (replicas != null) {
1142
            for (Replica replica: replicas) {
1143 6107 leinfelder
	            // Execute the insert statement
1144 7392 leinfelder
	            String insert = "insert into smReplicationStatus " +
1145 7188 leinfelder
	                "(guid, member_node, status, date_verified) " +
1146
	                "values (?, ?, ?, ?)";
1147 6107 leinfelder
	            PreparedStatement insertStatement = dbConn.prepareStatement(insert);
1148
1149
	            //data values
1150 7188 leinfelder
	            String memberNode = replica.getReplicaMemberNode().getValue();
1151
	            String status = replica.getReplicationStatus().toString();
1152 7399 cjones
	            java.sql.Timestamp sqlDate = new java.sql.Timestamp(replica.getReplicaVerified().getTime());
1153 6107 leinfelder
	            insertStatement.setString(1, guid);
1154 7188 leinfelder
	            insertStatement.setString(2, memberNode);
1155
	            insertStatement.setString(3, status);
1156 7399 cjones
	            insertStatement.setTimestamp(4, sqlDate);
1157 7188 leinfelder
1158 7392 leinfelder
	            logMetacat.debug("smReplicationStatus sql: " + insertStatement.toString());
1159 7102 leinfelder
1160 6107 leinfelder
	            //execute
1161
	            int rows = insertStatement.executeUpdate();
1162
	            insertStatement.close();
1163
            }
1164
        }
1165 7188 leinfelder
1166 6107 leinfelder
    }
1167
1168 5334 berkley
    /**
1169 5887 berkley
     * Insert the system metadata fields into the db
1170
     * @param sm
1171 6108 leinfelder
     * @throws McdbDocNotFoundException
1172 6892 cjones
     * @throws SQLException
1173 6904 cjones
     * @throws InvalidSystemMetadata
1174 7188 leinfelder
     * @throws AccessException
1175 5887 berkley
     */
1176 7188 leinfelder
    public void updateSystemMetadata(SystemMetadata sm, DBConnection dbConn)
1177
      throws McdbDocNotFoundException, SQLException, InvalidSystemMetadata, AccessException {
1178 6107 leinfelder
1179 6892 cjones
      Boolean replicationAllowed = false;
1180
		  Integer numberReplicas = -1;
1181 6107 leinfelder
    	ReplicationPolicy replicationPolicy = sm.getReplicationPolicy();
1182
    	if (replicationPolicy != null) {
1183
    		replicationAllowed = replicationPolicy.getReplicationAllowed();
1184
    		numberReplicas = replicationPolicy.getNumberReplicas();
1185
    		replicationAllowed = replicationAllowed == null ? false: replicationAllowed;
1186
    		numberReplicas = numberReplicas == null ? -1: numberReplicas;
1187
    	}
1188 6904 cjones
1189 6107 leinfelder
    	// the main systemMetadata fields
1190 6892 cjones
		  updateSystemMetadataFields(
1191 6311 leinfelder
				sm.getDateUploaded() == null ? null: sm.getDateUploaded().getTime(),
1192
				sm.getRightsHolder() == null ? null: sm.getRightsHolder().getValue(),
1193
				sm.getChecksum() == null ? null: sm.getChecksum().getValue(),
1194 6397 leinfelder
				sm.getChecksum() == null ? null: sm.getChecksum().getAlgorithm(),
1195 6311 leinfelder
				sm.getOriginMemberNode() == null ? null: sm.getOriginMemberNode().getValue(),
1196
				sm.getAuthoritativeMemberNode() == null ? null: sm.getAuthoritativeMemberNode().getValue(),
1197
				sm.getDateSysMetadataModified() == null ? null: sm.getDateSysMetadataModified().getTime(),
1198
				sm.getSubmitter() == null ? null: sm.getSubmitter().getValue(),
1199 6904 cjones
		    sm.getIdentifier().getValue(),
1200
		    sm.getFormatId() == null ? null: sm.getFormatId().getValue(),
1201
		    sm.getSize(),
1202
		    sm.getArchived() == null ? false: sm.getArchived(),
1203
		    replicationAllowed,
1204
		    numberReplicas,
1205
		    sm.getObsoletes() == null ? null:sm.getObsoletes().getValue(),
1206
		    sm.getObsoletedBy() == null ? null: sm.getObsoletedBy().getValue(),
1207 7188 leinfelder
		    sm.getSerialVersion(),
1208
		    dbConn
1209 6561 leinfelder
        );
1210 6097 leinfelder
1211
        String guid = sm.getIdentifier().getValue();
1212
1213 6107 leinfelder
        // save replication policies
1214
        if (replicationPolicy != null) {
1215
		    List<String> nodes = null;
1216
		    String policy = null;
1217
1218 6494 leinfelder
		    // check for null
1219
		    if (replicationPolicy.getBlockedMemberNodeList() != null) {
1220
			    nodes = new ArrayList<String>();
1221
			    policy = "blocked";
1222
			    for (NodeReference node: replicationPolicy.getBlockedMemberNodeList()) {
1223
			    	nodes.add(node.getValue());
1224
			    }
1225 7188 leinfelder
			    this.insertReplicationPolicy(guid, policy, nodes, dbConn);
1226 6107 leinfelder
		    }
1227
1228 6494 leinfelder
		    if (replicationPolicy.getPreferredMemberNodeList() != null) {
1229
			    nodes = new ArrayList<String>();
1230
			    policy = "preferred";
1231
			    for (NodeReference node: replicationPolicy.getPreferredMemberNodeList()) {
1232
			    	nodes.add(node.getValue());
1233
			    }
1234 7188 leinfelder
		        this.insertReplicationPolicy(guid, policy, nodes, dbConn);
1235 6107 leinfelder
		    }
1236
        }
1237 6097 leinfelder
1238 6107 leinfelder
        // save replica information
1239 7188 leinfelder
        this.insertReplicationStatus(guid, sm.getReplicaList(), dbConn);
1240 6107 leinfelder
1241 6108 leinfelder
        // save access policy
1242
        AccessPolicy accessPolicy = sm.getAccessPolicy();
1243
        if (accessPolicy != null) {
1244 7188 leinfelder
			this.insertAccessPolicy(guid, accessPolicy);
1245 6108 leinfelder
        }
1246 5887 berkley
    }
1247
1248
    /**
1249 6108 leinfelder
     * Creates Metacat access rules and inserts them
1250
     * @param accessPolicy
1251
     * @throws McdbDocNotFoundException
1252
     * @throws AccessException
1253
     */
1254
    private void insertAccessPolicy(String guid, AccessPolicy accessPolicy) throws McdbDocNotFoundException, AccessException {
1255
1256 6744 leinfelder
    	// check for the existing permOrder so that we remain compatible with it (DataONE does not care)
1257
        XMLAccessAccess accessController  = new XMLAccessAccess();
1258
		String existingPermOrder = AccessControlInterface.ALLOWFIRST;
1259
        Vector<XMLAccessDAO> existingAccess = accessController.getXMLAccessForDoc(guid);
1260
        if (existingAccess != null && existingAccess.size() > 0) {
1261
        	existingPermOrder = existingAccess.get(0).getPermOrder();
1262
        }
1263
1264 6108 leinfelder
    	List<XMLAccessDAO> accessDAOs = new ArrayList<XMLAccessDAO>();
1265
        for (AccessRule accessRule: accessPolicy.getAllowList()) {
1266
        	List<Subject> subjects = accessRule.getSubjectList();
1267
        	List<Permission> permissions = accessRule.getPermissionList();
1268
        	for (Subject subject: subjects) {
1269 6122 leinfelder
    			XMLAccessDAO accessDAO = new XMLAccessDAO();
1270
        		accessDAO.setPrincipalName(subject.getValue());
1271
    			accessDAO.setGuid(guid);
1272
    			accessDAO.setPermType(AccessControlInterface.ALLOW);
1273 6744 leinfelder
				accessDAO.setPermOrder(existingPermOrder);
1274
    			if (permissions != null) {
1275
	    			for (Permission permission: permissions) {
1276
	    				Long metacatPermission = new Long(convertPermission(permission));
1277
	        			accessDAO.addPermission(metacatPermission);
1278
	    			}
1279 6122 leinfelder
    			}
1280
    			accessDAOs.add(accessDAO);
1281 6108 leinfelder
        	}
1282
        }
1283
1284
1285 6744 leinfelder
        // remove all existing allow records
1286
        accessController.deleteXMLAccessForDoc(guid, AccessControlInterface.ALLOW);
1287
        // add the ones we can for this guid
1288
        accessController.insertAccess(guid, accessDAOs);
1289 6108 leinfelder
1290 6744 leinfelder
1291 6108 leinfelder
    }
1292
1293
    /**
1294
     * Lookup access policy from Metacat
1295
     * @param guid
1296
     * @return
1297
     * @throws McdbDocNotFoundException
1298
     * @throws AccessException
1299
     */
1300 6720 leinfelder
    public AccessPolicy getAccessPolicy(String guid) throws McdbDocNotFoundException, AccessException {
1301 6450 leinfelder
        AccessPolicy accessPolicy = new AccessPolicy();
1302
1303 6122 leinfelder
    	// use GUID to look up the access
1304 6744 leinfelder
        XMLAccessAccess accessController  = new XMLAccessAccess();
1305 6720 leinfelder
        List<XMLAccessDAO> accessDAOs = accessController.getXMLAccessForDoc(guid);
1306
1307 6108 leinfelder
        for (XMLAccessDAO accessDAO: accessDAOs) {
1308 6744 leinfelder
        	// only add allow rule
1309
        	if (accessDAO.getPermType().equals(AccessControlInterface.ALLOW)) {
1310
	        	AccessRule accessRule = new AccessRule();
1311
	        	List <Permission> permissions = convertPermission(accessDAO.getPermission().intValue());
1312 7088 leinfelder
	        	// cannot include if we have no permissions
1313
	        	if (permissions == null || permissions.isEmpty()) {
1314
	        		logMetacat.warn("skipping empty access rule permissions for " + guid);
1315
	        		continue;
1316
	        	}
1317 6744 leinfelder
	        	accessRule.setPermissionList(permissions);
1318
	        	Subject subject = new Subject();
1319
	        	subject.setValue(accessDAO.getPrincipalName());
1320
	        	accessRule.addSubject(subject);
1321
	            accessPolicy.addAllow(accessRule);
1322
        	}
1323 6108 leinfelder
        }
1324
        return accessPolicy;
1325
    }
1326
1327
    public int convertPermission(Permission permission) {
1328
    	if (permission.equals(Permission.READ)) {
1329
    		return AccessControlInterface.READ;
1330
    	}
1331
    	if (permission.equals(Permission.WRITE)) {
1332
    		return AccessControlInterface.WRITE;
1333
    	}
1334
    	if (permission.equals(Permission.CHANGE_PERMISSION)) {
1335
    		return AccessControlInterface.CHMOD;
1336
    	}
1337
		return -1;
1338
    }
1339
1340 6722 leinfelder
    public List<Permission> convertPermission(int permission) {
1341 6744 leinfelder
1342 6722 leinfelder
    	List<Permission> permissions = new ArrayList<Permission>();
1343 6744 leinfelder
    	if (permission == AccessControlInterface.ALL) {
1344 6722 leinfelder
    		permissions.add(Permission.READ);
1345
    		permissions.add(Permission.WRITE);
1346 6744 leinfelder
    		permissions.add(Permission.CHANGE_PERMISSION);
1347 6722 leinfelder
    		return permissions;
1348 6108 leinfelder
    	}
1349 6744 leinfelder
1350
    	if ((permission & AccessControlInterface.CHMOD) == AccessControlInterface.CHMOD) {
1351 6722 leinfelder
    		permissions.add(Permission.CHANGE_PERMISSION);
1352 6108 leinfelder
    	}
1353 6744 leinfelder
    	if ((permission & AccessControlInterface.READ) == AccessControlInterface.READ) {
1354 6722 leinfelder
    		permissions.add(Permission.READ);
1355 6744 leinfelder
    	}
1356
    	if ((permission & AccessControlInterface.WRITE) == AccessControlInterface.WRITE) {
1357 6722 leinfelder
    		permissions.add(Permission.WRITE);
1358 6720 leinfelder
    	}
1359 6744 leinfelder
1360
		return permissions;
1361 6108 leinfelder
    }
1362
1363
    /**
1364 6099 leinfelder
     * Lookup a localId given the GUID. If
1365
     * the identifier is not found, throw an exception.
1366
     *
1367
     * @param guid the global identifier to look up
1368
     * @return String containing the corresponding LocalId
1369
     * @throws McdbDocNotFoundException if the identifier is not found
1370 5334 berkley
     */
1371 6099 leinfelder
    public String getLocalId(String guid) throws McdbDocNotFoundException {
1372 5334 berkley
1373
      String db_guid = "";
1374
      String docid = "";
1375
      int rev = 0;
1376
1377 6099 leinfelder
      String query = "select guid, docid, rev from " + TYPE_IDENTIFIER + " where guid = ?";
1378 5334 berkley
1379
      DBConnection dbConn = null;
1380 5333 berkley
      int serialNumber = -1;
1381 5334 berkley
      try {
1382
          // Get a database connection from the pool
1383
          dbConn = DBConnectionPool.getDBConnection("Identifier.getLocalId");
1384
          serialNumber = dbConn.getCheckOutSerialNumber();
1385
1386
          // Execute the insert statement
1387
          PreparedStatement stmt = dbConn.prepareStatement(query);
1388
          stmt.setString(1, guid);
1389
          ResultSet rs = stmt.executeQuery();
1390
          if (rs.next()) {
1391
              db_guid = rs.getString(1);
1392
              docid = rs.getString(2);
1393
              rev = rs.getInt(3);
1394
              assert(db_guid.equals(guid));
1395
          } else {
1396
              throw new McdbDocNotFoundException("Document not found:" + guid);
1397
          }
1398
          stmt.close();
1399
      } catch (SQLException e) {
1400
          logMetacat.error("Error while looking up the local identifier: "
1401
                  + e.getMessage());
1402
      } finally {
1403
          // Return database connection to the pool
1404
          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1405
      }
1406
      return docid + "." + rev;
1407
    }
1408
1409 5377 berkley
    /**
1410 5895 berkley
     * query the systemmetadata table based on the given parameters
1411
     * @param startTime
1412
     * @param endTime
1413
     * @param objectFormat
1414
     * @param replicaStatus
1415
     * @param start
1416
     * @param count
1417
     * @return ObjectList
1418 6299 leinfelder
     * @throws SQLException
1419
     * @throws ServiceException
1420
     * @throws PropertyNotFoundException
1421 5895 berkley
     */
1422 6836 cjones
    public ObjectList querySystemMetadata(Date startTime, Date endTime,
1423
        ObjectFormatIdentifier objectFormatId, boolean replicaStatus,
1424
        int start, int count)
1425
        throws SQLException, PropertyNotFoundException, ServiceException {
1426 5895 berkley
        ObjectList ol = new ObjectList();
1427 5943 berkley
        DBConnection dbConn = null;
1428
        int serialNumber = -1;
1429 6836 cjones
1430 6299 leinfelder
        try {
1431 7452 leinfelder
            String fieldSql = "select guid, date_uploaded, rights_holder, checksum, "
1432 6836 cjones
                    + "checksum_algorithm, origin_member_node, authoritive_member_node, "
1433
                    + "date_modified, submitter, object_format, size from systemmetadata";
1434 7410 leinfelder
1435
            // handle special case quickly
1436
            String countSql = "select count(guid) from systemmetadata";
1437 7452 leinfelder
1438
            // the clause
1439
            String whereClauseSql = "";
1440 6836 cjones
1441 5895 berkley
            boolean f1 = false;
1442
            boolean f2 = false;
1443
            boolean f3 = false;
1444 6836 cjones
1445 6299 leinfelder
            if (startTime != null) {
1446 7452 leinfelder
                whereClauseSql += " where systemmetadata.date_modified >= ?";
1447 5895 berkley
                f1 = true;
1448
            }
1449 6836 cjones
1450 6299 leinfelder
            if (endTime != null) {
1451
                if (!f1) {
1452 7452 leinfelder
                    whereClauseSql += " where systemmetadata.date_modified < ?";
1453 6836 cjones
                } else {
1454 7452 leinfelder
                    whereClauseSql += " and systemmetadata.date_modified < ?";
1455 5917 berkley
                }
1456 5895 berkley
                f2 = true;
1457
            }
1458 6836 cjones
1459 6337 leinfelder
            if (objectFormatId != null) {
1460 6299 leinfelder
                if (!f1 && !f2) {
1461 7452 leinfelder
                    whereClauseSql += " where object_format = ?";
1462 6836 cjones
                } else {
1463 7452 leinfelder
                    whereClauseSql += " and object_format = ?";
1464 5917 berkley
                }
1465 5895 berkley
                f3 = true;
1466
            }
1467 6836 cjones
1468 7447 cjones
            if (!replicaStatus) {
1469 7030 cjones
                String currentNodeId = PropertyService.getInstance().getProperty("dataone.nodeId");
1470 6299 leinfelder
                if (!f1 && !f2 && !f3) {
1471 7462 leinfelder
                    whereClauseSql += " where authoritive_member_node = '" +
1472 6836 cjones
                        currentNodeId.trim() + "'";
1473
                } else {
1474 7462 leinfelder
                    whereClauseSql += " and authoritive_member_node = '" +
1475 6836 cjones
                        currentNodeId.trim() + "'";
1476 5917 berkley
                }
1477 5895 berkley
            }
1478 7310 leinfelder
1479 7452 leinfelder
            // connection
1480 5943 berkley
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.querySystemMetadata");
1481
            serialNumber = dbConn.getCheckOutSerialNumber();
1482 6836 cjones
1483 7452 leinfelder
            // the field query
1484
            String orderBySql = " order by guid ";
1485
            String fieldQuery = fieldSql + whereClauseSql + orderBySql;
1486
            String finalQuery = DatabaseService.getInstance().getDBAdapter().getPagedQuery(fieldQuery, start, count);
1487
            PreparedStatement fieldStmt = dbConn.prepareStatement(finalQuery);
1488
1489
            // construct the count query and statment
1490
            String countQuery = countSql + whereClauseSql;
1491
            PreparedStatement countStmt = dbConn.prepareStatement(countQuery);
1492
1493 6299 leinfelder
            if (f1 && f2 && f3) {
1494 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1495
                fieldStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1496
                fieldStmt.setString(3, objectFormatId.getValue());
1497
                // count
1498
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1499
                countStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1500
                countStmt.setString(3, objectFormatId.getValue());
1501 6836 cjones
            } else if (f1 && f2 && !f3) {
1502 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1503
                fieldStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1504
                // count
1505
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1506
                countStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1507 6836 cjones
            } else if (f1 && !f2 && f3) {
1508 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1509
                fieldStmt.setString(2, objectFormatId.getValue());
1510
                // count
1511
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1512
                countStmt.setString(2, objectFormatId.getValue());
1513 6836 cjones
            } else if (f1 && !f2 && !f3) {
1514 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1515
                // count
1516
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1517 6836 cjones
            } else if (!f1 && f2 && f3) {
1518 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1519
                fieldStmt.setString(2, objectFormatId.getValue());
1520
                // count
1521
                countStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1522
                countStmt.setString(2, objectFormatId.getValue());
1523 6836 cjones
            } else if (!f1 && !f2 && f3) {
1524 7452 leinfelder
                fieldStmt.setString(1, objectFormatId.getValue());
1525
                // count
1526
                countStmt.setString(1, objectFormatId.getValue());
1527 6836 cjones
            } else if (!f1 && f2 && !f3) {
1528 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1529
                // count
1530
                countStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1531 5895 berkley
            }
1532 6836 cjones
1533 7461 leinfelder
            logMetacat.debug("list objects fieldStmt: " + fieldStmt.toString());
1534
1535
            logMetacat.debug("list objects countStmt: " + countStmt.toString());
1536
1537 7452 leinfelder
            // get the total object count no matter what
1538
            int total = 0;
1539
            ResultSet totalResult = countStmt.executeQuery();
1540
            if (totalResult.next()) {
1541
            	total = totalResult.getInt(1);
1542 5895 berkley
            }
1543 7438 leinfelder
1544 7461 leinfelder
            logMetacat.debug("list objects total: " + total);
1545
1546 7452 leinfelder
        	// set the totals
1547
        	ol.setStart(start);
1548
            ol.setCount(count);
1549
            ol.setTotal(total);
1550
1551
            // retrieve the actual records if requested
1552
            if (count != 0) {
1553
1554
                ResultSet rs = fieldStmt.executeQuery();
1555 7410 leinfelder
	            while (rs.next()) {
1556 7438 leinfelder
1557 7410 leinfelder
	                String guid = rs.getString(1);
1558 7461 leinfelder
	                logMetacat.debug("query found object with guid " + guid);
1559 7410 leinfelder
	                // Timestamp dateUploaded = rs.getTimestamp(2);
1560
	                // String rightsHolder = rs.getString(3);
1561
	                String checksum = rs.getString(4);
1562
	                String checksumAlgorithm = rs.getString(5);
1563
	                // String originMemberNode = rs.getString(6);
1564
	                // String authoritiveMemberNode = rs.getString(7);
1565
	                Timestamp dateModified = rs.getTimestamp(8);
1566
	                // String submitter = rs.getString(9);
1567
	                String fmtidStr = rs.getString(10);
1568
	                String sz = rs.getString(11);
1569
	                BigInteger size = new BigInteger("0");
1570
1571
	                if (sz != null && !sz.trim().equals("")) {
1572
	                    size = new BigInteger(rs.getString(11));
1573
	                }
1574
1575
	                ObjectInfo oi = new ObjectInfo();
1576
1577
	                Identifier id = new Identifier();
1578
	                id.setValue(guid);
1579
	                oi.setIdentifier(id);
1580
1581
	                if (dateModified != null) {
1582
	                    oi.setDateSysMetadataModified(dateModified);
1583
	                }
1584
1585
	                Checksum cs = new Checksum();
1586
	                cs.setValue(checksum);
1587
	                try {
1588
	                    // cs.setAlgorithm(ChecksumAlgorithm.valueOf(checksumAlgorithm));
1589
	                    cs.setAlgorithm(checksumAlgorithm);
1590
	                } catch (Exception e) {
1591
	                    logMetacat.error("could not parse checksum algorithm", e);
1592
	                    continue;
1593
	                }
1594
	                oi.setChecksum(cs);
1595
1596
	                // set the format type
1597
	                ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
1598
	                fmtid.setValue(fmtidStr);
1599
	                oi.setFormatId(fmtid);
1600
1601
	                oi.setSize(size);
1602
1603 7438 leinfelder
	                ol.addObjectInfo(oi);
1604
1605 7410 leinfelder
	            }
1606 7452 leinfelder
1607 7461 leinfelder
	            logMetacat.debug("list objects count: " + ol.sizeObjectInfoList());
1608
1609 7452 leinfelder
	            // set the actual count retrieved
1610
	            ol.setCount(ol.sizeObjectInfoList());
1611 7410 leinfelder
1612
	        }
1613
1614 5895 berkley
        }
1615 6836 cjones
1616 6299 leinfelder
        finally {
1617 5943 berkley
            // Return database connection to the pool
1618
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1619
        }
1620 6836 cjones
1621 5895 berkley
        return ol;
1622
    }
1623
1624
    /**
1625 6099 leinfelder
     * create a mapping in the identifier table
1626 5377 berkley
     * @param guid
1627
     * @param localId
1628
     */
1629 6099 leinfelder
    public void createMapping(String guid, String localId)
1630 5453 berkley
    {
1631 5334 berkley
1632
        int serialNumber = -1;
1633 5333 berkley
        DBConnection dbConn = null;
1634
        try {
1635
1636
            // Parse the localId into scope and rev parts
1637
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
1638
            String docid = acc.getDocid();
1639 5344 berkley
            int rev = 1;
1640 6099 leinfelder
            if (acc.getRev() != null) {
1641 5344 berkley
              rev = (new Integer(acc.getRev()).intValue());
1642
            }
1643 5333 berkley
1644
            // Get a database connection from the pool
1645 6099 leinfelder
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.createMapping");
1646 5333 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
1647
1648
            // Execute the insert statement
1649 6099 leinfelder
            String query = "insert into " + TYPE_IDENTIFIER + " (guid, docid, rev) values (?, ?, ?)";
1650 5333 berkley
            PreparedStatement stmt = dbConn.prepareStatement(query);
1651
            stmt.setString(1, guid);
1652
            stmt.setString(2, docid);
1653
            stmt.setInt(3, rev);
1654 6099 leinfelder
            logMetacat.debug("mapping query: " + stmt.toString());
1655 5333 berkley
            int rows = stmt.executeUpdate();
1656
1657
            stmt.close();
1658
        } catch (SQLException e) {
1659 5344 berkley
            e.printStackTrace();
1660 6099 leinfelder
            logMetacat.error("createGenericMapping: SQL error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1661 5333 berkley
                    + e.getMessage());
1662
        } catch (NumberFormatException e) {
1663 5344 berkley
            e.printStackTrace();
1664 6099 leinfelder
            logMetacat.error("createGenericMapping: NumberFormat error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1665 5333 berkley
                    + e.getMessage());
1666
        } catch (AccessionNumberException e) {
1667 5344 berkley
            e.printStackTrace();
1668 6099 leinfelder
            logMetacat.error("createGenericMapping: AccessionNumber error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1669 5333 berkley
                    + e.getMessage());
1670
        } finally {
1671
            // Return database connection to the pool
1672
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1673
        }
1674
    }
1675 6099 leinfelder
1676
    /**
1677 7017 leinfelder
     * remove a mapping in the identifier table
1678
     * @param guid
1679
     * @param localId
1680
     */
1681
    public void removeMapping(String guid, String localId)
1682
    {
1683
1684
        int serialNumber = -1;
1685
        DBConnection dbConn = null;
1686
        try {
1687
1688
            // Parse the localId into scope and rev parts
1689
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
1690
            String docid = acc.getDocid();
1691
            int rev = 1;
1692
            if (acc.getRev() != null) {
1693
              rev = (new Integer(acc.getRev()).intValue());
1694
            }
1695
1696
            // Get a database connection from the pool
1697
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.removeMapping");
1698
            serialNumber = dbConn.getCheckOutSerialNumber();
1699
1700
            // Execute the insert statement
1701
            String query = "DELETE FROM " + TYPE_IDENTIFIER + " WHERE guid = ? AND docid = ? AND rev = ?";
1702
            PreparedStatement stmt = dbConn.prepareStatement(query);
1703
            stmt.setString(1, guid);
1704
            stmt.setString(2, docid);
1705
            stmt.setInt(3, rev);
1706
            logMetacat.debug("remove mapping query: " + stmt.toString());
1707
            int rows = stmt.executeUpdate();
1708
1709
            stmt.close();
1710
        } catch (SQLException e) {
1711
            e.printStackTrace();
1712
            logMetacat.error("removeMapping: SQL error while removing a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1713
                    + e.getMessage());
1714
        } catch (NumberFormatException e) {
1715
            e.printStackTrace();
1716
            logMetacat.error("removeMapping: NumberFormat error while removing a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1717
                    + e.getMessage());
1718
        } catch (AccessionNumberException e) {
1719
            e.printStackTrace();
1720
            logMetacat.error("removeMapping: AccessionNumber error while removing a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1721
                    + e.getMessage());
1722
        } finally {
1723
            // Return database connection to the pool
1724
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1725
        }
1726
    }
1727
1728
    /**
1729 6099 leinfelder
     * create the systemmetadata record
1730
     * @param guid
1731 7188 leinfelder
     * @param dbConn
1732
     * @throws SQLException
1733 6099 leinfelder
     */
1734 7188 leinfelder
    private void insertSystemMetadata(String guid, DBConnection dbConn) throws SQLException
1735 6099 leinfelder
    {
1736
1737 7188 leinfelder
        // Execute the insert statement
1738
        String query = "insert into " + TYPE_SYSTEM_METADATA + " (guid) values (?)";
1739
        PreparedStatement stmt = dbConn.prepareStatement(query);
1740
        stmt.setString(1, guid);
1741
        logMetacat.debug("system metadata query: " + stmt.toString());
1742
        int rows = stmt.executeUpdate();
1743 6099 leinfelder
1744 7188 leinfelder
        stmt.close();
1745
1746 6099 leinfelder
    }
1747 6277 leinfelder
1748 6648 leinfelder
    public void deleteSystemMetadata(String guid)
1749 6277 leinfelder
    {
1750
1751
        int serialNumber = -1;
1752
        DBConnection dbConn = null;
1753 6648 leinfelder
        String query = null;
1754
        PreparedStatement stmt = null;
1755
        int rows = 0;
1756 6277 leinfelder
        try {
1757
1758
            // Get a database connection from the pool
1759 6648 leinfelder
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.deleteSystemMetadata");
1760 6277 leinfelder
            serialNumber = dbConn.getCheckOutSerialNumber();
1761
1762 6648 leinfelder
            // remove main system metadata entry
1763
            query = "delete from " + TYPE_SYSTEM_METADATA + " where guid = ? ";
1764
            stmt = dbConn.prepareStatement(query);
1765 6277 leinfelder
            stmt.setString(1, guid);
1766
            logMetacat.debug("delete system metadata: " + stmt.toString());
1767 6648 leinfelder
            rows = stmt.executeUpdate();
1768 6277 leinfelder
            stmt.close();
1769 6648 leinfelder
1770 7392 leinfelder
            // remove the smReplicationPolicy
1771
            query = "delete from smReplicationPolicy " +
1772 6648 leinfelder
            "where guid = ?";
1773
            stmt = dbConn.prepareStatement(query);
1774
            stmt.setString(1, guid);
1775 7392 leinfelder
            logMetacat.debug("delete smReplicationPolicy: " + stmt.toString());
1776 6648 leinfelder
            rows = stmt.executeUpdate();
1777
            stmt.close();
1778
1779 7392 leinfelder
            // remove the smReplicationStatus
1780
            query = "delete from smReplicationStatus " +
1781 6648 leinfelder
            "where guid = ?";
1782
            stmt = dbConn.prepareStatement(query);
1783
            stmt.setString(1, guid);
1784 7392 leinfelder
            logMetacat.debug("delete smReplicationStatus: " + stmt.toString());
1785 6648 leinfelder
            rows = stmt.executeUpdate();
1786
            stmt.close();
1787
1788 6744 leinfelder
            // TODO: remove the access?
1789 6648 leinfelder
            // Metacat keeps "deleted" documents so we should not remove access rules.
1790
1791 6277 leinfelder
        } catch (Exception e) {
1792
            e.printStackTrace();
1793
            logMetacat.error("Error while deleting " + TYPE_SYSTEM_METADATA + " record: " + guid, e );
1794 6648 leinfelder
            try {
1795
				dbConn.rollback();
1796
			} catch (SQLException sqle) {
1797
	            logMetacat.error("Error while rolling back delete for record: " + guid, sqle );
1798
			}
1799 6277 leinfelder
        } finally {
1800
            // Return database connection to the pool
1801
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1802
        }
1803
    }
1804 6862 leinfelder
1805
    public void updateAuthoritativeMemberNodeId(String existingMemberNodeId, String newMemberNodeId)
1806
    {
1807
        DBConnection dbConn = null;
1808
        int serialNumber = -1;
1809
1810
        try {
1811
            // Get a database connection from the pool
1812
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.updateAuthoritativeMemberNodeId");
1813
            serialNumber = dbConn.getCheckOutSerialNumber();
1814
1815
            // Execute the insert statement
1816
            String query = "update " + TYPE_SYSTEM_METADATA +
1817
                " set authoritive_member_node = ? " +
1818
                " where authoritive_member_node = ?";
1819
            PreparedStatement stmt = dbConn.prepareStatement(query);
1820
1821
            //data values
1822
            stmt.setString(1, newMemberNodeId);
1823
            stmt.setString(2, existingMemberNodeId);
1824
1825
            logMetacat.debug("stmt: " + stmt.toString());
1826
            //execute
1827
            int rows = stmt.executeUpdate();
1828
1829
            stmt.close();
1830
        } catch (SQLException e) {
1831
            e.printStackTrace();
1832
            logMetacat.error("updateSystemMetadataFields: SQL error while updating system metadata: "
1833
                    + e.getMessage());
1834
        } catch (NumberFormatException e) {
1835
            e.printStackTrace();
1836
            logMetacat.error("updateSystemMetadataFields: NumberFormat error while updating system metadata: "
1837
                    + e.getMessage());
1838
        } finally {
1839
            // Return database connection to the pool
1840
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1841
        }
1842
    }
1843 5282 jones
}