Project

General

Profile

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