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