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