Project

General

Profile

1 5282 jones
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2010 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author: jones $'
7
 *     '$Date: 2010-02-03 17:58:12 -0900 (Wed, 03 Feb 2010) $'
8
 * '$Revision: 5211 $'
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 */
24
25
package edu.ucsb.nceas.metacat;
26
27 6384 cjones
import java.math.BigInteger;
28 5282 jones
import java.sql.PreparedStatement;
29
import java.sql.ResultSet;
30
import java.sql.SQLException;
31 5895 berkley
import java.sql.Timestamp;
32 6107 leinfelder
import java.util.ArrayList;
33
import java.util.Date;
34
import java.util.Hashtable;
35
import java.util.List;
36
import java.util.Vector;
37 5282 jones
38
import org.apache.log4j.Logger;
39 6124 cjones
import org.dataone.client.ObjectFormatCache;
40 7010 cjones
import org.dataone.service.exceptions.BaseException;
41 6904 cjones
import org.dataone.service.exceptions.InvalidSystemMetadata;
42 6124 cjones
import org.dataone.service.exceptions.NotFound;
43 7010 cjones
import org.dataone.service.exceptions.NotImplemented;
44
import org.dataone.service.exceptions.ServiceFailure;
45 6366 leinfelder
import org.dataone.service.types.v1.AccessPolicy;
46
import org.dataone.service.types.v1.AccessRule;
47
import org.dataone.service.types.v1.Checksum;
48
import org.dataone.service.types.v1.Identifier;
49
import org.dataone.service.types.v1.NodeReference;
50
import org.dataone.service.types.v1.ObjectFormatIdentifier;
51
import org.dataone.service.types.v1.ObjectInfo;
52
import org.dataone.service.types.v1.ObjectList;
53
import org.dataone.service.types.v1.Permission;
54
import org.dataone.service.types.v1.Replica;
55
import org.dataone.service.types.v1.ReplicationPolicy;
56
import org.dataone.service.types.v1.ReplicationStatus;
57
import org.dataone.service.types.v1.Subject;
58
import org.dataone.service.types.v1.SystemMetadata;
59 5282 jones
60 6108 leinfelder
import edu.ucsb.nceas.metacat.accesscontrol.AccessControlInterface;
61
import edu.ucsb.nceas.metacat.accesscontrol.XMLAccessAccess;
62
import edu.ucsb.nceas.metacat.accesscontrol.XMLAccessDAO;
63 5282 jones
import edu.ucsb.nceas.metacat.database.DBConnection;
64
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
65 5887 berkley
import edu.ucsb.nceas.metacat.properties.PropertyService;
66 6108 leinfelder
import edu.ucsb.nceas.metacat.shared.AccessException;
67 6299 leinfelder
import edu.ucsb.nceas.metacat.shared.ServiceException;
68 5286 jones
import edu.ucsb.nceas.metacat.util.DocumentUtil;
69 6299 leinfelder
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
70 5282 jones
71
/**
72
 * Manage the relationship between Metacat local identifiers (LocalIDs) that are
73 6099 leinfelder
 * codified as the (docid, rev) pair with globally unique string identifiers
74 5282 jones
 * (GUIDs) that are opaque strings.  This class provides methods to manage these
75
 * identifiers, and to search for and look up LocalIDs based on their GUID and
76
 * vice versa. IdentifierManager is a singleton.
77
 *
78
 * @author Matthew Jones
79
 */
