Project

General

Profile

1
/**
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
import java.sql.Timestamp;
31
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

    
37
import org.apache.log4j.Logger;
38
import org.dataone.service.types.Checksum;
39
import org.dataone.service.types.ChecksumAlgorithm;
40
import org.dataone.service.types.Identifier;
41
import org.dataone.service.types.NodeReference;
42
import org.dataone.service.types.ObjectFormat;
43
import org.dataone.service.types.ObjectInfo;
44
import org.dataone.service.types.ObjectList;
45
import org.dataone.service.types.Replica;
46
import org.dataone.service.types.ReplicationPolicy;
47
import org.dataone.service.types.ReplicationStatus;
48
import org.dataone.service.types.Subject;
49
import org.dataone.service.types.SystemMetadata;
50

    
51
import edu.ucsb.nceas.metacat.database.DBConnection;
52
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
53
import edu.ucsb.nceas.metacat.properties.PropertyService;
54
import edu.ucsb.nceas.metacat.util.DocumentUtil;
55

    
56
/**
57
 * Manage the relationship between Metacat local identifiers (LocalIDs) that are
58
 * codified as the (docid, rev) pair with globally unique string identifiers
59
 * (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
    public static final String TYPE_SYSTEM_METADATA = "systemmetadata";
68
    public static final String TYPE_IDENTIFIER = "identifier";
69
  
70
    /**
71
     * The single instance of the manager that is always returned.
72
     */
73
    private static IdentifierManager self = null;
74
    private Logger logMetacat = Logger.getLogger(IdentifierManager.class);
75

    
76
    /**
77
     * A private constructor that initializes the class when getInstance() is
78
     * called.
79
     */
80
    private IdentifierManager() {}
81

    
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
    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
    /**
130
     * 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
          "origin_member_node, authoritive_member_node, date_modified, submitter, object_format, size " +
149
          "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
                String objectFormat = rs.getString(10);
174
                long size = new Long(rs.getString(11)).longValue();
175
                
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
                h.put("object_format", objectFormat);
186
                h.put("size", new Long(size).toString());
187
                
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
     * return a hash of all of the info that is in the systemmetadata table
214
     * @param guid
215
     * @return
216
     */
217
    public SystemMetadata getSystemMetadata(String guid)
218
    	throws McdbDocNotFoundException
219
    {
220
        
221
        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
          "from systemmetadata where guid = ?";
225
        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
            stmt.setString(1, guid);
236
            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
                throw new McdbDocNotFoundException("Could not find " + guid);
281
            }
282
            
283
        } 
284
        catch (SQLException e) 
