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
import java.sql.PreparedStatement;
28
import java.sql.ResultSet;
29
import java.sql.SQLException;
30 5895 berkley
import java.sql.Timestamp;
31 6107 leinfelder
import java.util.ArrayList;
32
import java.util.Date;
33
import java.util.Hashtable;
34
import java.util.List;
35
import java.util.Vector;
36 5282 jones
37
import org.apache.log4j.Logger;
38 5895 berkley
import org.dataone.service.types.Checksum;
39
import org.dataone.service.types.ChecksumAlgorithm;
40 6107 leinfelder
import org.dataone.service.types.Identifier;
41 6097 leinfelder
import org.dataone.service.types.NodeReference;
42 5895 berkley
import org.dataone.service.types.ObjectFormat;
43
import org.dataone.service.types.ObjectInfo;
44
import org.dataone.service.types.ObjectList;
45 6107 leinfelder
import org.dataone.service.types.Replica;
46
import org.dataone.service.types.ReplicationPolicy;
47
import org.dataone.service.types.ReplicationStatus;
48 6097 leinfelder
import org.dataone.service.types.Subject;
49 5887 berkley
import org.dataone.service.types.SystemMetadata;
50 5282 jones
51
import edu.ucsb.nceas.metacat.database.DBConnection;
52
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
53 5887 berkley
import edu.ucsb.nceas.metacat.properties.PropertyService;
54 5286 jones
import edu.ucsb.nceas.metacat.util.DocumentUtil;
55 5282 jones
56
/**
57
 * Manage the relationship between Metacat local identifiers (LocalIDs) that are
58 6099 leinfelder
 * codified as the (docid, rev) pair with globally unique string identifiers
59 5282 jones
 * (GUIDs) that are opaque strings.  This class provides methods to manage these
60
 * identifiers, and to search for and look up LocalIDs based on their GUID and
61
 * vice versa. IdentifierManager is a singleton.
62
 *
63
 * @author Matthew Jones
64
 */