80
public class IdentifierManager {
81
82 5334 berkley
    public static final String TYPE_SYSTEM_METADATA = "systemmetadata";
83
    public static final String TYPE_IDENTIFIER = "identifier";
84
85 5282 jones
    /**
86
     * The single instance of the manager that is always returned.
87
     */
88
    private static IdentifierManager self = null;
89 6099 leinfelder
    private Logger logMetacat = Logger.getLogger(IdentifierManager.class);
90 5282 jones
91
    /**
92
     * A private constructor that initializes the class when getInstance() is
93
     * called.
94
     */
95 6099 leinfelder
    private IdentifierManager() {}
96 5282 jones
97
    /**
98
     * Return the single instance of the manager after initializing it if it
99
     * wasn't previously initialized.
100
     *
101
     * @return the single IdentifierManager instance
102
     */
103
    public static IdentifierManager getInstance()
104
    {
105
        if (self == null) {
106
            self = new IdentifierManager();
107
        }
108
        return self;
109
    }
110
111 6097 leinfelder
    public SystemMetadata asSystemMetadata(Date dateUploaded, String rightsHolder,
112
            String checksum, String checksumAlgorithm, String originMemberNode,
113
            String authoritativeMemberNode, Date dateModified, String submitter,
114 6561 leinfelder
            String guid, String fmtidStr, BigInteger size, BigInteger serialVersion) {
115 6097 leinfelder
        SystemMetadata sysMeta = new SystemMetadata();
116
117
        Identifier sysMetaId = new Identifier();
118
        sysMetaId.setValue(guid);
119
        sysMeta.setIdentifier(sysMetaId);
120
        sysMeta.setDateUploaded(dateUploaded);
121
        Subject rightsHolderSubject = new Subject();
122
        rightsHolderSubject.setValue(rightsHolder);
123
        sysMeta.setRightsHolder(rightsHolderSubject);
124
        Checksum checksumObject = new Checksum();
125
        checksumObject.setValue(checksum);
126 6397 leinfelder
        checksumObject.setAlgorithm(checksumAlgorithm);
127 6097 leinfelder
        sysMeta.setChecksum(checksumObject);
128
        NodeReference omn = new NodeReference();
129
        omn.setValue(originMemberNode);
130
        sysMeta.setOriginMemberNode(omn);
131
        NodeReference amn = new NodeReference();
132
        amn.setValue(authoritativeMemberNode);
133
        sysMeta.setAuthoritativeMemberNode(amn);
134
        sysMeta.setDateSysMetadataModified(dateModified);
135
        Subject submitterSubject = new Subject();
136
        submitterSubject.setValue(submitter);
137
        sysMeta.setSubmitter(submitterSubject);
138 7010 cjones
        ObjectFormatIdentifier fmtid = null;
139 6124 cjones
        try {
140 7010 cjones
        	ObjectFormatIdentifier formatId = new ObjectFormatIdentifier();
141
        	formatId.setValue(fmtidStr);
142
        	fmtid = ObjectFormatCache.getInstance().getFormat(formatId).getFormatId();
143 6561 leinfelder
        	sysMeta.setFormatId(fmtid);
144 7010 cjones
145
        } catch (BaseException nfe) {
146
            logMetacat.error("The objectFormat " + fmtidStr +
147 6384 cjones
          	" is not registered. Setting the default format id.");
148 7010 cjones
            fmtid = new ObjectFormatIdentifier();
149
            fmtid.setValue("application/octet-stream");
150
            sysMeta.setFormatId(fmtid);
151
152 6124 cjones
        }
153 6097 leinfelder
        sysMeta.setSize(size);
154 6561 leinfelder
        sysMeta.setSerialVersion(serialVersion);
155 6097 leinfelder
156
        return sysMeta;
157
    }
158
159 5282 jones
    /**
160 5895 berkley
     * return a hash of all of the info that is in the systemmetadata table
161
     * @param localId
162
     * @return
163
     */
164
    public Hashtable<String, String> getSystemMetadataInfo(String localId)
165
    throws McdbDocNotFoundException
166
    {
167
        try
168
        {
169
            AccessionNumber acc = new AccessionNumber(localId, "NONE");
170
            localId = acc.getDocid();
171
        }
172
        catch(Exception e)
173
        {
174
            //do nothing. just try the localId as it is
175
        }
176
        Hashtable<String, String> h = new Hashtable<String, String>();
177
        String sql = "select guid, date_uploaded, rights_holder, checksum, checksum_algorithm, " +
178 5944 berkley
          "origin_member_node, authoritive_member_node, date_modified, submitter, object_format, size " +
179 5895 berkley
          "from systemmetadata where docid = ?";
180
        DBConnection dbConn = null;
181
        int serialNumber = -1;
182
        try
183
        {
184
            // Get a database connection from the pool
185
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getDocumentInfo");
186
            serialNumber = dbConn.getCheckOutSerialNumber();
187
188
            // Execute the insert statement
189
            PreparedStatement stmt = dbConn.prepareStatement(sql);
190
            stmt.setString(1, localId);
191
            ResultSet rs = stmt.executeQuery();
192
            if (rs.next())
193
            {
194
                String guid = rs.getString(1);
195
                Timestamp dateUploaded = rs.getTimestamp(2);
196
                String rightsHolder = rs.getString(3);
197
                String checksum = rs.getString(4);
198
                String checksumAlgorithm = rs.getString(5);
199
                String originMemberNode = rs.getString(6);
200
                String authoritativeMemberNode = rs.getString(7);
201
                Timestamp dateModified = rs.getTimestamp(8);
202
                String submitter = rs.getString(9);
203 5917 berkley
                String objectFormat = rs.getString(10);
204
                long size = new Long(rs.getString(11)).longValue();
205 5895 berkley
206
                h.put("guid", guid);
207
                h.put("date_uploaded", new Long(dateUploaded.getTime()).toString());
208
                h.put("rights_holder", rightsHolder);
209
                h.put("checksum", checksum);
210
                h.put("checksum_algorithm", checksumAlgorithm);
211
                h.put("origin_member_node", originMemberNode);
212
                h.put("authoritative_member_node", authoritativeMemberNode);
213
                h.put("date_modified", new Long(dateModified.getTime()).toString());
214
                h.put("submitter", submitter);
215 5917 berkley
                h.put("object_format", objectFormat);
216
                h.put("size", new Long(size).toString());
217 5895 berkley
218
                stmt.close();
219
            }
220
            else
221
            {
222
                stmt.close();
223
                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
224
                throw new McdbDocNotFoundException("2Could not find document " + localId);
225
            }
226
227
        }
228
        catch (SQLException e)
229
        {
230
            e.printStackTrace();
231
            logMetacat.error("Error while getting system metadata info for localid " + localId + " : "
232
                    + e.getMessage());
233
        }
234
        finally
235
        {
236
            // Return database connection to the pool
237
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
238
        }
239
        return h;
240
    }
241
242
    /**
243 6097 leinfelder
     * return a hash of all of the info that is in the systemmetadata table
244 6099 leinfelder
     * @param guid
245 6097 leinfelder
     * @return
246 6108 leinfelder
     * @throws McdbDocNotFoundException
247 6097 leinfelder
     */
248 6099 leinfelder
    public SystemMetadata getSystemMetadata(String guid)
249 6097 leinfelder
    	throws McdbDocNotFoundException
250
    {
251 6099 leinfelder
252 6097 leinfelder
        SystemMetadata sysMeta = new SystemMetadata();
253
        String sql = "select guid, date_uploaded, rights_holder, checksum, checksum_algorithm, " +
254 6375 leinfelder
          "origin_member_node, authoritive_member_node, date_modified, submitter, object_format, size, " +
255 6561 leinfelder
          "replication_allowed, number_replicas, obsoletes, obsoleted_by, serial_version " +
256 6099 leinfelder
          "from systemmetadata where guid = ?";
257 6097 leinfelder
        DBConnection dbConn = null;
258
        int serialNumber = -1;
259 6533 cjones
        Boolean replicationAllowed = new Boolean(false);
260
        BigInteger numberOfReplicas = new BigInteger("-1");
261 6561 leinfelder
        BigInteger serialVersion = new BigInteger("-1");
262
263 6097 leinfelder
        try
264
        {
265
            // Get a database connection from the pool
266
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getSystemMetadata");
267
            serialNumber = dbConn.getCheckOutSerialNumber();
268
269
            // Execute the statement
270
            PreparedStatement stmt = dbConn.prepareStatement(sql);
271 6099 leinfelder
            stmt.setString(1, guid);
272 6097 leinfelder
            ResultSet rs = stmt.executeQuery();
273
            if (rs.next())
274
            {
275
                Timestamp dateUploaded = rs.getTimestamp(2);
276
                String rightsHolder = rs.getString(3);
277
                String checksum = rs.getString(4);
278
                String checksumAlgorithm = rs.getString(5);
279
                String originMemberNode = rs.getString(6);
280
                String authoritativeMemberNode = rs.getString(7);
281
                Timestamp dateModified = rs.getTimestamp(8);
282
                String submitter = rs.getString(9);
283 6296 cjones
                String fmtidStr = rs.getString(10);
284 6384 cjones
                BigInteger size = new BigInteger(rs.getString(11));
285 6535 cjones
                replicationAllowed = new Boolean(rs.getBoolean(12));
286 6533 cjones
                numberOfReplicas = new BigInteger(rs.getString(13));
287
                String obsoletes = rs.getString(14);
288
                String obsoletedBy = rs.getString(15);
289 6561 leinfelder
                serialVersion = new BigInteger(rs.getString(16));
290 6375 leinfelder
291 6561 leinfelder
292 6097 leinfelder
                Identifier sysMetaId = new Identifier();
293
                sysMetaId.setValue(guid);
294
                sysMeta.setIdentifier(sysMetaId);
295 6561 leinfelder
                sysMeta.setSerialVersion(serialVersion);
296 6097 leinfelder
                sysMeta.setDateUploaded(dateUploaded);
297
                Subject rightsHolderSubject = new Subject();
298
                rightsHolderSubject.setValue(rightsHolder);
299
                sysMeta.setRightsHolder(rightsHolderSubject);
300
                Checksum checksumObject = new Checksum();
301
                checksumObject.setValue(checksum);
302 6397 leinfelder
                checksumObject.setAlgorithm(checksumAlgorithm);
303 6097 leinfelder
                sysMeta.setChecksum(checksumObject);
304 6519 leinfelder
                if (originMemberNode != null) {
305
	                NodeReference omn = new NodeReference();
306
	                omn.setValue(originMemberNode);
307
	                sysMeta.setOriginMemberNode(omn);
308
                }
309
                if (authoritativeMemberNode != null) {
310
	                NodeReference amn = new NodeReference();
311
	                amn.setValue(authoritativeMemberNode);
312
	                sysMeta.setAuthoritativeMemberNode(amn);
313
                }
314 6097 leinfelder
                sysMeta.setDateSysMetadataModified(dateModified);
315
                Subject submitterSubject = new Subject();
316
                submitterSubject.setValue(submitter);
317
                sysMeta.setSubmitter(submitterSubject);
318 7023 leinfelder
                ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
319
                fmtid.setValue(fmtidStr);
320
            	sysMeta.setFormatId(fmtid);
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 7045 leinfelder
     * NOTE: looks in the identifier and system metadata table for a match
749
     * (in that order)
750 5282 jones
     *
751
     * @param guid the global identifier to look up
752
     * @return boolean true if the identifier exists
753
     */
754
    public boolean identifierExists(String guid)
755
    {
756
        boolean idExists = false;
757
        try {
758
            String id = getLocalId(guid);
759
            if (id != null) {
760
                idExists = true;
761
            }
762
        } catch (McdbDocNotFoundException e) {
763 6123 leinfelder
        	// try system metadata only
764
        	try {
765 6416 rnahf
        		idExists = systemMetadataExists(guid);
766 6454 leinfelder
            } catch (Exception e2) {
767 6123 leinfelder
            	idExists = false;
768
            }
769 5282 jones
        }
770
        return idExists;
771
    }
772
773
    /**
774 7045 leinfelder
     * Determine if an identifier mapping exists already,
775
     * returning true if so.
776 5282 jones
     *
777 7045 leinfelder
     * @param guid the global identifier to look up
778
     * @return boolean true if the identifier exists
779
     */
780
    public boolean mappingExists(String guid)
781
    {
782
        boolean idExists = false;
783
        try {
784
            String id = getLocalId(guid);
785
            if (id != null) {
786
                idExists = true;
787
            }
788
        } catch (McdbDocNotFoundException e) {
789
        	// nope!
790
        }
791
        return idExists;
792
    }
793
794
    /**
795
     *
796 5453 berkley
     * @param guid
797
     * @param rev
798
     * @return
799
     */
800
    public String generateLocalId(String guid, int rev)
801
    {
802
        return generateLocalId(guid, rev, false);
803
    }
804 5286 jones
805
    /**
806
     * Given a global identifier (guid), create a suitable local identifier that
807
     * follows Metacat's docid semantics and format (scope.id.rev), and create
808
     * a mapping between these two identifiers.  This effectively reserves both
809
     * the global and the local identifier, as they will now be present in the
810 7070 leinfelder
     * identifier mapping table.
811
     *
812
     * REMOVED feature: If the incoming guid has the syntax of a
813 5286 jones
     * Metacat docid (scope.id.rev), then simply use it.
814 7070 leinfelder
     * WHY: because "test.1.001" becomes "test.1.1" which is not correct for DataONE
815
     * identifier use (those revision numbers are just chartacters and should not be interpreted)
816 5286 jones
     *
817
     * @param guid the global string identifier
818
     * @param rev the revision number to be used in the localId
819
     * @return String containing the localId to be used for Metacat operations
820
     */
821 5453 berkley
    public String generateLocalId(String guid, int rev, boolean isSystemMetadata)
822 5286 jones
    {
823
        String localId = "";
824
        boolean conformsToDocidFormat = false;
825
826 7070 leinfelder
        // BRL -- do not allow Metacat-conforming IDs to be used:
827
        // test.1.001 becomes test.1.1 which is NOT correct for DataONE identifiers
828 5286 jones
        // Check if the guid passed in is already in docid (scope.id.rev) format
829 7070 leinfelder
//        try {
830
//            AccessionNumber acc = new AccessionNumber(guid, "NONE");
831
//            if (new Integer(acc.getRev()).intValue() > 0) {
832
//                conformsToDocidFormat = true;
833
//            }
834
//        } catch (NumberFormatException e) {
835
//            // No action needed, simply detecting invalid AccessionNumbers
836
//        } catch (AccessionNumberException e) {
837
//            // No action needed, simply detecting invalid AccessionNumbers
838
//        } catch (SQLException e) {
839
//            // No action needed, simply detecting invalid AccessionNumbers
840
//        }
841 5286 jones
842
        if (conformsToDocidFormat) {
843
            // if it conforms, use it for both guid and localId
844
            localId = guid;
845
        } else {
846
            // if not, then generate a new unique localId
847
            localId = DocumentUtil.generateDocumentId(rev);
848
        }
849
850
        // Register this new pair in the identifier mapping table
851 6099 leinfelder
        logMetacat.debug("creating mapping in generateLocalId");
852 5453 berkley
        if(!isSystemMetadata)
853
        { //don't do this if we're generating for system metadata
854
            createMapping(guid, localId);
855
        }
856 5286 jones
857
        return localId;
858
    }
859 5322 berkley
860
    /**
861
     * given a local identifer, look up the guid.  Throw McdbDocNotFoundException
862 5452 berkley
     * if the docid, rev is not found in the identifiers or systemmetadata tables
863 5322 berkley
     *
864
     * @param docid the docid to look up
865
     * @param rev the revision of the docid to look up
866
     * @return String containing the mapped guid
867
     * @throws McdbDocNotFoundException if the docid, rev is not found
868
     */
869
    public String getGUID(String docid, int rev)
870
      throws McdbDocNotFoundException
871
    {
872 6099 leinfelder
        logMetacat.debug("getting guid for " + docid);
873 5322 berkley
        String query = "select guid from identifier where docid = ? and rev = ?";
874
        String guid = null;
875
876
        DBConnection dbConn = null;
877
        int serialNumber = -1;
878
        try {
879
            // Get a database connection from the pool
880 5377 berkley
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getGUID");
881 5322 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
882
883
            // Execute the insert statement
884
            PreparedStatement stmt = dbConn.prepareStatement(query);
885
            stmt.setString(1, docid);
886
            stmt.setInt(2, rev);
887
            ResultSet rs = stmt.executeQuery();
888 5451 berkley
            if (rs.next())
889
            {
890 5322 berkley
                guid = rs.getString(1);
891 5451 berkley
            }
892
            else
893
            {
894 6104 leinfelder
            	throw new McdbDocNotFoundException("No guid registered for docid " + docid + "." + rev);
895 5322 berkley
            }
896 5451 berkley
897 5322 berkley
        } catch (SQLException e) {
898
            logMetacat.error("Error while looking up the guid: "
899
                    + e.getMessage());
900
        } finally {
901
            // Return database connection to the pool
902
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
903
        }
904
905
        return guid;
906
    }
907 5333 berkley
908 6454 leinfelder
    public boolean systemMetadataExists(String guid) {
909 6123 leinfelder
		logMetacat.debug("looking up system metadata for guid " + guid);
910
		boolean exists = false;
911 6337 leinfelder
		String query = "select guid from systemmetadata where guid = ?";
912 6123 leinfelder
913
		DBConnection dbConn = null;
914
		int serialNumber = -1;
915
		try {
916
			// Get a database connection from the pool
917
			dbConn = DBConnectionPool.getDBConnection("IdentifierManager.systemMetadataExisits");
918
			serialNumber = dbConn.getCheckOutSerialNumber();
919
920
			// Execute the insert statement
921
			PreparedStatement stmt = dbConn.prepareStatement(query);
922
			stmt.setString(1, guid);
923
			ResultSet rs = stmt.executeQuery();
924
			if (rs.next()) {
925
				exists = true;
926
			}
927
928
		} catch (SQLException e) {
929
			logMetacat.error("Error while looking up the system metadata: "
930
					+ e.getMessage());
931
		} finally {
932
			// Return database connection to the pool
933
			DBConnectionPool.returnDBConnection(dbConn, serialNumber);
934
		}
935
936
		return exists;
937
	}
938
939 5333 berkley
    /**
940 5887 berkley
     * creates a system metadata mapping and adds additional fields from sysmeta
941
     * to the table for quick searching.
942
     *
943
     * @param guid the id to insert
944
     * @param localId the systemMetadata object to get the local id for
945 6108 leinfelder
     * @throws McdbDocNotFoundException
946 6892 cjones
     * @throws SQLException
947 6904 cjones
     * @throws InvalidSystemMetadata
948 5887 berkley
     */
949 6997 leinfelder
    public void insertSystemMetadata(SystemMetadata sysmeta)
950 6904 cjones
        throws McdbDocNotFoundException, SQLException, InvalidSystemMetadata {
951 6277 leinfelder
    	String guid = sysmeta.getIdentifier().getValue();
952 6337 leinfelder
    	// insert the record
953
        insertSystemMetadata(guid);
954
        // update with the values
955 6099 leinfelder
        updateSystemMetadata(sysmeta);
956 6892 cjones
957 5887 berkley
    }
958 6099 leinfelder
959 5887 berkley
960
    /**
961 6079 leinfelder
     * update a mapping
962
     * @param guid
963
     * @param localId
964
     */
965
    public void updateMapping(String guid, String localId)
966
    {
967
968 6099 leinfelder
        logMetacat.debug("$$$$$$$$$$$$$$ updating mapping table");
969 5350 berkley
        int serialNumber = -1;
970
        DBConnection dbConn = null;
971
        try {
972
            // Parse the localId into scope and rev parts
973
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
974
            String docid = acc.getDocid();
975
            int rev = 1;
976
            if(acc.getRev() != null)
977
            {
978
              rev = (new Integer(acc.getRev()).intValue());
979
            }
980
981
            // Get a database connection from the pool
982
            dbConn =
983 6079 leinfelder
                DBConnectionPool.getDBConnection("IdentifierManager.updateMapping");
984 5350 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
985
986 6099 leinfelder
            // Execute the update statement
987 6595 leinfelder
            String query = "update " + TYPE_IDENTIFIER + " set (docid, rev) = (?, ?) where guid = ?";
988 5350 berkley
            PreparedStatement stmt = dbConn.prepareStatement(query);
989
            stmt.setString(1, docid);
990
            stmt.setInt(2, rev);
991 6595 leinfelder
            stmt.setString(3, guid);
992 5350 berkley
            int rows = stmt.executeUpdate();
993
994
            stmt.close();
995
        } catch (SQLException e) {
996
            e.printStackTrace();
997 6079 leinfelder
            logMetacat.error("SQL error while updating a mapping identifier: "
998 5350 berkley
                    + e.getMessage());
999
        } catch (NumberFormatException e) {
1000
            e.printStackTrace();
1001 6079 leinfelder
            logMetacat.error("NumberFormat error while updating a mapping identifier: "
1002 5350 berkley
                    + e.getMessage());
1003
        } catch (AccessionNumberException e) {
1004
            e.printStackTrace();
1005 6079 leinfelder
            logMetacat.error("AccessionNumber error while updating a mapping identifier: "
1006 5350 berkley
                    + e.getMessage());
1007
        } finally {
1008
            // Return database connection to the pool
1009
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1010
        }
1011 6099 leinfelder
        logMetacat.debug("done updating mapping");
1012 5350 berkley
    }
1013 6099 leinfelder
1014
    private void updateSystemMetadataFields(long dateUploaded, String rightsHolder,
1015 6892 cjones
        String checksum, String checksumAlgorithm, String originMemberNode,
1016
        String authoritativeMemberNode, long modifiedDate, String submitter,
1017
        String guid, String objectFormat, BigInteger size, boolean archived,
1018
        boolean replicationAllowed, int numberReplicas, String obsoletes,
1019
        String obsoletedBy, BigInteger serialVersion) throws SQLException  {
1020
1021 5887 berkley
        DBConnection dbConn = null;
1022
        int serialNumber = -1;
1023 5957 berkley
1024 5887 berkley
        try {
1025
            // Get a database connection from the pool
1026
            dbConn =
1027
                DBConnectionPool.getDBConnection("IdentifierManager.createMapping");
1028
            serialNumber = dbConn.getCheckOutSerialNumber();
1029
1030
            // Execute the insert statement
1031
            String query = "update " + TYPE_SYSTEM_METADATA +
1032
                " set (date_uploaded, rights_holder, checksum, checksum_algorithm, " +
1033 5917 berkley
                "origin_member_node, authoritive_member_node, date_modified, " +
1034 6766 leinfelder
                "submitter, object_format, size, archived, replication_allowed, number_replicas, " +
1035 6561 leinfelder
                "obsoletes, obsoleted_by, serial_version) " +
1036 6766 leinfelder
                "= (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) where guid = ?";
1037 5887 berkley
            PreparedStatement stmt = dbConn.prepareStatement(query);
1038
1039
            //data values
1040
            stmt.setTimestamp(1, new java.sql.Timestamp(dateUploaded));
1041
            stmt.setString(2, rightsHolder);
1042
            stmt.setString(3, checksum);
1043
            stmt.setString(4, checksumAlgorithm);
1044
            stmt.setString(5, originMemberNode);
1045
            stmt.setString(6, authoritativeMemberNode);
1046
            stmt.setTimestamp(7, new java.sql.Timestamp(modifiedDate));
1047
            stmt.setString(8, submitter);
1048 5917 berkley
            stmt.setString(9, objectFormat);
1049 6384 cjones
            stmt.setString(10, size.toString());
1050 6766 leinfelder
            stmt.setBoolean(11, archived);
1051
            stmt.setBoolean(12, replicationAllowed);
1052
            stmt.setInt(13, numberReplicas);
1053
            stmt.setString(14, obsoletes);
1054
            stmt.setString(15, obsoletedBy);
1055
            stmt.setString(16, serialVersion.toString());
1056 6375 leinfelder
1057 5887 berkley
            //where clause
1058 6766 leinfelder
            stmt.setString(17, guid);
1059 6099 leinfelder
            logMetacat.debug("stmt: " + stmt.toString());
1060 5887 berkley
            //execute
1061
            int rows = stmt.executeUpdate();
1062
1063
            stmt.close();
1064 6892 cjones
1065 5887 berkley
        } catch (SQLException e) {
1066 6766 leinfelder
            logMetacat.error("updateSystemMetadataFields: SQL error while updating system metadata: "
1067 5887 berkley
                    + e.getMessage());
1068 6892 cjones
            throw e;
1069
1070 5887 berkley
        } finally {
1071
            // Return database connection to the pool
1072
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1073
        }
1074
    }
1075
1076 6107 leinfelder
    private void insertReplicationPolicy(String guid, String policy, List<String> memberNodes)
1077
    {
1078
        DBConnection dbConn = null;
1079
        int serialNumber = -1;
1080
1081
        try {
1082
            // Get a database connection from the pool
1083
            dbConn =
1084
                DBConnectionPool.getDBConnection("IdentifierManager.insertReplicationPolicy");
1085
            serialNumber = dbConn.getCheckOutSerialNumber();
1086
1087
            // remove existing values first
1088
            String delete = "delete from systemMetadataReplicationPolicy " +
1089
            "where guid = ? and policy = ?";
1090
	        PreparedStatement stmt = dbConn.prepareStatement(delete);
1091
	        //data values
1092
	        stmt.setString(1, guid);
1093
	        stmt.setString(2, policy);
1094
	        //execute
1095
	        int deletedCount = stmt.executeUpdate();
1096
	        stmt.close();
1097
1098
            for (String memberNode: memberNodes) {
1099
	            // Execute the insert statement
1100
	            String insert = "insert into systemMetadataReplicationPolicy " +
1101
	                "(guid, policy, member_node) " +
1102
	                "values (?, ?, ?)";
1103
	            PreparedStatement insertStatement = dbConn.prepareStatement(insert);
1104
1105
	            //data values
1106
	            insertStatement.setString(1, guid);
1107
	            insertStatement.setString(2, policy);
1108
	            insertStatement.setString(3, memberNode);
1109 7102 leinfelder
1110
	            logMetacat.debug("systemMetadataReplicationPolicy sql: " + insertStatement.toString());
1111
1112 6107 leinfelder
	            //execute
1113
	            int rows = insertStatement.executeUpdate();
1114
	            insertStatement.close();
1115
            }
1116
        } catch (SQLException e) {
1117
            logMetacat.error("SQL error while adding systemMetadataReplicationPolicy for: " + guid, e);
1118
        } finally {
1119
            // Return database connection to the pool
1120
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1121
        }
1122
    }
1123
1124
    private void insertReplicationStatus(String guid, List<Replica> replicas) {
1125
        DBConnection dbConn = null;
1126
        int serialNumber = -1;
1127
1128
        try {
1129
            // Get a database connection from the pool
1130
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.insertReplicas");
1131
            serialNumber = dbConn.getCheckOutSerialNumber();
1132
1133
            // remove existing values first
1134
            String delete = "delete from systemMetadataReplicationStatus " +
1135
            "where guid = ?";
1136
	        PreparedStatement stmt = dbConn.prepareStatement(delete);
1137
	        //data values
1138
	        stmt.setString(1, guid);
1139
	        //execute
1140
	        int deletedCount = stmt.executeUpdate();
1141
	        stmt.close();
1142
1143 6443 leinfelder
	        if (replicas != null) {
1144
	            for (Replica replica: replicas) {
1145
		            // Execute the insert statement
1146
		            String insert = "insert into systemMetadataReplicationStatus " +
1147
		                "(guid, member_node, status, date_verified) " +
1148
		                "values (?, ?, ?, ?)";
1149
		            PreparedStatement insertStatement = dbConn.prepareStatement(insert);
1150
1151
		            //data values
1152
		            String memberNode = replica.getReplicaMemberNode().getValue();
1153
		            String status = replica.getReplicationStatus().toString();
1154
		            java.sql.Date sqlDate = new java.sql.Date(replica.getReplicaVerified().getTime());
1155
		            insertStatement.setString(1, guid);
1156
		            insertStatement.setString(2, memberNode);
1157
		            insertStatement.setString(3, status);
1158
		            insertStatement.setDate(4, sqlDate);
1159
1160 7102 leinfelder
		            logMetacat.debug("systemMetadataReplicationStatus sql: " + insertStatement.toString());
1161
1162 6443 leinfelder
		            //execute
1163
		            int rows = insertStatement.executeUpdate();
1164
		            insertStatement.close();
1165
	            }
1166
	        }
1167 6107 leinfelder
        } catch (SQLException e) {
1168
            logMetacat.error("SQL error while adding systemMetadataReplicationStatus for: " + guid, e);
1169
        } finally {
1170
            // Return database connection to the pool
1171
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1172
        }
1173
    }
1174
1175 5334 berkley
    /**
1176 5887 berkley
     * Insert the system metadata fields into the db
1177
     * @param sm
1178 6108 leinfelder
     * @throws McdbDocNotFoundException
1179 6892 cjones
     * @throws SQLException
1180 6904 cjones
     * @throws InvalidSystemMetadata
1181 5887 berkley
     */
1182 6892 cjones
    public void updateSystemMetadata(SystemMetadata sm)
1183 6904 cjones
      throws McdbDocNotFoundException, SQLException, InvalidSystemMetadata {
1184 6107 leinfelder
1185 6892 cjones
      Boolean replicationAllowed = false;
1186
		  Integer numberReplicas = -1;
1187 6107 leinfelder
    	ReplicationPolicy replicationPolicy = sm.getReplicationPolicy();
1188
    	if (replicationPolicy != null) {
1189
    		replicationAllowed = replicationPolicy.getReplicationAllowed();
1190
    		numberReplicas = replicationPolicy.getNumberReplicas();
1191
    		replicationAllowed = replicationAllowed == null ? false: replicationAllowed;
1192
    		numberReplicas = numberReplicas == null ? -1: numberReplicas;
1193
    	}
1194 6904 cjones
1195 6107 leinfelder
    	// the main systemMetadata fields
1196 6892 cjones
		  updateSystemMetadataFields(
1197 6311 leinfelder
				sm.getDateUploaded() == null ? null: sm.getDateUploaded().getTime(),
1198
				sm.getRightsHolder() == null ? null: sm.getRightsHolder().getValue(),
1199
				sm.getChecksum() == null ? null: sm.getChecksum().getValue(),
1200 6397 leinfelder
				sm.getChecksum() == null ? null: sm.getChecksum().getAlgorithm(),
1201 6311 leinfelder
				sm.getOriginMemberNode() == null ? null: sm.getOriginMemberNode().getValue(),
1202
				sm.getAuthoritativeMemberNode() == null ? null: sm.getAuthoritativeMemberNode().getValue(),
1203
				sm.getDateSysMetadataModified() == null ? null: sm.getDateSysMetadataModified().getTime(),
1204
				sm.getSubmitter() == null ? null: sm.getSubmitter().getValue(),
1205 6904 cjones
		    sm.getIdentifier().getValue(),
1206
		    sm.getFormatId() == null ? null: sm.getFormatId().getValue(),
1207
		    sm.getSize(),
1208
		    sm.getArchived() == null ? false: sm.getArchived(),
1209
		    replicationAllowed,
1210
		    numberReplicas,
1211
		    sm.getObsoletes() == null ? null:sm.getObsoletes().getValue(),
1212
		    sm.getObsoletedBy() == null ? null: sm.getObsoletedBy().getValue(),
1213 7021 leinfelder
		    sm.getSerialVersion()
1214 6561 leinfelder
        );
1215 6097 leinfelder
1216
        String guid = sm.getIdentifier().getValue();
1217
1218 6107 leinfelder
        // save replication policies
1219
        if (replicationPolicy != null) {
1220
		    List<String> nodes = null;
1221
		    String policy = null;
1222
1223 6494 leinfelder
		    // check for null
1224
		    if (replicationPolicy.getBlockedMemberNodeList() != null) {
1225
			    nodes = new ArrayList<String>();
1226
			    policy = "blocked";
1227
			    for (NodeReference node: replicationPolicy.getBlockedMemberNodeList()) {
1228
			    	nodes.add(node.getValue());
1229
			    }
1230
			    this.insertReplicationPolicy(guid, policy, nodes);
1231 6107 leinfelder
		    }
1232
1233 6494 leinfelder
		    if (replicationPolicy.getPreferredMemberNodeList() != null) {
1234
			    nodes = new ArrayList<String>();
1235
			    policy = "preferred";
1236
			    for (NodeReference node: replicationPolicy.getPreferredMemberNodeList()) {
1237
			    	nodes.add(node.getValue());
1238
			    }
1239
		        this.insertReplicationPolicy(guid, policy, nodes);
1240 6107 leinfelder
		    }
1241
        }
1242 6097 leinfelder
1243 6107 leinfelder
        // save replica information
1244
        this.insertReplicationStatus(guid, sm.getReplicaList());
1245
1246 6108 leinfelder
        // save access policy
1247
        AccessPolicy accessPolicy = sm.getAccessPolicy();
1248
        if (accessPolicy != null) {
1249
        	try {
1250
				this.insertAccessPolicy(guid, accessPolicy);
1251
			} catch (AccessException e) {
1252
				throw new McdbDocNotFoundException(e);
1253
			}
1254
        }
1255 5887 berkley
    }
1256
1257
    /**
1258 6108 leinfelder
     * Creates Metacat access rules and inserts them
1259
     * @param accessPolicy
1260
     * @throws McdbDocNotFoundException
1261
     * @throws AccessException
1262
     */
1263
    private void insertAccessPolicy(String guid, AccessPolicy accessPolicy) throws McdbDocNotFoundException, AccessException {
1264
1265 6744 leinfelder
    	// check for the existing permOrder so that we remain compatible with it (DataONE does not care)
1266
        XMLAccessAccess accessController  = new XMLAccessAccess();
1267
		String existingPermOrder = AccessControlInterface.ALLOWFIRST;
1268
        Vector<XMLAccessDAO> existingAccess = accessController.getXMLAccessForDoc(guid);
1269
        if (existingAccess != null && existingAccess.size() > 0) {
1270
        	existingPermOrder = existingAccess.get(0).getPermOrder();
1271
        }
1272
1273 6108 leinfelder
    	List<XMLAccessDAO> accessDAOs = new ArrayList<XMLAccessDAO>();
1274
        for (AccessRule accessRule: accessPolicy.getAllowList()) {
1275
        	List<Subject> subjects = accessRule.getSubjectList();
1276
        	List<Permission> permissions = accessRule.getPermissionList();
1277
        	for (Subject subject: subjects) {
1278 6122 leinfelder
    			XMLAccessDAO accessDAO = new XMLAccessDAO();
1279
        		accessDAO.setPrincipalName(subject.getValue());
1280
    			accessDAO.setGuid(guid);
1281
    			accessDAO.setPermType(AccessControlInterface.ALLOW);
1282 6744 leinfelder
				accessDAO.setPermOrder(existingPermOrder);
1283
    			if (permissions != null) {
1284
	    			for (Permission permission: permissions) {
1285
	    				Long metacatPermission = new Long(convertPermission(permission));
1286
	        			accessDAO.addPermission(metacatPermission);
1287
	    			}
1288 6122 leinfelder
    			}
1289
    			accessDAOs.add(accessDAO);
1290 6108 leinfelder
        	}
1291
        }
1292
1293
1294 6744 leinfelder
        // remove all existing allow records
1295
        accessController.deleteXMLAccessForDoc(guid, AccessControlInterface.ALLOW);
1296
        // add the ones we can for this guid
1297
        accessController.insertAccess(guid, accessDAOs);
1298 6108 leinfelder
1299 6744 leinfelder
1300 6108 leinfelder
    }
1301
1302
    /**
1303
     * Lookup access policy from Metacat
1304
     * @param guid
1305
     * @return
1306
     * @throws McdbDocNotFoundException
1307
     * @throws AccessException
1308
     */
1309 6720 leinfelder
    public AccessPolicy getAccessPolicy(String guid) throws McdbDocNotFoundException, AccessException {
1310 6450 leinfelder
        AccessPolicy accessPolicy = new AccessPolicy();
1311
1312 6122 leinfelder
    	// use GUID to look up the access
1313 6744 leinfelder
        XMLAccessAccess accessController  = new XMLAccessAccess();
1314 6720 leinfelder
        List<XMLAccessDAO> accessDAOs = accessController.getXMLAccessForDoc(guid);
1315
1316 6108 leinfelder
        for (XMLAccessDAO accessDAO: accessDAOs) {
1317 6744 leinfelder
        	// only add allow rule
1318
        	if (accessDAO.getPermType().equals(AccessControlInterface.ALLOW)) {
1319
	        	AccessRule accessRule = new AccessRule();
1320
	        	List <Permission> permissions = convertPermission(accessDAO.getPermission().intValue());
1321 7088 leinfelder
	        	// cannot include if we have no permissions
1322
	        	if (permissions == null || permissions.isEmpty()) {
1323
	        		logMetacat.warn("skipping empty access rule permissions for " + guid);
1324
	        		continue;
1325
	        	}
1326 6744 leinfelder
	        	accessRule.setPermissionList(permissions);
1327
	        	Subject subject = new Subject();
1328
	        	subject.setValue(accessDAO.getPrincipalName());
1329
	        	accessRule.addSubject(subject);
1330
	            accessPolicy.addAllow(accessRule);
1331
        	}
1332 6108 leinfelder
        }
1333
        return accessPolicy;
1334
    }
1335
1336
    public int convertPermission(Permission permission) {
1337
    	if (permission.equals(Permission.READ)) {
1338
    		return AccessControlInterface.READ;
1339
    	}
1340
    	if (permission.equals(Permission.WRITE)) {
1341
    		return AccessControlInterface.WRITE;
1342
    	}
1343
    	if (permission.equals(Permission.CHANGE_PERMISSION)) {
1344
    		return AccessControlInterface.CHMOD;
1345
    	}
1346
		return -1;
1347
    }
1348
1349 6722 leinfelder
    public List<Permission> convertPermission(int permission) {
1350 6744 leinfelder
1351 6722 leinfelder
    	List<Permission> permissions = new ArrayList<Permission>();
1352 6744 leinfelder
    	if (permission == AccessControlInterface.ALL) {
1353 6722 leinfelder
    		permissions.add(Permission.READ);
1354
    		permissions.add(Permission.WRITE);
1355 6744 leinfelder
    		permissions.add(Permission.CHANGE_PERMISSION);
1356 6722 leinfelder
    		return permissions;
1357 6108 leinfelder
    	}
1358 6744 leinfelder
1359
    	if ((permission & AccessControlInterface.CHMOD) == AccessControlInterface.CHMOD) {
1360 6722 leinfelder
    		permissions.add(Permission.CHANGE_PERMISSION);
1361 6108 leinfelder
    	}
1362 6744 leinfelder
    	if ((permission & AccessControlInterface.READ) == AccessControlInterface.READ) {
1363 6722 leinfelder
    		permissions.add(Permission.READ);
1364 6744 leinfelder
    	}
1365
    	if ((permission & AccessControlInterface.WRITE) == AccessControlInterface.WRITE) {
1366 6722 leinfelder
    		permissions.add(Permission.WRITE);
1367 6720 leinfelder
    	}
1368 6744 leinfelder
1369
		return permissions;
1370 6108 leinfelder
    }
1371
1372
    /**
1373 6099 leinfelder
     * Lookup a localId given the GUID. If
1374
     * the identifier is not found, throw an exception.
1375
     *
1376
     * @param guid the global identifier to look up
1377
     * @return String containing the corresponding LocalId
1378
     * @throws McdbDocNotFoundException if the identifier is not found
1379 5334 berkley
     */
1380 6099 leinfelder
    public String getLocalId(String guid) throws McdbDocNotFoundException {
1381 5334 berkley
1382
      String db_guid = "";
1383
      String docid = "";
1384
      int rev = 0;
1385
1386 6099 leinfelder
      String query = "select guid, docid, rev from " + TYPE_IDENTIFIER + " where guid = ?";
1387 5334 berkley
1388
      DBConnection dbConn = null;
1389 5333 berkley
      int serialNumber = -1;
1390 5334 berkley
      try {
1391
          // Get a database connection from the pool
1392
          dbConn = DBConnectionPool.getDBConnection("Identifier.getLocalId");
1393
          serialNumber = dbConn.getCheckOutSerialNumber();
1394
1395
          // Execute the insert statement
1396
          PreparedStatement stmt = dbConn.prepareStatement(query);
1397
          stmt.setString(1, guid);
1398
          ResultSet rs = stmt.executeQuery();
1399
          if (rs.next()) {
1400
              db_guid = rs.getString(1);
1401
              docid = rs.getString(2);
1402
              rev = rs.getInt(3);
1403
              assert(db_guid.equals(guid));
1404
          } else {
1405
              throw new McdbDocNotFoundException("Document not found:" + guid);
1406
          }
1407
          stmt.close();
1408
      } catch (SQLException e) {
1409
          logMetacat.error("Error while looking up the local identifier: "
1410
                  + e.getMessage());
1411
      } finally {
1412
          // Return database connection to the pool
1413
          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1414
      }
1415
      return docid + "." + rev;
1416
    }
1417
1418 5377 berkley
    /**
1419 5895 berkley
     * query the systemmetadata table based on the given parameters
1420
     * @param startTime
1421
     * @param endTime
1422
     * @param objectFormat
1423
     * @param replicaStatus
1424
     * @param start
1425
     * @param count
1426
     * @return ObjectList
1427 6299 leinfelder
     * @throws SQLException
1428
     * @throws ServiceException
1429
     * @throws PropertyNotFoundException
1430 5895 berkley
     */
1431 6836 cjones
    public ObjectList querySystemMetadata(Date startTime, Date endTime,
1432
        ObjectFormatIdentifier objectFormatId, boolean replicaStatus,
1433
        int start, int count)
1434
        throws SQLException, PropertyNotFoundException, ServiceException {
1435 5895 berkley
        ObjectList ol = new ObjectList();
1436
        int total = 0;
1437 5943 berkley
        DBConnection dbConn = null;
1438
        int serialNumber = -1;
1439 6836 cjones
1440 6299 leinfelder
        try {
1441 6836 cjones
            String sql = "select guid, date_uploaded, rights_holder, checksum, "
1442
                    + "checksum_algorithm, origin_member_node, authoritive_member_node, "
1443
                    + "date_modified, submitter, object_format, size from systemmetadata";
1444
1445 5895 berkley
            boolean f1 = false;
1446
            boolean f2 = false;
1447
            boolean f3 = false;
1448 6836 cjones
1449 6299 leinfelder
            if (startTime != null) {
1450 6798 cjones
                sql += " where systemmetadata.date_modified >= ?";
1451 5895 berkley
                f1 = true;
1452
            }
1453 6836 cjones
1454 6299 leinfelder
            if (endTime != null) {
1455
                if (!f1) {
1456 5917 berkley
                    sql += " where systemmetadata.date_modified < ?";
1457 6836 cjones
                } else {
1458 5917 berkley
                    sql += " and systemmetadata.date_modified < ?";
1459
                }
1460 5895 berkley
                f2 = true;
1461
            }
1462 6836 cjones
1463 6337 leinfelder
            if (objectFormatId != null) {
1464 6299 leinfelder
                if (!f1 && !f2) {
1465 5917 berkley
                    sql += " where object_format = ?";
1466 6836 cjones
                } else {
1467 5917 berkley
                    sql += " and object_format = ?";
1468
                }
1469 5895 berkley
                f3 = true;
1470
            }
1471 6836 cjones
1472 6299 leinfelder
            if (replicaStatus) {
1473 7030 cjones
                String currentNodeId = PropertyService.getInstance().getProperty("dataone.nodeId");
1474 6299 leinfelder
                if (!f1 && !f2 && !f3) {
1475 6836 cjones
                    sql += " where authoritive_member_node != '" +
1476
                        currentNodeId.trim() + "'";
1477
                } else {
1478
                    sql += " and authoritive_member_node != '" +
1479
                        currentNodeId.trim() + "'";
1480 5917 berkley
                }
1481 5895 berkley
            }
1482 6836 cjones
1483 5943 berkley
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.querySystemMetadata");
1484
            serialNumber = dbConn.getCheckOutSerialNumber();
1485 5895 berkley
            PreparedStatement stmt = dbConn.prepareStatement(sql);
1486 6836 cjones
1487 6299 leinfelder
            if (f1 && f2 && f3) {
1488 5895 berkley
                stmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1489
                stmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1490 6337 leinfelder
                stmt.setString(3, objectFormatId.getValue());
1491 6836 cjones
            } else if (f1 && f2 && !f3) {
1492 5895 berkley
                stmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1493
                stmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1494 6836 cjones
            } else if (f1 && !f2 && f3) {
1495 5895 berkley
                stmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1496 6337 leinfelder
                stmt.setString(2, objectFormatId.getValue());
1497 6836 cjones
            } else if (f1 && !f2 && !f3) {
1498 5895 berkley
                stmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1499 6836 cjones
            } else if (!f1 && f2 && f3) {
1500 5895 berkley
                stmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1501 6337 leinfelder
                stmt.setString(2, objectFormatId.getValue());
1502 6836 cjones
            } else if (!f1 && !f2 && f3) {
1503 6337 leinfelder
                stmt.setString(1, objectFormatId.getValue());
1504 6836 cjones
            } else if (!f1 && f2 && !f3) {
1505 5895 berkley
                stmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1506
            }
1507 6836 cjones
1508
            // logMetacat.debug("LISTOBJECTS QUERY: " + stmt.toString());
1509
1510 5895 berkley
            ResultSet rs = stmt.executeQuery();
1511 6836 cjones
            for (int i = 0; i < start; i++) {
1512 6299 leinfelder
                if (rs.next()) {
1513 5917 berkley
                    total++;
1514 6299 leinfelder
                } else {
1515 5917 berkley
                    break;
1516
                }
1517 5895 berkley
            }
1518 6836 cjones
1519 5895 berkley
            int countIndex = 0;
1520 6836 cjones
1521
            while (rs.next()) {
1522 5895 berkley
                total++;
1523 6299 leinfelder
                if (countIndex >= count) {
1524 6836 cjones
                    // allow unlimited (negative number for count)
1525
                    if (count > 0) {
1526
                        break;
1527
                    }
1528 5895 berkley
                }
1529 6836 cjones
1530 5895 berkley
                String guid = rs.getString(1);
1531 6836 cjones
                // logMetacat.debug("query found doc with guid " + guid);
1532
                // Timestamp dateUploaded = rs.getTimestamp(2);
1533
                // String rightsHolder = rs.getString(3);
1534 6318 cjones
                String checksum = rs.getString(4);
1535
                String checksumAlgorithm = rs.getString(5);
1536 6836 cjones
                // String originMemberNode = rs.getString(6);
1537
                // String authoritiveMemberNode = rs.getString(7);
1538 6318 cjones
                Timestamp dateModified = rs.getTimestamp(8);
1539 6836 cjones
                // String submitter = rs.getString(9);
1540 6318 cjones
                String fmtidStr = rs.getString(10);
1541
                String sz = rs.getString(11);
1542 6384 cjones
                BigInteger size = new BigInteger("0");
1543 6836 cjones
1544 6299 leinfelder
                if (sz != null && !sz.trim().equals("")) {
1545 6384 cjones
                    size = new BigInteger(rs.getString(11));
1546 5917 berkley
                }
1547 6836 cjones
1548 5895 berkley
                ObjectInfo oi = new ObjectInfo();
1549 6836 cjones
1550 5895 berkley
                Identifier id = new Identifier();
1551
                id.setValue(guid);
1552
                oi.setIdentifier(id);
1553 6836 cjones
1554 6299 leinfelder
                if (dateModified != null) {
1555 7056 leinfelder
                    oi.setDateSysMetadataModified(dateModified);
1556 6299 leinfelder
                }
1557 6836 cjones
1558 5895 berkley
                Checksum cs = new Checksum();
1559
                cs.setValue(checksum);
1560 6299 leinfelder
                try {
1561 6836 cjones
                    // cs.setAlgorithm(ChecksumAlgorithm.valueOf(checksumAlgorithm));
1562 6397 leinfelder
                    cs.setAlgorithm(checksumAlgorithm);
1563 6299 leinfelder
                } catch (Exception e) {
1564 6836 cjones
                    logMetacat.error("could not parse checksum algorithm", e);
1565
                    continue;
1566
                }
1567 5895 berkley
                oi.setChecksum(cs);
1568 6836 cjones
1569 6519 leinfelder
                // set the format type
1570
                ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
1571 6836 cjones
                fmtid.setValue(fmtidStr);
1572 6561 leinfelder
                oi.setFormatId(fmtid);
1573 6836 cjones
1574 5917 berkley
                oi.setSize(size);
1575 6836 cjones
1576 6837 cjones
                // when requested count == 0, return an empty object list
1577
                if (count != 0) {
1578
                    ol.addObjectInfo(oi);
1579
                }
1580 5895 berkley
                countIndex++;
1581
            }
1582 6836 cjones
1583 6299 leinfelder
            // expend the resultset to get the total count of possible rows
1584 6836 cjones
            while (rs.next()) {
1585 5895 berkley
                total++;
1586
            }
1587
        }
1588 6836 cjones
1589 6299 leinfelder
        finally {
1590 5943 berkley
            // Return database connection to the pool
1591
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1592
        }
1593 6836 cjones
1594 5895 berkley
        ol.setStart(start);
1595 5922 berkley
        ol.setCount(ol.sizeObjectInfoList());
1596 5895 berkley
        ol.setTotal(total);
1597 6836 cjones
1598 5895 berkley
        return ol;
1599
    }
1600
1601
    /**
1602 6099 leinfelder
     * create a mapping in the identifier table
1603 5377 berkley
     * @param guid
1604
     * @param localId
1605
     */
1606 6099 leinfelder
    public void createMapping(String guid, String localId)
1607 5453 berkley
    {
1608 5334 berkley
1609
        int serialNumber = -1;
1610 5333 berkley
        DBConnection dbConn = null;
1611
        try {
1612
1613
            // Parse the localId into scope and rev parts
1614
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
1615
            String docid = acc.getDocid();
1616 5344 berkley
            int rev = 1;
1617 6099 leinfelder
            if (acc.getRev() != null) {
1618 5344 berkley
              rev = (new Integer(acc.getRev()).intValue());
1619
            }
1620 5333 berkley
1621
            // Get a database connection from the pool
1622 6099 leinfelder
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.createMapping");
1623 5333 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
1624
1625
            // Execute the insert statement
1626 6099 leinfelder
            String query = "insert into " + TYPE_IDENTIFIER + " (guid, docid, rev) values (?, ?, ?)";
1627 5333 berkley
            PreparedStatement stmt = dbConn.prepareStatement(query);
1628
            stmt.setString(1, guid);
1629
            stmt.setString(2, docid);
1630
            stmt.setInt(3, rev);
1631 6099 leinfelder
            logMetacat.debug("mapping query: " + stmt.toString());
1632 5333 berkley
            int rows = stmt.executeUpdate();
1633
1634
            stmt.close();
1635
        } catch (SQLException e) {
1636 5344 berkley
            e.printStackTrace();
1637 6099 leinfelder
            logMetacat.error("createGenericMapping: SQL error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1638 5333 berkley
                    + e.getMessage());
1639
        } catch (NumberFormatException e) {
1640 5344 berkley
            e.printStackTrace();
1641 6099 leinfelder
            logMetacat.error("createGenericMapping: NumberFormat error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1642 5333 berkley
                    + e.getMessage());
1643
        } catch (AccessionNumberException e) {
1644 5344 berkley
            e.printStackTrace();
1645 6099 leinfelder
            logMetacat.error("createGenericMapping: AccessionNumber error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1646 5333 berkley
                    + e.getMessage());
1647
        } finally {
1648
            // Return database connection to the pool
1649
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1650
        }
1651
    }
1652 6099 leinfelder
1653
    /**
1654 7017 leinfelder
     * remove a mapping in the identifier table
1655
     * @param guid
1656
     * @param localId
1657
     */
1658
    public void removeMapping(String guid, String localId)
1659
    {
1660
1661
        int serialNumber = -1;
1662
        DBConnection dbConn = null;
1663
        try {
1664
1665
            // Parse the localId into scope and rev parts
1666
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
1667
            String docid = acc.getDocid();
1668
            int rev = 1;
1669
            if (acc.getRev() != null) {
1670
              rev = (new Integer(acc.getRev()).intValue());
1671
            }
1672
1673
            // Get a database connection from the pool
1674
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.removeMapping");
1675
            serialNumber = dbConn.getCheckOutSerialNumber();
1676
1677
            // Execute the insert statement
1678
            String query = "DELETE FROM " + TYPE_IDENTIFIER + " WHERE guid = ? AND docid = ? AND rev = ?";
1679
            PreparedStatement stmt = dbConn.prepareStatement(query);
1680
            stmt.setString(1, guid);
1681
            stmt.setString(2, docid);
1682
            stmt.setInt(3, rev);
1683
            logMetacat.debug("remove mapping query: " + stmt.toString());
1684
            int rows = stmt.executeUpdate();
1685
1686
            stmt.close();
1687
        } catch (SQLException e) {
1688
            e.printStackTrace();
1689
            logMetacat.error("removeMapping: SQL error while removing a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1690
                    + e.getMessage());
1691
        } catch (NumberFormatException e) {
1692
            e.printStackTrace();
1693
            logMetacat.error("removeMapping: NumberFormat error while removing a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1694
                    + e.getMessage());
1695
        } catch (AccessionNumberException e) {
1696
            e.printStackTrace();
1697
            logMetacat.error("removeMapping: AccessionNumber error while removing a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1698
                    + e.getMessage());
1699
        } finally {
1700
            // Return database connection to the pool
1701
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1702
        }
1703
    }
1704
1705
    /**
1706 6099 leinfelder
     * create the systemmetadata record
1707
     * @param guid
1708
     */
1709 6337 leinfelder
    private void insertSystemMetadata(String guid)
1710 6099 leinfelder
    {
1711
1712
        int serialNumber = -1;
1713
        DBConnection dbConn = null;
1714
        try {
1715
1716
            // Get a database connection from the pool
1717
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.insertSystemMetadata");
1718
            serialNumber = dbConn.getCheckOutSerialNumber();
1719
1720
            // Execute the insert statement
1721 6337 leinfelder
            String query = "insert into " + TYPE_SYSTEM_METADATA + " (guid) values (?)";
1722 6099 leinfelder
            PreparedStatement stmt = dbConn.prepareStatement(query);
1723
            stmt.setString(1, guid);
1724
            logMetacat.debug("system metadata query: " + stmt.toString());
1725
            int rows = stmt.executeUpdate();
1726
1727
            stmt.close();
1728
        } catch (Exception e) {
1729
            e.printStackTrace();
1730 6277 leinfelder
            logMetacat.error("Error while creating " + TYPE_SYSTEM_METADATA + " record: " + guid, e );
1731 6099 leinfelder
        } finally {
1732
            // Return database connection to the pool
1733
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1734
        }
1735
    }
1736 6277 leinfelder
1737 6648 leinfelder
    public void deleteSystemMetadata(String guid)
1738 6277 leinfelder
    {
1739
1740
        int serialNumber = -1;
1741
        DBConnection dbConn = null;
1742 6648 leinfelder
        String query = null;
1743
        PreparedStatement stmt = null;
1744
        int rows = 0;
1745 6277 leinfelder
        try {
1746
1747
            // Get a database connection from the pool
1748 6648 leinfelder
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.deleteSystemMetadata");
1749 6277 leinfelder
            serialNumber = dbConn.getCheckOutSerialNumber();
1750
1751 6648 leinfelder
            // remove main system metadata entry
1752
            query = "delete from " + TYPE_SYSTEM_METADATA + " where guid = ? ";
1753
            stmt = dbConn.prepareStatement(query);
1754 6277 leinfelder
            stmt.setString(1, guid);
1755
            logMetacat.debug("delete system metadata: " + stmt.toString());
1756 6648 leinfelder
            rows = stmt.executeUpdate();
1757 6277 leinfelder
            stmt.close();
1758 6648 leinfelder
1759
            // remove the systemMetadataReplicationPolicy
1760
            query = "delete from systemMetadataReplicationPolicy " +
1761
            "where guid = ?";
1762
            stmt = dbConn.prepareStatement(query);
1763
            stmt.setString(1, guid);
1764
            logMetacat.debug("delete systemMetadataReplicationPolicy: " + stmt.toString());
1765
            rows = stmt.executeUpdate();
1766
            stmt.close();
1767
1768
            // remove the systemMetadataReplicationStatus
1769
            query = "delete from systemMetadataReplicationStatus " +
1770
            "where guid = ?";
1771
            stmt = dbConn.prepareStatement(query);
1772
            stmt.setString(1, guid);
1773
            logMetacat.debug("delete systemMetadataReplicationStatus: " + stmt.toString());
1774
            rows = stmt.executeUpdate();
1775
            stmt.close();
1776
1777 6744 leinfelder
            // TODO: remove the access?
1778 6648 leinfelder
            // Metacat keeps "deleted" documents so we should not remove access rules.
1779
1780 6277 leinfelder
        } catch (Exception e) {
1781
            e.printStackTrace();
1782
            logMetacat.error("Error while deleting " + TYPE_SYSTEM_METADATA + " record: " + guid, e );
1783 6648 leinfelder
            try {
1784
				dbConn.rollback();
1785
			} catch (SQLException sqle) {
1786
	            logMetacat.error("Error while rolling back delete for record: " + guid, sqle );
1787
			}
1788 6277 leinfelder
        } finally {
1789
            // Return database connection to the pool
1790
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1791
        }
1792
    }
1793 6862 leinfelder
1794
    public void updateAuthoritativeMemberNodeId(String existingMemberNodeId, String newMemberNodeId)
1795
    {
1796
        DBConnection dbConn = null;
1797
        int serialNumber = -1;
1798
1799
        try {
1800
            // Get a database connection from the pool
1801
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.updateAuthoritativeMemberNodeId");
1802
            serialNumber = dbConn.getCheckOutSerialNumber();
1803
1804
            // Execute the insert statement
1805
            String query = "update " + TYPE_SYSTEM_METADATA +
1806
                " set authoritive_member_node = ? " +
1807
                " where authoritive_member_node = ?";
1808
            PreparedStatement stmt = dbConn.prepareStatement(query);
1809
1810
            //data values
1811
            stmt.setString(1, newMemberNodeId);
1812
            stmt.setString(2, existingMemberNodeId);
1813
1814
            logMetacat.debug("stmt: " + stmt.toString());
1815
            //execute
1816
            int rows = stmt.executeUpdate();
1817
1818
            stmt.close();
1819
        } catch (SQLException e) {
1820
            e.printStackTrace();
1821
            logMetacat.error("updateSystemMetadataFields: SQL error while updating system metadata: "
1822
                    + e.getMessage());
1823
        } catch (NumberFormatException e) {
1824
            e.printStackTrace();
1825
            logMetacat.error("updateSystemMetadataFields: NumberFormat error while updating system metadata: "
1826
                    + e.getMessage());
1827
        } finally {
1828
            // Return database connection to the pool
1829
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1830
        }
1831
    }
1832 5282 jones
}