285
        {
286
            e.printStackTrace();
287
            logMetacat.error("Error while getting system metadata for guid " + guid + " : "  
288
                    + 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
        // 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
        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
	    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
    
355
    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
    
394
    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
    /**
438
     * 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
    public Hashtable<String, Object> getDocumentInfo(String localId)
446
        throws McdbDocNotFoundException
447
    {
448
        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
        Hashtable<String, Object> h = new Hashtable<String, Object>();
458
        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
                h.put("docid", localId);
483
                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
                throw new McdbDocNotFoundException("2Could not find document " + localId);
499
            }
500
            
501
            String sql2 = "select principal_name, permission, perm_type, perm_order from xml_access " +
502
            "where docid like '" + localId + "'";
503
            logMetacat.debug("executing sql: " + sql2);
504
            PreparedStatement stmt2 = dbConn.prepareStatement(sql2);
505
            rs = stmt2.executeQuery();
506
            Vector accessVector = new Vector();
507
            while(rs.next())
508
            {
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
                logMetacat.debug("accessHash: " + accessHash.toString());
519
                accessVector.add(accessHash);
520
            }
521
            h.put("access", accessVector);
522
        } 
523
        catch (SQLException e) 
524
        {
525
            e.printStackTrace();
526
            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
        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
        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
                throw new McdbDocNotFoundException("While trying to get the latest rev, could not find document " + localId);
577
            }
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
     * return all local ids in the object store that do not have associated
594
     * system metadata
595
     */
596
    public List<String> getLocalIdsWithNoSystemMetadata()
597
    {
598
        Vector<String> ids = new Vector<String>();
599
        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
        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
                String rev = rs.getString(2);
617
                localid += "." + rev;
618
                logMetacat.debug("id to add SM for: " + localid);
619
                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

    
678
    
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
     * @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

    
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
    public String generateLocalId(String guid, int rev, boolean isSystemMetadata) 
723
    {
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
        logMetacat.debug("creating mapping in generateLocalId");
751
        if(!isSystemMetadata)
752
        { //don't do this if we're generating for system metadata
753
            createMapping(guid, localId);
754
        }
755
        
756
        return localId;
757
    }
758
    
759
    /**
760
     * given a local identifer, look up the guid.  Throw McdbDocNotFoundException
761
     * if the docid, rev is not found in the identifiers or systemmetadata tables
762
     *
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
        logMetacat.debug("getting guid for " + docid);
772
        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
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getGUID");
780
            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
            if (rs.next()) 
788
            {
789
                guid = rs.getString(1);
790
            } 
791
            else
792
            {
793
            	throw new McdbDocNotFoundException("No guid registered for docid " + docid + "." + rev);
794
            }
795
            
796
        } 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
    
807
    /**
808
     * 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
    public void createSystemMetadata(SystemMetadata sysmeta)
815
    {
816
        insertSystemMetadata(sysmeta.getIdentifier().getValue());
817
        updateSystemMetadata(sysmeta);
818
    }
819
        
820
    
821
    /**
822
     * update a mapping
823
     * @param guid
824
     * @param localId
825
     */
826
    public void updateMapping(String guid, String localId)
827
    {
828
    	
829
        logMetacat.debug("$$$$$$$$$$$$$$ updating mapping table");
830
        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
                DBConnectionPool.getDBConnection("IdentifierManager.updateMapping");
845
            serialNumber = dbConn.getCheckOutSerialNumber();
846

    
847
            // Execute the update statement
848
            String query = "update " + TYPE_IDENTIFIER + " set (docid, rev) = (?, ?) where guid='" + guid + "'";
849
            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
            logMetacat.error("SQL error while updating a mapping identifier: " 
858
                    + e.getMessage());
859
        } catch (NumberFormatException e) {
860
            e.printStackTrace();
861
            logMetacat.error("NumberFormat error while updating a mapping identifier: " 
862
                    + e.getMessage());
863
        } catch (AccessionNumberException e) {
864
            e.printStackTrace();
865
            logMetacat.error("AccessionNumber error while updating a mapping identifier: " 
866
                    + e.getMessage());
867
        } finally {
868
            // Return database connection to the pool
869
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
870
        }
871
        logMetacat.debug("done updating mapping");
872
    }
873
        
874
    private void updateSystemMetadataFields(long dateUploaded, String rightsHolder,
875
            String checksum, String checksumAlgorithm, String originMemberNode,
876
            String authoritativeMemberNode, long modifiedDate, String submitter, 
877
            String guid, String objectFormat, long size, boolean replicationAllowed,
878
            int numberReplicas)
879
    {
880
        DBConnection dbConn = null;
881
        int serialNumber = -1;
882
        
883
        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
                "origin_member_node, authoritive_member_node, date_modified, " +
893
                "submitter, object_format, size, replication_allowed, number_replicas) " +
894
                "= (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) where guid = ?";
895
            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
            stmt.setString(9, objectFormat);
907
            stmt.setString(10, new Long(size).toString());
908
            stmt.setBoolean(11, replicationAllowed);
909
            stmt.setInt(12, numberReplicas);
910
            //where clause
911
            stmt.setString(13, guid);
912
            logMetacat.debug("stmt: " + stmt.toString());
913
            //execute
914
            int rows = stmt.executeUpdate();
915

    
916
            stmt.close();
917
        } catch (SQLException e) {
918
            e.printStackTrace();
919
            logMetacat.error("insertAdditionalSystemMetadataFields: SQL error while creating a mapping to the system metadata identifier: " 
920
                    + e.getMessage());
921
        } catch (NumberFormatException e) {
922
            e.printStackTrace();
923
            logMetacat.error("insertAdditionalSystemMetadataFields: NumberFormat error while creating a mapping to the system metadata identifier: " 
924
                    + e.getMessage());
925
        } finally {
926
            // Return database connection to the pool
927
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
928
        }
929
    }
930
    
931
    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
                DBConnectionPool.getDBConnection("IdentifierManager.insertSystemMetadataProvenance");
940
            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
    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
    /**
1069
     * Insert the system metadata fields into the db
1070
     * @param sm
1071
     */
1072
    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
                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
                sm.getIdentifier().getValue(),
1095
                sm.getObjectFormat().toString(),
1096
                sm.getSize(),
1097
                replicationAllowed, 
1098
                numberReplicas);
1099
        
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
                
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
        
1160
        // save replica information
1161
        this.insertReplicationStatus(guid, sm.getReplicaList());
1162
        
1163
    }
1164
    
1165
    /**
1166
     * 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
     */
