Project

General

Profile

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