65
public class IdentifierManager {
66
67 5334 berkley
    public static final String TYPE_SYSTEM_METADATA = "systemmetadata";
68
    public static final String TYPE_IDENTIFIER = "identifier";
69
70 5282 jones
    /**
71
     * The single instance of the manager that is always returned.
72
     */
73
    private static IdentifierManager self = null;
74 6099 leinfelder
    private Logger logMetacat = Logger.getLogger(IdentifierManager.class);
75 5282 jones
76
    /**
77
     * A private constructor that initializes the class when getInstance() is
78
     * called.
79
     */
80 6099 leinfelder
    private IdentifierManager() {}
81 5282 jones
82
    /**
83
     * Return the single instance of the manager after initializing it if it
84
     * wasn't previously initialized.
85
     *
86
     * @return the single IdentifierManager instance
87
     */
88
    public static IdentifierManager getInstance()
89
    {
90
        if (self == null) {
91
            self = new IdentifierManager();
92
        }
93
        return self;
94
    }
95
96 6097 leinfelder
    public SystemMetadata asSystemMetadata(Date dateUploaded, String rightsHolder,
97
            String checksum, String checksumAlgorithm, String originMemberNode,
98
            String authoritativeMemberNode, Date dateModified, String submitter,
99
            String guid, String objectFormat, long size) {
100
        SystemMetadata sysMeta = new SystemMetadata();
101
102
        Identifier sysMetaId = new Identifier();
103
        sysMetaId.setValue(guid);
104
        sysMeta.setIdentifier(sysMetaId);
105
        sysMeta.setDateUploaded(dateUploaded);
106
        Subject rightsHolderSubject = new Subject();
107
        rightsHolderSubject.setValue(rightsHolder);
108
        sysMeta.setRightsHolder(rightsHolderSubject);
109
        Checksum checksumObject = new Checksum();
110
        checksumObject.setValue(checksum);
111
        checksumObject.setAlgorithm(ChecksumAlgorithm.convert(checksumAlgorithm));
112
        sysMeta.setChecksum(checksumObject);
113
        NodeReference omn = new NodeReference();
114
        omn.setValue(originMemberNode);
115
        sysMeta.setOriginMemberNode(omn);
116
        NodeReference amn = new NodeReference();
117
        amn.setValue(authoritativeMemberNode);
118
        sysMeta.setAuthoritativeMemberNode(amn);
119
        sysMeta.setDateSysMetadataModified(dateModified);
120
        Subject submitterSubject = new Subject();
121
        submitterSubject.setValue(submitter);
122
        sysMeta.setSubmitter(submitterSubject);
123
        sysMeta.setObjectFormat(ObjectFormat.convert(objectFormat));
124
        sysMeta.setSize(size);
125
126
        return sysMeta;
127
    }
128
129 5282 jones
    /**
130 5895 berkley
     * return a hash of all of the info that is in the systemmetadata table
131
     * @param localId
132
     * @return
133
     */
134
    public Hashtable<String, String> getSystemMetadataInfo(String localId)
135
    throws McdbDocNotFoundException
136
    {
137
        try
138
        {
139
            AccessionNumber acc = new AccessionNumber(localId, "NONE");
140
            localId = acc.getDocid();
141
        }
142
        catch(Exception e)
143
        {
144
            //do nothing. just try the localId as it is
145
        }
146
        Hashtable<String, String> h = new Hashtable<String, String>();
147
        String sql = "select guid, date_uploaded, rights_holder, checksum, checksum_algorithm, " +
148 5944 berkley
          "origin_member_node, authoritive_member_node, date_modified, submitter, object_format, size " +
149 5895 berkley
          "from systemmetadata where docid = ?";
150
        DBConnection dbConn = null;
151
        int serialNumber = -1;
152
        try
153
        {
154
            // Get a database connection from the pool
155
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getDocumentInfo");
156
            serialNumber = dbConn.getCheckOutSerialNumber();
157
158
            // Execute the insert statement
159
            PreparedStatement stmt = dbConn.prepareStatement(sql);
160
            stmt.setString(1, localId);
161
            ResultSet rs = stmt.executeQuery();
162
            if (rs.next())
163
            {
164
                String guid = rs.getString(1);
165
                Timestamp dateUploaded = rs.getTimestamp(2);
166
                String rightsHolder = rs.getString(3);
167
                String checksum = rs.getString(4);
168
                String checksumAlgorithm = rs.getString(5);
169
                String originMemberNode = rs.getString(6);
170
                String authoritativeMemberNode = rs.getString(7);
171
                Timestamp dateModified = rs.getTimestamp(8);
172
                String submitter = rs.getString(9);
173 5917 berkley
                String objectFormat = rs.getString(10);
174
                long size = new Long(rs.getString(11)).longValue();
175 5895 berkley
176
                h.put("guid", guid);
177
                h.put("date_uploaded", new Long(dateUploaded.getTime()).toString());
178
                h.put("rights_holder", rightsHolder);
179
                h.put("checksum", checksum);
180
                h.put("checksum_algorithm", checksumAlgorithm);
181
                h.put("origin_member_node", originMemberNode);
182
                h.put("authoritative_member_node", authoritativeMemberNode);
183
                h.put("date_modified", new Long(dateModified.getTime()).toString());
184
                h.put("submitter", submitter);
185 5917 berkley
                h.put("object_format", objectFormat);
186
                h.put("size", new Long(size).toString());
187 5895 berkley
188
                stmt.close();
189
            }
190
            else
191
            {
192
                stmt.close();
193
                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
194
                throw new McdbDocNotFoundException("2Could not find document " + localId);
195
            }
196
197
        }
198
        catch (SQLException e)
199
        {
200
            e.printStackTrace();
201
            logMetacat.error("Error while getting system metadata info for localid " + localId + " : "
202
                    + e.getMessage());
203
        }
204
        finally
205
        {
206
            // Return database connection to the pool
207
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
208
        }
209
        return h;
210
    }
211
212
    /**
213 6097 leinfelder
     * return a hash of all of the info that is in the systemmetadata table
214 6099 leinfelder
     * @param guid
215 6097 leinfelder
     * @return
216
     */
217 6099 leinfelder
    public SystemMetadata getSystemMetadata(String guid)
218 6097 leinfelder
    	throws McdbDocNotFoundException
219
    {
220 6099 leinfelder
221 6097 leinfelder
        SystemMetadata sysMeta = new SystemMetadata();
222
        String sql = "select guid, date_uploaded, rights_holder, checksum, checksum_algorithm, " +
223
          "origin_member_node, authoritive_member_node, date_modified, submitter, object_format, size " +
224 6099 leinfelder
          "from systemmetadata where guid = ?";
225 6097 leinfelder
        DBConnection dbConn = null;
226
        int serialNumber = -1;
227
        try
228
        {
229
            // Get a database connection from the pool
230
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getSystemMetadata");
231
            serialNumber = dbConn.getCheckOutSerialNumber();
232
233
            // Execute the statement
234
            PreparedStatement stmt = dbConn.prepareStatement(sql);
235 6099 leinfelder
            stmt.setString(1, guid);
236 6097 leinfelder
            ResultSet rs = stmt.executeQuery();
237
            if (rs.next())
238
            {
239
                Timestamp dateUploaded = rs.getTimestamp(2);
240
                String rightsHolder = rs.getString(3);
241
                String checksum = rs.getString(4);
242
                String checksumAlgorithm = rs.getString(5);
243
                String originMemberNode = rs.getString(6);
244
                String authoritativeMemberNode = rs.getString(7);
245
                Timestamp dateModified = rs.getTimestamp(8);
246
                String submitter = rs.getString(9);
247
                String objectFormat = rs.getString(10);
248
                long size = new Long(rs.getString(11)).longValue();
249
250
                Identifier sysMetaId = new Identifier();
251
                sysMetaId.setValue(guid);
252
                sysMeta.setIdentifier(sysMetaId);
253
                sysMeta.setDateUploaded(dateUploaded);
254
                Subject rightsHolderSubject = new Subject();
255
                rightsHolderSubject.setValue(rightsHolder);
256
                sysMeta.setRightsHolder(rightsHolderSubject);
257
                Checksum checksumObject = new Checksum();
258
                checksumObject.setValue(checksum);
259
                checksumObject.setAlgorithm(ChecksumAlgorithm.convert(checksumAlgorithm));
260
                sysMeta.setChecksum(checksumObject);
261
                NodeReference omn = new NodeReference();
262
                omn.setValue(originMemberNode);
263
                sysMeta.setOriginMemberNode(omn);
264
                NodeReference amn = new NodeReference();
265
                amn.setValue(authoritativeMemberNode);
266
                sysMeta.setAuthoritativeMemberNode(amn);
267
                sysMeta.setDateSysMetadataModified(dateModified);
268
                Subject submitterSubject = new Subject();
269
                submitterSubject.setValue(submitter);
270
                sysMeta.setSubmitter(submitterSubject);
271
                sysMeta.setObjectFormat(ObjectFormat.convert(objectFormat));
272
                sysMeta.setSize(size);
273
274
                stmt.close();
275
            }
276
            else
277
            {
278
                stmt.close();
279
                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
280 6099 leinfelder
                throw new McdbDocNotFoundException("Could not find " + guid);
281 6097 leinfelder
            }
282
283
        }
284
        catch (SQLException e)
285
        {
286
            e.printStackTrace();
287 6099 leinfelder
            logMetacat.error("Error while getting system metadata for guid " + guid + " : "
288 6097 leinfelder
                    + e.getMessage());
289
        }
290
        finally
291
        {
292
            // Return database connection to the pool
293
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
294
        }
295
296
        // look up provenance information
297
        sysMeta.setObsoleteList(getSystemMetadataProvenance(sysMeta.getIdentifier().getValue(), "obsoletes"));
298
        sysMeta.setObsoletedByList(getSystemMetadataProvenance(sysMeta.getIdentifier().getValue(), "obsoletedBy"));
299
        sysMeta.setDescribeList(getSystemMetadataProvenance(sysMeta.getIdentifier().getValue(), "describes"));
300
        sysMeta.setDescribedByList(getSystemMetadataProvenance(sysMeta.getIdentifier().getValue(), "describedBy"));
301
        sysMeta.setDerivedFromList(getSystemMetadataProvenance(sysMeta.getIdentifier().getValue(), "derivedFrom"));
302
303 6107 leinfelder
        // look up replication policy
304
        ReplicationPolicy replicationPolicy = new ReplicationPolicy();
305
        replicationPolicy.setBlockedMemberNodeList(getReplicationPolicy(guid, "blocked"));
306
        replicationPolicy.setPreferredMemberNodeList(getReplicationPolicy(guid, "preferred"));
307
		sysMeta.setReplicationPolicy(replicationPolicy);
308
309
		// look up replication status
310
		sysMeta.setReplicaList(getReplicationStatus(guid));
311
312 6097 leinfelder
        return sysMeta;
313
    }
314
315
    private List<Identifier> getSystemMetadataProvenance(String guid, String relationship)
316
    	throws McdbDocNotFoundException {
317
318
    	List<Identifier> identifiers = new ArrayList<Identifier>();
319
    	String sql = "select guid, relationship, target_guid " +
320
    		"from systemMetadataProvenance where guid = ? and relationship = ?";
321 6107 leinfelder
	    DBConnection dbConn = null;
322
	    int serialNumber = -1;
323
	    try {
324
	        // Get a database connection from the pool
325
	        dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getSystemMetadataProvenance");
326
	        serialNumber = dbConn.getCheckOutSerialNumber();
327
328
	        // Execute the statement
329
	        PreparedStatement stmt = dbConn.prepareStatement(sql);
330
	        stmt.setString(1, guid);
331
	        stmt.setString(2, relationship);
332
	        ResultSet rs = stmt.executeQuery();
333
	        while (rs.next())
334
	        {
335
	            String targetGuid = rs.getString(3);
336
	            Identifier id = new Identifier();
337
	            id.setValue(targetGuid);
338
	            identifiers.add(id);
339
340
	        }
341
	        stmt.close();
342
343
	    }
344
	    catch (SQLException e) {
345
	        logMetacat.error("Error while getting system metadata provenance for guid " + guid, e);
346
	    }
347
	    finally {
348
	        // Return database connection to the pool
349
	        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
350
	    }
351
352
	    return identifiers;
353
	}
354 6097 leinfelder
355 6107 leinfelder
    private List<NodeReference> getReplicationPolicy(String guid, String policy)
356
		throws McdbDocNotFoundException {
357
358
		List<NodeReference> nodes = new ArrayList<NodeReference>();
359
		String sql = "select guid, policy, member_node " +
360
			"from systemMetadataReplicationPolicy where guid = ? and policy = ?";
361
	    DBConnection dbConn = null;
362
	    int serialNumber = -1;
363
	    try {
364
	        // Get a database connection from the pool
365
	        dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getReplicationPolicy");
366
	        serialNumber = dbConn.getCheckOutSerialNumber();
367
368
	        // Execute the statement
369
	        PreparedStatement stmt = dbConn.prepareStatement(sql);
370
	        stmt.setString(1, guid);
371
	        stmt.setString(2, policy);
372
	        ResultSet rs = stmt.executeQuery();
373
	        while (rs.next())
374
	        {
375
	            String memberNode = rs.getString(3);
376
	            NodeReference node = new NodeReference();
377
	            node.setValue(memberNode);
378
	            nodes.add(node);
379
380
	        }
381
	        stmt.close();
382
383
	    } catch (SQLException e) {
384
	        logMetacat.error("Error while getting system metadata replication policy for guid " + guid, e);
385
	    }
386
	    finally {
387
	        // Return database connection to the pool
388
	        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
389
	    }
390
391
	    return nodes;
392
	}
393 6097 leinfelder
394 6107 leinfelder
    private List<Replica> getReplicationStatus(String guid) throws McdbDocNotFoundException {
395
396
		List<Replica> replicas = new ArrayList<Replica>();
397
		String sql = "select guid, member_node, status, date_verified " +
398
			"from systemMetadataReplicationStatus where guid = ?";
399
	    DBConnection dbConn = null;
400
	    int serialNumber = -1;
401
	    try {
402
	        // Get a database connection from the pool
403
	        dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getReplicas");
404
	        serialNumber = dbConn.getCheckOutSerialNumber();
405
406
	        // Execute the statement
407
	        PreparedStatement stmt = dbConn.prepareStatement(sql);
408
	        stmt.setString(1, guid);
409
	        ResultSet rs = stmt.executeQuery();
410
	        while (rs.next())
411
	        {
412
	            String memberNode = rs.getString(2);
413
	            String status = rs.getString(3);
414
	            java.sql.Date verified = rs.getDate(4);
415
416
	            Replica replica = new Replica();
417
	            NodeReference node = new NodeReference();
418
	            node.setValue(memberNode);
419
	            replica.setReplicaMemberNode(node);
420
	            replica.setReplicationStatus(ReplicationStatus.convert(status));
421
	            replica.setReplicaVerified(new Date(verified.getTime()));
422
	            replicas.add(replica);
423
	        }
424
	        stmt.close();
425
426
	    } catch (SQLException e) {
427
	        logMetacat.error("Error while getting system metadata replication policy for guid " + guid, e);
428
	    }
429
	    finally {
430
	        // Return database connection to the pool
431
	        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
432
	    }
433
434
	    return replicas;
435
	}
436
437 6097 leinfelder
    /**
438 5378 berkley
     * return information on the document with localId.  These are the fields
439
     * from the xml_documents table.  They can be used to contstruct metadata
440
     * about the object that is stored.
441
     * @param localId
442
     * @return
443
     * @throws McdbDocNotFoundException
444
     */
445 5441 berkley
    public Hashtable<String, Object> getDocumentInfo(String localId)
446 5378 berkley
        throws McdbDocNotFoundException
447
    {
448 5798 berkley
        try
449
        {
450
            AccessionNumber acc = new AccessionNumber(localId, "NONE");
451
            localId = acc.getDocid();
452
        }
453
        catch(Exception e)
454
        {
455
            //do nothing. just try the localId as it is
456
        }
457 5441 berkley
        Hashtable<String, Object> h = new Hashtable<String, Object>();
458 5378 berkley
        String sql = "select docname, doctype, user_owner, user_updated, " +
459
            "server_location, rev, date_created, date_updated from " +
460
            "xml_documents where docid like '" + localId + "'";
461
        DBConnection dbConn = null;
462
        int serialNumber = -1;
463
        try
464
        {
465
            // Get a database connection from the pool
466
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getDocumentInfo");
467
            serialNumber = dbConn.getCheckOutSerialNumber();
468
469
            // Execute the insert statement
470
            PreparedStatement stmt = dbConn.prepareStatement(sql);
471
            ResultSet rs = stmt.executeQuery();
472
            if (rs.next())
473
            {
474
                String docname = rs.getString(1);
475
                String doctype = rs.getString(2);
476
                String user_owner = rs.getString(3);
477
                String user_updated = rs.getString(4);
478
                String server_location = rs.getString(5);
479
                int rev = rs.getInt(6);
480
                String date_created = rs.getString(7);
481
                String date_updated = rs.getString(8);
482 6042 cjones
                h.put("docid", localId);
483 5378 berkley
                h.put("docname", docname);
484
                h.put("doctype", doctype);
485
                h.put("user_owner", user_owner);
486
                h.put("user_updated", user_updated);
487
                h.put("server_location", server_location);
488
                h.put("rev", new Integer(rev).toString());
489
                h.put("date_created", date_created);
490
                h.put("date_updated", date_updated);
491
492
                stmt.close();
493
            }
494
            else
495
            {
496
                stmt.close();
497
                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
498 5798 berkley
                throw new McdbDocNotFoundException("2Could not find document " + localId);
499 5378 berkley
            }
500 5441 berkley
501 5444 berkley
            String sql2 = "select principal_name, permission, perm_type, perm_order from xml_access " +
502 5441 berkley
            "where docid like '" + localId + "'";
503 6099 leinfelder
            logMetacat.debug("executing sql: " + sql2);
504 5441 berkley
            PreparedStatement stmt2 = dbConn.prepareStatement(sql2);
505 5442 berkley
            rs = stmt2.executeQuery();
506 5441 berkley
            Vector accessVector = new Vector();
507 5445 berkley
            while(rs.next())
508 5441 berkley
            {
509
                Hashtable accessHash = new Hashtable();
510
                String principal_name = rs.getString(1);
511
                String permission = rs.getString(2);
512
                String permissionType = rs.getString(3);
513
                String permissionOrder = rs.getString(4);
514
                accessHash.put("principal_name", principal_name);
515
                accessHash.put("permission", permission);
516
                accessHash.put("permission_type", permissionType);
517
                accessHash.put("permission_order", permissionOrder);
518 6099 leinfelder
                logMetacat.debug("accessHash: " + accessHash.toString());
519 5441 berkley
                accessVector.add(accessHash);
520
            }
521
            h.put("access", accessVector);
522 5378 berkley
        }
523
        catch (SQLException e)
524
        {
525 5444 berkley
            e.printStackTrace();
526 5378 berkley
            logMetacat.error("Error while getting document info for localid " + localId + " : "
527
                    + e.getMessage());
528
        }
529
        finally
530
        {
531
            // Return database connection to the pool
532
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
533
        }
534
        return h;
535
    }
536
537
    /**
538
     * return the newest rev for a given localId
539
     * @param localId
540
     * @return
541
     */
542
    public int getLatestRevForLocalId(String localId)
543
        throws McdbDocNotFoundException
544
    {
545 5798 berkley
        try
546
        {
547
            AccessionNumber acc = new AccessionNumber(localId, "NONE");
548
            localId = acc.getDocid();
549
        }
550
        catch(Exception e)
551
        {
552
            //do nothing. just try the localId as it is
553
        }
554 5378 berkley
        int rev = 0;
555
        String sql = "select rev from xml_documents where docid like '" + localId + "'";
556
        DBConnection dbConn = null;
557
        int serialNumber = -1;
558
        try
559
        {
560
            // Get a database connection from the pool
561
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getLatestRevForLocalId");
562
            serialNumber = dbConn.getCheckOutSerialNumber();
563
564
            // Execute the insert statement
565
            PreparedStatement stmt = dbConn.prepareStatement(sql);
566
            ResultSet rs = stmt.executeQuery();
567
            if (rs.next())
568
            {
569
                rev = rs.getInt(1);
570
                stmt.close();
571
            }
572
            else
573
            {
574
                stmt.close();
575
                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
576 5798 berkley
                throw new McdbDocNotFoundException("While trying to get the latest rev, could not find document " + localId);
577 5378 berkley
            }
578
        }
579
        catch (SQLException e)
580
        {
581
            logMetacat.error("Error while looking up the guid: "
582
                    + e.getMessage());
583
        }
584
        finally
585
        {
586
            // Return database connection to the pool
587
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
588
        }
589
        return rev;
590
    }
591
592
    /**
593 5377 berkley
     * return all local ids in the object store that do not have associated
594 6099 leinfelder
     * system metadata
595 5377 berkley
     */
596
    public List<String> getLocalIdsWithNoSystemMetadata()
597
    {
598
        Vector<String> ids = new Vector<String>();
599 6099 leinfelder
        String sql = "select docid, rev from xml_documents " +
600
        		"where docid not in " +
601
        		"(select docid from identifier where guid in (select guid from systemmetadata)))";
602 5377 berkley
        DBConnection dbConn = null;
603
        int serialNumber = -1;
604
        try
605
        {
606
            // Get a database connection from the pool
607
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getLocalIdsWithNoSystemMetadata");
608
            serialNumber = dbConn.getCheckOutSerialNumber();
609
610
            // Execute the insert statement
611
            PreparedStatement stmt = dbConn.prepareStatement(sql);
612
            ResultSet rs = stmt.executeQuery();
613
            while (rs.next())
614
            {
615
                String localid = rs.getString(1);
616 5798 berkley
                String rev = rs.getString(2);
617
                localid += "." + rev;
618 6099 leinfelder
                logMetacat.debug("id to add SM for: " + localid);
619 5377 berkley
                ids.add(localid);
620
            }
621
            stmt.close();
622
        }
623
        catch (SQLException e)
624
        {
625
            logMetacat.error("Error while looking up the guid: "
626
                    + e.getMessage());
627
        }
628
        finally
629
        {
630
            // Return database connection to the pool
631
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
632
        }
633
634
        return ids;
635
    }
636
637
    /**
638
     * return a listing of all local ids in the object store
639
     * @return a list of all local ids in metacat
640
     */
641
    public List<String> getAllLocalIds()
642
       throws Exception
643
    {
644
        Vector<String> ids = new Vector<String>();
645
        String sql = "select docid from xml_documents";
646
        DBConnection dbConn = null;
647
        int serialNumber = -1;
648
        try
649
        {
650
            // Get a database connection from the pool
651
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getAllLocalIds");
652
            serialNumber = dbConn.getCheckOutSerialNumber();
653
654
            // Execute the insert statement
655
            PreparedStatement stmt = dbConn.prepareStatement(sql);
656
            ResultSet rs = stmt.executeQuery();
657
            while (rs.next())
658
            {
659
                String localid = rs.getString(1);
660
                ids.add(localid);
661
            }
662
            stmt.close();
663
        }
664
        catch (SQLException e)
665
        {
666
            logMetacat.error("Error while looking up the guid: "
667
                    + e.getMessage());
668
        }
669
        finally
670
        {
671
            // Return database connection to the pool
672
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
673
        }
674
        return ids;
675
    }
676
677 6099 leinfelder
678 5282 jones
679
    /**
680
     * Determine if an identifier exists already, returning true if so.
681
     *
682
     * @param guid the global identifier to look up
683
     * @return boolean true if the identifier exists
684
     */
685
    public boolean identifierExists(String guid)
686
    {
687
        boolean idExists = false;
688
        try {
689
            String id = getLocalId(guid);
690
            if (id != null) {
691
                idExists = true;
692
            }
693
        } catch (McdbDocNotFoundException e) {
694
            idExists = false;
695
        }
696
        return idExists;
697
    }
698
699
    /**
700
     *
701 5453 berkley
     * @param guid
702
     * @param rev
703
     * @return
704
     */
705
    public String generateLocalId(String guid, int rev)
706
    {
707
        return generateLocalId(guid, rev, false);
708
    }
709 5286 jones
710
    /**
711
     * Given a global identifier (guid), create a suitable local identifier that
712
     * follows Metacat's docid semantics and format (scope.id.rev), and create
713
     * a mapping between these two identifiers.  This effectively reserves both
714
     * the global and the local identifier, as they will now be present in the
715
     * identifier mapping table.  If the incoming guid has the syntax of a
716
     * Metacat docid (scope.id.rev), then simply use it.
717
     *
718
     * @param guid the global string identifier
719
     * @param rev the revision number to be used in the localId
720
     * @return String containing the localId to be used for Metacat operations
721
     */
722 5453 berkley
    public String generateLocalId(String guid, int rev, boolean isSystemMetadata)
723 5286 jones
    {
724
        String localId = "";
725
        boolean conformsToDocidFormat = false;
726
727
        // Check if the guid passed in is already in docid (scope.id.rev) format
728
        try {
729
            AccessionNumber acc = new AccessionNumber(guid, "NONE");
730
            if (new Integer(acc.getRev()).intValue() > 0) {
731
                conformsToDocidFormat = true;
732
            }
733
        } catch (NumberFormatException e) {
734
            // No action needed, simply detecting invalid AccessionNumbers
735
        } catch (AccessionNumberException e) {
736
            // No action needed, simply detecting invalid AccessionNumbers
737
        } catch (SQLException e) {
738
            // No action needed, simply detecting invalid AccessionNumbers
739
        }
740
741
        if (conformsToDocidFormat) {
742
            // if it conforms, use it for both guid and localId
743
            localId = guid;
744
        } else {
745
            // if not, then generate a new unique localId
746
            localId = DocumentUtil.generateDocumentId(rev);
747
        }
748
749
        // Register this new pair in the identifier mapping table
750 6099 leinfelder
        logMetacat.debug("creating mapping in generateLocalId");
751 5453 berkley
        if(!isSystemMetadata)
752
        { //don't do this if we're generating for system metadata
753
            createMapping(guid, localId);
754
        }
755 5286 jones
756
        return localId;
757
    }
758 5322 berkley
759
    /**
760
     * given a local identifer, look up the guid.  Throw McdbDocNotFoundException
761 5452 berkley
     * if the docid, rev is not found in the identifiers or systemmetadata tables
762 5322 berkley
     *
763
     * @param docid the docid to look up
764
     * @param rev the revision of the docid to look up
765
     * @return String containing the mapped guid
766
     * @throws McdbDocNotFoundException if the docid, rev is not found
767
     */
768
    public String getGUID(String docid, int rev)
769
      throws McdbDocNotFoundException
770
    {
771 6099 leinfelder
        logMetacat.debug("getting guid for " + docid);
772 5322 berkley
        String query = "select guid from identifier where docid = ? and rev = ?";
773
        String guid = null;
774
775
        DBConnection dbConn = null;
776
        int serialNumber = -1;
777
        try {
778
            // Get a database connection from the pool
779 5377 berkley
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getGUID");
780 5322 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
781
782
            // Execute the insert statement
783
            PreparedStatement stmt = dbConn.prepareStatement(query);
784
            stmt.setString(1, docid);
785
            stmt.setInt(2, rev);
786
            ResultSet rs = stmt.executeQuery();
787 5451 berkley
            if (rs.next())
788
            {
789 5322 berkley
                guid = rs.getString(1);
790 5451 berkley
            }
791
            else
792
            {
793 6104 leinfelder
            	throw new McdbDocNotFoundException("No guid registered for docid " + docid + "." + rev);
794 5322 berkley
            }
795 5451 berkley
796 5322 berkley
        } catch (SQLException e) {
797
            logMetacat.error("Error while looking up the guid: "
798
                    + e.getMessage());
799
        } finally {
800
            // Return database connection to the pool
801
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
802
        }
803
804
        return guid;
805
    }
806 5333 berkley
807
    /**
808 5887 berkley
     * creates a system metadata mapping and adds additional fields from sysmeta
809
     * to the table for quick searching.
810
     *
811
     * @param guid the id to insert
812
     * @param localId the systemMetadata object to get the local id for
813
     */
814 6099 leinfelder
    public void createSystemMetadata(SystemMetadata sysmeta)
815 5887 berkley
    {
816 6099 leinfelder
        insertSystemMetadata(sysmeta.getIdentifier().getValue());
817
        updateSystemMetadata(sysmeta);
818 5887 berkley
    }
819 6099 leinfelder
820 5887 berkley
821
    /**
822 6079 leinfelder
     * update a mapping
823
     * @param guid
824
     * @param localId
825
     */
826
    public void updateMapping(String guid, String localId)
827
    {
828
829 6099 leinfelder
        logMetacat.debug("$$$$$$$$$$$$$$ updating mapping table");
830 5350 berkley
        int serialNumber = -1;
831
        DBConnection dbConn = null;
832
        try {
833
            // Parse the localId into scope and rev parts
834
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
835
            String docid = acc.getDocid();
836
            int rev = 1;
837
            if(acc.getRev() != null)
838
            {
839
              rev = (new Integer(acc.getRev()).intValue());
840
            }
841
842
            // Get a database connection from the pool
843
            dbConn =
844 6079 leinfelder
                DBConnectionPool.getDBConnection("IdentifierManager.updateMapping");
845 5350 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
846
847 6099 leinfelder
            // Execute the update statement
848
            String query = "update " + TYPE_IDENTIFIER + " set (docid, rev) = (?, ?) where guid='" + guid + "'";
849 5350 berkley
            PreparedStatement stmt = dbConn.prepareStatement(query);
850
            stmt.setString(1, docid);
851
            stmt.setInt(2, rev);
852
            int rows = stmt.executeUpdate();
853
854
            stmt.close();
855
        } catch (SQLException e) {
856
            e.printStackTrace();
857 6079 leinfelder
            logMetacat.error("SQL error while updating a mapping identifier: "
858 5350 berkley
                    + e.getMessage());
859
        } catch (NumberFormatException e) {
860
            e.printStackTrace();
861 6079 leinfelder
            logMetacat.error("NumberFormat error while updating a mapping identifier: "
862 5350 berkley
                    + e.getMessage());
863
        } catch (AccessionNumberException e) {
864
            e.printStackTrace();
865 6079 leinfelder
            logMetacat.error("AccessionNumber error while updating a mapping identifier: "
866 5350 berkley
                    + e.getMessage());
867
        } finally {
868
            // Return database connection to the pool
869
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
870
        }
871 6099 leinfelder
        logMetacat.debug("done updating mapping");
872 5350 berkley
    }
873 6099 leinfelder
874
    private void updateSystemMetadataFields(long dateUploaded, String rightsHolder,
875 5887 berkley
            String checksum, String checksumAlgorithm, String originMemberNode,
876 5917 berkley
            String authoritativeMemberNode, long modifiedDate, String submitter,
877 6107 leinfelder
            String guid, String objectFormat, long size, boolean replicationAllowed,
878
            int numberReplicas)
879 5887 berkley
    {
880
        DBConnection dbConn = null;
881
        int serialNumber = -1;
882 5957 berkley
883 5887 berkley
        try {
884
            // Get a database connection from the pool
885
            dbConn =
886
                DBConnectionPool.getDBConnection("IdentifierManager.createMapping");
887
            serialNumber = dbConn.getCheckOutSerialNumber();
888
889
            // Execute the insert statement
890
            String query = "update " + TYPE_SYSTEM_METADATA +
891
                " set (date_uploaded, rights_holder, checksum, checksum_algorithm, " +
892 5917 berkley
                "origin_member_node, authoritive_member_node, date_modified, " +
893 6107 leinfelder
                "submitter, object_format, size, replication_allowed, number_replicas) " +
894
                "= (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) where guid = ?";
895 5887 berkley
            PreparedStatement stmt = dbConn.prepareStatement(query);
896
897
            //data values
898
            stmt.setTimestamp(1, new java.sql.Timestamp(dateUploaded));
899
            stmt.setString(2, rightsHolder);
900
            stmt.setString(3, checksum);
901
            stmt.setString(4, checksumAlgorithm);
902
            stmt.setString(5, originMemberNode);
903
            stmt.setString(6, authoritativeMemberNode);
904
            stmt.setTimestamp(7, new java.sql.Timestamp(modifiedDate));
905
            stmt.setString(8, submitter);
906 5917 berkley
            stmt.setString(9, objectFormat);
907
            stmt.setString(10, new Long(size).toString());
908 6107 leinfelder
            stmt.setBoolean(11, replicationAllowed);
909
            stmt.setInt(12, numberReplicas);
910 5887 berkley
            //where clause
911 6107 leinfelder
            stmt.setString(13, guid);
912 6099 leinfelder
            logMetacat.debug("stmt: " + stmt.toString());
913 5887 berkley
            //execute
914
            int rows = stmt.executeUpdate();
915
916
            stmt.close();
917
        } catch (SQLException e) {
918
            e.printStackTrace();
919 5950 berkley
            logMetacat.error("insertAdditionalSystemMetadataFields: SQL error while creating a mapping to the system metadata identifier: "
920 5887 berkley
                    + e.getMessage());
921
        } catch (NumberFormatException e) {
922
            e.printStackTrace();
923 5950 berkley
            logMetacat.error("insertAdditionalSystemMetadataFields: NumberFormat error while creating a mapping to the system metadata identifier: "
924 5887 berkley
                    + e.getMessage());
925
        } finally {
926
            // Return database connection to the pool
927
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
928
        }
929
    }
930
931 6097 leinfelder
    private void insertSystemMetadataProvenance(String guid, String relationship, List<String> targetGuids)
932
    {
933
        DBConnection dbConn = null;
934
        int serialNumber = -1;
935
936
        try {
937
            // Get a database connection from the pool
938
            dbConn =
939 6107 leinfelder
                DBConnectionPool.getDBConnection("IdentifierManager.insertSystemMetadataProvenance");
940 6097 leinfelder
            serialNumber = dbConn.getCheckOutSerialNumber();
941
942
            // remove existing values first
943
            String delete = "delete from systemMetadataProvenance " +
944
            "where guid = ? and relationship = ?";
945
	        PreparedStatement stmt = dbConn.prepareStatement(delete);
946
	        //data values
947
	        stmt.setString(1, guid);
948
	        stmt.setString(2, relationship);
949
	        //execute
950
	        int deletedCount = stmt.executeUpdate();
951
	        stmt.close();
952
953
            for (String targetGuid: targetGuids) {
954
	            // Execute the insert statement
955
	            String insert = "insert into systemMetadataProvenance " +
956
	                "(guid, relationship, target_guid) " +
957
	                "values (?, ?, ?)";
958
	            PreparedStatement insertStatement = dbConn.prepareStatement(insert);
959
960
	            //data values
961
	            insertStatement.setString(1, guid);
962
	            insertStatement.setString(2, relationship);
963
	            insertStatement.setString(3, targetGuid);
964
	            //execute
965
	            int rows = insertStatement.executeUpdate();
966
	            insertStatement.close();
967
            }
968
        } catch (SQLException e) {
969
            logMetacat.error("SQL error while adding systemMetadataProvenance for: " + guid, e);
970
        } finally {
971
            // Return database connection to the pool
972
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
973
        }
974
    }
975
976 6107 leinfelder
    private void insertReplicationPolicy(String guid, String policy, List<String> memberNodes)
977
    {
978
        DBConnection dbConn = null;
979
        int serialNumber = -1;
980
981
        try {
982
            // Get a database connection from the pool
983
            dbConn =
984
                DBConnectionPool.getDBConnection("IdentifierManager.insertReplicationPolicy");
985
            serialNumber = dbConn.getCheckOutSerialNumber();
986
987
            // remove existing values first
988
            String delete = "delete from systemMetadataReplicationPolicy " +
989
            "where guid = ? and policy = ?";
990
	        PreparedStatement stmt = dbConn.prepareStatement(delete);
991
	        //data values
992
	        stmt.setString(1, guid);
993
	        stmt.setString(2, policy);
994
	        //execute
995
	        int deletedCount = stmt.executeUpdate();
996
	        stmt.close();
997
998
            for (String memberNode: memberNodes) {
999
	            // Execute the insert statement
1000
	            String insert = "insert into systemMetadataReplicationPolicy " +
1001
	                "(guid, policy, member_node) " +
1002
	                "values (?, ?, ?)";
1003
	            PreparedStatement insertStatement = dbConn.prepareStatement(insert);
1004
1005
	            //data values
1006
	            insertStatement.setString(1, guid);
1007
	            insertStatement.setString(2, policy);
1008
	            insertStatement.setString(3, memberNode);
1009
	            //execute
1010
	            int rows = insertStatement.executeUpdate();
1011
	            insertStatement.close();
1012
            }
1013
        } catch (SQLException e) {
1014
            logMetacat.error("SQL error while adding systemMetadataReplicationPolicy for: " + guid, e);
1015
        } finally {
1016
            // Return database connection to the pool
1017
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1018
        }
1019
    }
1020
1021
    private void insertReplicationStatus(String guid, List<Replica> replicas) {
1022
        DBConnection dbConn = null;
1023
        int serialNumber = -1;
1024
1025
        try {
1026
            // Get a database connection from the pool
1027
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.insertReplicas");
1028
            serialNumber = dbConn.getCheckOutSerialNumber();
1029
1030
            // remove existing values first
1031
            String delete = "delete from systemMetadataReplicationStatus " +
1032
            "where guid = ?";
1033
	        PreparedStatement stmt = dbConn.prepareStatement(delete);
1034
	        //data values
1035
	        stmt.setString(1, guid);
1036
	        //execute
1037
	        int deletedCount = stmt.executeUpdate();
1038
	        stmt.close();
1039
1040
            for (Replica replica: replicas) {
1041
	            // Execute the insert statement
1042
	            String insert = "insert into systemMetadataReplicationStatus " +
1043
	                "(guid, member_node, status, date_verified) " +
1044
	                "values (?, ?, ?, ?)";
1045
	            PreparedStatement insertStatement = dbConn.prepareStatement(insert);
1046
1047
	            //data values
1048
	            String memberNode = replica.getReplicaMemberNode().getValue();
1049
	            String status = replica.getReplicationStatus().toString();
1050
	            java.sql.Date sqlDate = new java.sql.Date(replica.getReplicaVerified().getTime());
1051
	            insertStatement.setString(1, guid);
1052
	            insertStatement.setString(2, memberNode);
1053
	            insertStatement.setString(3, status);
1054
	            insertStatement.setDate(4, sqlDate);
1055
1056
	            //execute
1057
	            int rows = insertStatement.executeUpdate();
1058
	            insertStatement.close();
1059
            }
1060
        } catch (SQLException e) {
1061
            logMetacat.error("SQL error while adding systemMetadataReplicationStatus for: " + guid, e);
1062
        } finally {
1063
            // Return database connection to the pool
1064
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1065
        }
1066
    }
1067
1068 5334 berkley
    /**
1069 5887 berkley
     * Insert the system metadata fields into the db
1070
     * @param sm
1071
     */
1072 6107 leinfelder
    public void updateSystemMetadata(SystemMetadata sm) {
1073
1074
        Boolean replicationAllowed = false;
1075
		Integer numberReplicas = -1;
1076
    	ReplicationPolicy replicationPolicy = sm.getReplicationPolicy();
1077
    	if (replicationPolicy != null) {
1078
    		replicationAllowed = replicationPolicy.getReplicationAllowed();
1079
    		numberReplicas = replicationPolicy.getNumberReplicas();
1080
    		replicationAllowed = replicationAllowed == null ? false: replicationAllowed;
1081
    		numberReplicas = numberReplicas == null ? -1: numberReplicas;
1082
    	}
1083
1084
    	// the main systemMetadata fields
1085
		updateSystemMetadataFields(
1086 5887 berkley
                sm.getDateUploaded().getTime(),
1087
                sm.getRightsHolder().getValue(),
1088
                sm.getChecksum().getValue(),
1089
                sm.getChecksum().getAlgorithm().name(),
1090
                sm.getOriginMemberNode().getValue(),
1091
                sm.getAuthoritativeMemberNode().getValue(),
1092
                sm.getDateSysMetadataModified().getTime(),
1093
                sm.getSubmitter().getValue(),
1094 5917 berkley
                sm.getIdentifier().getValue(),
1095
                sm.getObjectFormat().toString(),
1096 6107 leinfelder
                sm.getSize(),
1097
                replicationAllowed,
1098
                numberReplicas);
1099 6097 leinfelder
1100
        // add provenance information
1101
        String guid = sm.getIdentifier().getValue();
1102
        List<String> targetGuids = null;
1103
        String relationship = null;
1104
1105
        relationship = "obsoletedBy";
1106
        targetGuids = new ArrayList<String>();
1107
        for (Identifier id: sm.getObsoletedByList()) {
1108
        	targetGuids.add(id.getValue());
1109
        }
1110
        this.insertSystemMetadataProvenance(guid, relationship, targetGuids);
1111
1112
        relationship = "obsoletes";
1113
        targetGuids = new ArrayList<String>();
1114
        for (Identifier id: sm.getObsoleteList()) {
1115
        	targetGuids.add(id.getValue());
1116
        }
1117
        this.insertSystemMetadataProvenance(guid, relationship, targetGuids);
1118
1119
        relationship = "describes";
1120
        targetGuids = new ArrayList<String>();
1121
        for (Identifier id: sm.getDescribeList()) {
1122
        	targetGuids.add(id.getValue());
1123
        }
1124
        this.insertSystemMetadataProvenance(guid, relationship, targetGuids);
1125
1126
        relationship = "describedBy";
1127
        targetGuids = new ArrayList<String>();
1128
        for (Identifier id: sm.getDescribedByList()) {
1129
        	targetGuids.add(id.getValue());
1130
        }
1131
        this.insertSystemMetadataProvenance(guid, relationship, targetGuids);
1132
1133
        relationship = "derivedFrom";
1134
        targetGuids = new ArrayList<String>();
1135
        for (Identifier id: sm.getDerivedFromList()) {
1136
        	targetGuids.add(id.getValue());
1137
        }
1138
        this.insertSystemMetadataProvenance(guid, relationship, targetGuids);
1139 6107 leinfelder
1140
        // save replication policies
1141
        if (replicationPolicy != null) {
1142
		    List<String> nodes = null;
1143
		    String policy = null;
1144
1145
		    nodes = new ArrayList<String>();
1146
		    policy = "blocked";
1147
		    for (NodeReference node: replicationPolicy.getBlockedMemberNodeList()) {
1148
		    	nodes.add(node.getValue());
1149
		    }
1150
		    this.insertReplicationPolicy(guid, policy, nodes);
1151
1152
		    nodes = new ArrayList<String>();
1153
		    policy = "preferred";
1154
		    for (NodeReference node: replicationPolicy.getPreferredMemberNodeList()) {
1155
		    	nodes.add(node.getValue());
1156
		    }
1157
	        this.insertReplicationPolicy(guid, policy, nodes);
1158
        }
1159 6097 leinfelder
1160 6107 leinfelder
        // save replica information
1161
        this.insertReplicationStatus(guid, sm.getReplicaList());
1162
1163 5887 berkley
    }
1164
1165
    /**
1166 6099 leinfelder
     * Lookup a localId given the GUID. If
1167
     * the identifier is not found, throw an exception.
1168
     *
1169
     * @param guid the global identifier to look up
1170
     * @return String containing the corresponding LocalId
1171
     * @throws McdbDocNotFoundException if the identifier is not found
1172 5334 berkley
     */
1173 6099 leinfelder
    public String getLocalId(String guid) throws McdbDocNotFoundException {
1174 5334 berkley
1175
      String db_guid = "";
1176
      String docid = "";
1177
      int rev = 0;
1178
1179 6099 leinfelder
      String query = "select guid, docid, rev from " + TYPE_IDENTIFIER + " where guid = ?";
1180 5334 berkley
1181
      DBConnection dbConn = null;
1182 5333 berkley
      int serialNumber = -1;
1183 5334 berkley
      try {
1184
          // Get a database connection from the pool
1185
          dbConn = DBConnectionPool.getDBConnection("Identifier.getLocalId");
1186
          serialNumber = dbConn.getCheckOutSerialNumber();
1187
1188
          // Execute the insert statement
1189
          PreparedStatement stmt = dbConn.prepareStatement(query);
1190
          stmt.setString(1, guid);
1191
          ResultSet rs = stmt.executeQuery();
1192
          if (rs.next()) {
1193
              db_guid = rs.getString(1);
1194
              docid = rs.getString(2);
1195
              rev = rs.getInt(3);
1196
              assert(db_guid.equals(guid));
1197
          } else {
1198
              throw new McdbDocNotFoundException("Document not found:" + guid);
1199
          }
1200
          stmt.close();
1201
      } catch (SQLException e) {
1202
          logMetacat.error("Error while looking up the local identifier: "
1203
                  + e.getMessage());
1204
      } finally {
1205
          // Return database connection to the pool
1206
          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1207
      }
1208
      return docid + "." + rev;
1209
    }
1210
1211 5377 berkley
    /**
1212 5895 berkley
     * query the systemmetadata table based on the given parameters
1213
     * @param startTime
1214
     * @param endTime
1215
     * @param objectFormat
1216
     * @param replicaStatus
1217
     * @param start
1218
     * @param count
1219
     * @return ObjectList
1220
     */
1221
    public ObjectList querySystemMetadata(Date startTime, Date endTime,
1222
            ObjectFormat objectFormat, boolean replicaStatus, int start, int count)
1223
    {
1224
        ObjectList ol = new ObjectList();
1225
        int total = 0;
1226 5943 berkley
        DBConnection dbConn = null;
1227
        int serialNumber = -1;
1228 5895 berkley
1229
        try
1230
        {
1231
            String sql = "select guid, date_uploaded, rights_holder, checksum, " +
1232
                "checksum_algorithm, origin_member_node, authoritive_member_node, " +
1233 5917 berkley
                "date_modified, submitter, object_format, size from systemmetadata";
1234 5895 berkley
1235
            boolean f1 = false;
1236
            boolean f2 = false;
1237
            boolean f3 = false;
1238
1239
            if(startTime != null)
1240
            {
1241 5917 berkley
                sql += " where systemmetadata.date_modified > ?";
1242 5895 berkley
                f1 = true;
1243
            }
1244
1245
            if(endTime != null)
1246
            {
1247 5917 berkley
                if(!f1)
1248
                {
1249
                    sql += " where systemmetadata.date_modified < ?";
1250
                }
1251
                else
1252
                {
1253
                    sql += " and systemmetadata.date_modified < ?";
1254
                }
1255 5895 berkley
                f2 = true;
1256
            }
1257
1258
            if(objectFormat != null)
1259
            {
1260 5917 berkley
                if(!f1 && !f2)
1261
                {
1262
                    sql += " where object_format = ?";
1263
                }
1264
                else
1265
                {
1266
                    sql += " and object_format = ?";
1267
                }
1268 5895 berkley
                f3 = true;
1269
            }
1270
1271
            if(replicaStatus)
1272
            {
1273
                String currentNodeId = PropertyService.getInstance().getProperty("dataone.memberNodeId");
1274 5917 berkley
                if(!f1 && !f2 && !f3)
1275
                {
1276
                    sql += " where authoritive_member_node != '" + currentNodeId.trim() + "'";
1277
                }
1278
                else
1279
                {
1280
                    sql += " and authoritive_member_node != '" + currentNodeId.trim() + "'";
1281
                }
1282 5895 berkley
            }
1283
1284 5943 berkley
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.querySystemMetadata");
1285
            serialNumber = dbConn.getCheckOutSerialNumber();
1286 5895 berkley
            PreparedStatement stmt = dbConn.prepareStatement(sql);
1287
1288
            if(f1 && f2 && f3)
1289
            {
1290
                stmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1291
                stmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1292
                stmt.setString(3, objectFormat.toString());
1293
            }
1294
            else if(f1 && f2 && !f3)
1295
            {
1296
                stmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1297
                stmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1298
            }
1299
            else if(f1 && !f2 && f3)
1300
            {
1301
                stmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1302
                stmt.setString(2, objectFormat.toString());
1303
            }
1304
            else if(f1 && !f2 && !f3)
1305
            {
1306
                stmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1307
            }
1308
            else if(!f1 && f2 && f3)
1309
            {
1310
                stmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1311
                stmt.setString(2, objectFormat.toString());
1312
            }
1313
            else if(!f1 && !f2 && f3)
1314
            {
1315
                stmt.setString(1, objectFormat.toString());
1316
            }
1317
            else if(!f1 && f2 && !f3)
1318
            {
1319
                stmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1320
            }
1321
1322 6099 leinfelder
            //logMetacat.debug("LISTOBJECTS QUERY: " + stmt.toString());
1323 5895 berkley
1324
            ResultSet rs = stmt.executeQuery();
1325 5917 berkley
            for(int i=0; i<start; i++)
1326 5895 berkley
            {
1327 5917 berkley
                if(rs.next())
1328
                {
1329
                    total++;
1330
                }
1331
                else
1332
                {
1333
                    break;
1334
                }
1335 5895 berkley
            }
1336 5917 berkley
1337 5895 berkley
            int countIndex = 0;
1338
1339
            while(rs.next())
1340
            {
1341
                total++;
1342
                if(countIndex >= count)
1343
                {
1344
                    break;
1345
                }
1346
                String guid = rs.getString(1);
1347 6099 leinfelder
                //logMetacat.debug("query found doc with guid " + guid);
1348 5895 berkley
                //Timestamp dateUploaded = rs.getTimestamp(2);
1349
                //String rightsHolder = rs.getString(3);
1350
                String checksum = rs.getString(4);
1351
                String checksumAlgorithm = rs.getString(5);
1352
                //String originMemberNode = rs.getString(6);
1353
                String authoritiveMemberNode = rs.getString(7);
1354
                Timestamp dateModified = rs.getTimestamp(8);
1355
                //String submitter = rs.getString(9);
1356
                String format = rs.getString(10);
1357 5917 berkley
                String sz = rs.getString(11);
1358
                long size = 0;
1359
                if(sz != null && !sz.trim().equals(""))
1360
                {
1361
                    size = new Long(rs.getString(11)).longValue();
1362
                }
1363 5895 berkley
1364
                ObjectInfo oi = new ObjectInfo();
1365
1366
                Identifier id = new Identifier();
1367
                id.setValue(guid);
1368
                oi.setIdentifier(id);
1369
1370
                oi.setDateSysMetadataModified(new Date(dateModified.getTime()));
1371
1372
                Checksum cs = new Checksum();
1373
                cs.setValue(checksum);
1374 5906 berkley
                cs.setAlgorithm(ChecksumAlgorithm.valueOf(checksumAlgorithm));
1375 5957 berkley
                //cs.setAlgorithm(ChecksumAlgorithm.convert(checksumAlgorithm));
1376 5895 berkley
                oi.setChecksum(cs);
1377
1378 6091 cjones
                ObjectFormat oFormat = ObjectFormat.convert(format);
1379 5895 berkley
                if(oFormat != null)
1380
                {
1381
                    oi.setObjectFormat(oFormat);
1382
                }
1383 5906 berkley
                else
1384
                { //if there is no object format, just default to text/plain
1385 6091 cjones
                    oi.setObjectFormat(ObjectFormat.OCTET_STREAM);
1386 5906 berkley
                }
1387 5917 berkley
1388
                oi.setSize(size);
1389 5895 berkley
1390
                ol.addObjectInfo(oi);
1391
                countIndex++;
1392
            }
1393
1394
            while(rs.next())
1395
            { //expend the resultset to get the total count of possible rows
1396
                total++;
1397
            }
1398
        }
1399
        catch(Exception e)
1400
        {
1401
           e.printStackTrace();
1402 6099 leinfelder
           logMetacat.error("Error querying system metadata: " + e.getMessage());
1403 5895 berkley
        }
1404 5943 berkley
        finally
1405
        {
1406
            // Return database connection to the pool
1407
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1408
        }
1409 5895 berkley
1410
        ol.setStart(start);
1411 5922 berkley
        ol.setCount(ol.sizeObjectInfoList());
1412 5895 berkley
        ol.setTotal(total);
1413
1414
        return ol;
1415
    }
1416
1417
    /**
1418 6099 leinfelder
     * create a mapping in the identifier table
1419 5377 berkley
     * @param guid
1420
     * @param localId
1421
     */
1422 6099 leinfelder
    public void createMapping(String guid, String localId)
1423 5453 berkley
    {
1424 5334 berkley
1425
        int serialNumber = -1;
1426 5333 berkley
        DBConnection dbConn = null;
1427
        try {
1428
1429
            // Parse the localId into scope and rev parts
1430
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
1431
            String docid = acc.getDocid();
1432 5344 berkley
            int rev = 1;
1433 6099 leinfelder
            if (acc.getRev() != null) {
1434 5344 berkley
              rev = (new Integer(acc.getRev()).intValue());
1435
            }
1436 5333 berkley
1437
            // Get a database connection from the pool
1438 6099 leinfelder
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.createMapping");
1439 5333 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
1440
1441
            // Execute the insert statement
1442 6099 leinfelder
            String query = "insert into " + TYPE_IDENTIFIER + " (guid, docid, rev) values (?, ?, ?)";
1443 5333 berkley
            PreparedStatement stmt = dbConn.prepareStatement(query);
1444
            stmt.setString(1, guid);
1445
            stmt.setString(2, docid);
1446
            stmt.setInt(3, rev);
1447 6099 leinfelder
            logMetacat.debug("mapping query: " + stmt.toString());
1448 5333 berkley
            int rows = stmt.executeUpdate();
1449
1450
            stmt.close();
1451
        } catch (SQLException e) {
1452 5344 berkley
            e.printStackTrace();
1453 6099 leinfelder
            logMetacat.error("createGenericMapping: SQL error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1454 5333 berkley
                    + e.getMessage());
1455
        } catch (NumberFormatException e) {
1456 5344 berkley
            e.printStackTrace();
1457 6099 leinfelder
            logMetacat.error("createGenericMapping: NumberFormat error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1458 5333 berkley
                    + e.getMessage());
1459
        } catch (AccessionNumberException e) {
1460 5344 berkley
            e.printStackTrace();
1461 6099 leinfelder
            logMetacat.error("createGenericMapping: AccessionNumber error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
1462 5333 berkley
                    + e.getMessage());
1463
        } finally {
1464
            // Return database connection to the pool
1465
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1466
        }
1467
    }
1468 6099 leinfelder
1469
    /**
1470
     * create the systemmetadata record
1471
     * @param guid
1472
     */
1473
    public void insertSystemMetadata(String guid)
1474
    {
1475
1476
        int serialNumber = -1;
1477
        DBConnection dbConn = null;
1478
        try {
1479
1480
            // Get a database connection from the pool
1481
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.insertSystemMetadata");
1482
            serialNumber = dbConn.getCheckOutSerialNumber();
1483
1484
            // Execute the insert statement
1485
            String query = "insert into " + TYPE_SYSTEM_METADATA + " (guid) values (?)";
1486
            PreparedStatement stmt = dbConn.prepareStatement(query);
1487
            stmt.setString(1, guid);
1488
            logMetacat.debug("system metadata query: " + stmt.toString());
1489
            int rows = stmt.executeUpdate();
1490
1491
            stmt.close();
1492
        } catch (Exception e) {
1493
            e.printStackTrace();
1494
            logMetacat.error("Error while creating " + TYPE_SYSTEM_METADATA + " record: "
1495
                    + e.getMessage());
1496
        } finally {
1497
            // Return database connection to the pool
1498
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1499
        }
1500
    }
1501 5282 jones
}