1173
    public String getLocalId(String guid) throws McdbDocNotFoundException {
1174
      
1175
      String db_guid = "";
1176
      String docid = "";
1177
      int rev = 0;
1178
      
1179
      String query = "select guid, docid, rev from " + TYPE_IDENTIFIER + " where guid = ?";
1180
      
1181
      DBConnection dbConn = null;
1182
      int serialNumber = -1;
1183
      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
    /**
1212
     * 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
        DBConnection dbConn = null;
1227
        int serialNumber = -1;
1228
        
1229
        try
1230
        {
1231
            String sql = "select guid, date_uploaded, rights_holder, checksum, " +
1232
                "checksum_algorithm, origin_member_node, authoritive_member_node, " +
1233
                "date_modified, submitter, object_format, size from systemmetadata";
1234
            
1235
            boolean f1 = false;
1236
            boolean f2 = false;
1237
            boolean f3 = false;
1238
            
1239
            if(startTime != null)
1240
            {
1241
                sql += " where systemmetadata.date_modified > ?";
1242
                f1 = true;
1243
            }
1244
            
1245
            if(endTime != null)
1246
            {
1247
                if(!f1)
1248
                {
1249
                    sql += " where systemmetadata.date_modified < ?";
1250
                }
1251
                else
1252
                {
1253
                    sql += " and systemmetadata.date_modified < ?";
1254
                }
1255
                f2 = true;
1256
            }
1257
            
1258
            if(objectFormat != null)
1259
            {
1260
                if(!f1 && !f2)
1261
                {
1262
                    sql += " where object_format = ?";
1263
                }
1264
                else 
1265
                {
1266
                    sql += " and object_format = ?";
1267
                }
1268
                f3 = true;
1269
            }
1270
            
1271
            if(replicaStatus)
1272
            {
1273
                String currentNodeId = PropertyService.getInstance().getProperty("dataone.memberNodeId");
1274
                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
            }
1283
            
1284
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.querySystemMetadata");
1285
            serialNumber = dbConn.getCheckOutSerialNumber();
1286
            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
            //logMetacat.debug("LISTOBJECTS QUERY: " + stmt.toString());
1323
            
1324
            ResultSet rs = stmt.executeQuery();
1325
            for(int i=0; i<start; i++)
1326
            {
1327
                if(rs.next())
1328
                {
1329
                    total++;
1330
                }
1331
                else
1332
                {
1333
                    break;
1334
                }
1335
            }
1336
            
1337
            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
                //logMetacat.debug("query found doc with guid " + guid);
1348
                //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
                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
                
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
                cs.setAlgorithm(ChecksumAlgorithm.valueOf(checksumAlgorithm));
1375
                //cs.setAlgorithm(ChecksumAlgorithm.convert(checksumAlgorithm));
1376
                oi.setChecksum(cs);
1377
                
1378
                ObjectFormat oFormat = ObjectFormat.convert(format);
1379
                if(oFormat != null)
1380
                {
1381
                    oi.setObjectFormat(oFormat);
1382
                }
1383
                else
1384
                { //if there is no object format, just default to text/plain
1385
                    oi.setObjectFormat(ObjectFormat.OCTET_STREAM);
1386
                }
1387
                                
1388
                oi.setSize(size);
1389
                
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
           logMetacat.error("Error querying system metadata: " + e.getMessage());
1403
        }
1404
        finally 
1405
        {
1406
            // Return database connection to the pool
1407
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1408
        }
1409
        
1410
        ol.setStart(start);
1411
        ol.setCount(ol.sizeObjectInfoList());
1412
        ol.setTotal(total);
1413
        
1414
        return ol;
1415
    }
1416
    
1417
    /**
1418
     * create a mapping in the identifier table
1419
     * @param guid
1420
     * @param localId
1421
     */
1422
    public void createMapping(String guid, String localId)
1423
    {        
1424
        
1425
        int serialNumber = -1;
1426
        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
            int rev = 1;
1433
            if (acc.getRev() != null) {
1434
              rev = (new Integer(acc.getRev()).intValue());
1435
            }
1436

    
1437
            // Get a database connection from the pool
1438
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.createMapping");
1439
            serialNumber = dbConn.getCheckOutSerialNumber();
1440

    
1441
            // Execute the insert statement
1442
            String query = "insert into " + TYPE_IDENTIFIER + " (guid, docid, rev) values (?, ?, ?)";
1443
            PreparedStatement stmt = dbConn.prepareStatement(query);
1444
            stmt.setString(1, guid);
1445
            stmt.setString(2, docid);
1446
            stmt.setInt(3, rev);
1447
            logMetacat.debug("mapping query: " + stmt.toString());
1448
            int rows = stmt.executeUpdate();
1449

    
1450
            stmt.close();
1451
        } catch (SQLException e) {
1452
            e.printStackTrace();
1453
            logMetacat.error("createGenericMapping: SQL error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: " 
1454
                    + e.getMessage());
1455
        } catch (NumberFormatException e) {
1456
            e.printStackTrace();
1457
            logMetacat.error("createGenericMapping: NumberFormat error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: " 
1458
                    + e.getMessage());
1459
        } catch (AccessionNumberException e) {
1460
            e.printStackTrace();
1461
            logMetacat.error("createGenericMapping: AccessionNumber error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: " 
1462
                    + e.getMessage());
1463
        } finally {
1464
            // Return database connection to the pool
1465
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1466
        }
1467
    }
1468
    
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
}
1502

    
(37-37/65)