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