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 9465 tao
        PreparedStatement stmt = null;
932 5322 berkley
        try {
933
            // Get a database connection from the pool
934 5377 berkley
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getGUID");
935 5322 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
936
937
            // Execute the insert statement
938 9465 tao
            stmt = dbConn.prepareStatement(query);
939 5322 berkley
            stmt.setString(1, docid);
940
            stmt.setInt(2, rev);
941
            ResultSet rs = stmt.executeQuery();
942 5451 berkley
            if (rs.next())
943
            {
944 5322 berkley
                guid = rs.getString(1);
945 5451 berkley
            }
946
            else
947
            {
948 6104 leinfelder
            	throw new McdbDocNotFoundException("No guid registered for docid " + docid + "." + rev);
949 5322 berkley
            }
950 9465 tao
            if(rs != null) {
951
                rs.close();
952
            }
953 5322 berkley
        } catch (SQLException e) {
954
            logMetacat.error("Error while looking up the guid: "
955
                    + e.getMessage());
956
        } finally {
957 9465 tao
            try {
958
                if(stmt != null) {
959
                    stmt.close();
960
                }
961
            } catch (Exception e) {
962
                logMetacat.warn("Couldn't close the prepared statement since "+e.getMessage());
963
            } finally {
964
                // Return database connection to the pool
965
                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
966
            }
967
968 5322 berkley
        }
969
970
        return guid;
971
    }
972 5333 berkley
973 9015 tao
    /**
974
     * Get the pid of the head (current) version of objects match the specified sid.
975 9119 tao
     * 1. locate all candidate chain-ends for S1:
976
     *      determined by:  seriesId == S1 AND (obsoletedBy == null  OR obsoletedBy.seriesId != S1) // these are the type1 and type2 ends
977
     *      If obsoletedBy is missing, we generally consider it a type 2 end except:
978
     *      there is another object in the chain (has the same series id) that obsoletes the missing object.
979
     * 2. if only 1 candidate chain-end, return it as the HEAD
980
     * 3. otherwise return the one in the chain with the latest dateUploaded value.
981 9015 tao
     * @param sid specified sid which should match.
982
     * @return the pid of the head version. The null will be returned if there is no pid found.
983 9016 tao
     * @throws SQLException
984 9015 tao
     */
985 9016 tao
    public Identifier getHeadPID(Identifier sid) throws SQLException {
986 9015 tao
        Identifier pid = null;
987
        if(sid != null && sid.getValue() != null && !sid.getValue().trim().equals("")) {
988
            logMetacat.debug("getting pid of the head version for matching the sid: " + sid.getValue());
989 9119 tao
            String sql = "select guid from systemMetadata where series_id = ? order by date_uploaded DESC";
990 9015 tao
            DBConnection dbConn = null;
991
            int serialNumber = -1;
992 9465 tao
            PreparedStatement stmt = null;
993 9119 tao
            int endsCount = 0;
994
            boolean hasError = false;
995 9015 tao
            try {
996
                // Get a database connection from the pool
997
                dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getHeadPID");
998
                serialNumber = dbConn.getCheckOutSerialNumber();
999
                // Execute the insert statement
1000 9465 tao
                stmt = dbConn.prepareStatement(sql);
1001 9015 tao
                stmt.setString(1, sid.getValue());
1002
                ResultSet rs = stmt.executeQuery();
1003 9119 tao
                boolean hasNext = rs.next();
1004
                boolean first = true;
1005
                Identifier firstOne = new Identifier();//since the sql using the desc order, the first one has the latest upload date.
1006
                if (hasNext)
1007 9015 tao
                {
1008 9119 tao
                    while(hasNext) {
1009
                        String guidStr = rs.getString(1);
1010
                        Identifier guid = new Identifier();
1011
                        guid.setValue(guidStr);
1012
                        if(first) {
1013
                            firstOne = guid;
1014
                            first =false;
1015
                        }
1016
                        SystemMetadata sysmeta = HazelcastService.getInstance().getSystemMetadataMap().get(guid);
1017
                        if(sysmeta.getObsoletedBy() == null) {
1018
                            //type 1 end
1019 9128 tao
                            logMetacat.debug(""+guidStr+" is a type 1 end for sid "+sid.getValue());
1020 9119 tao
                            pid = guid;
1021
                            endsCount++;
1022
                        } else {
1023
                            Identifier obsoletedBy = sysmeta.getObsoletedBy();
1024
                            SystemMetadata obsoletedBySysmeta = HazelcastService.getInstance().getSystemMetadataMap().get(obsoletedBy);
1025
                            if(obsoletedBySysmeta != null) {
1026
                                Identifier sidInObsoletedBy = obsoletedBySysmeta.getSeriesId();
1027
                                if(sidInObsoletedBy == null|| !sidInObsoletedBy.equals(sid)) {
1028
                                    // type 2 end
1029 9128 tao
                                    logMetacat.debug(""+guidStr+" is a type 2 end for sid "+sid.getValue());
1030 9119 tao
                                    pid = guid;
1031
                                    endsCount++;
1032
                                }
1033
                            } else {
1034
                                //obsoletedBySysmeta doesn't exist; it means the object is missing
1035
                                //generally, we consider it we generally consider it a type 2 end except:
1036
                                 //there is another object in the chain (has the same series id) that obsoletes the missing object.
1037
                                String sql2 = "select guid from systemMetadata where  obsoletes = ? and series_id = ?";
1038
                                PreparedStatement stmt2 = dbConn.prepareStatement(sql2);
1039
                                stmt2.setString(1, obsoletedBy.getValue());
1040
                                stmt2.setString(2, sid.getValue());
1041
                                ResultSet result = stmt2.executeQuery();
1042
                                boolean next = result.next();
1043
                                int count = 0;
1044
                                while(next) {
1045
                                    count++;
1046
                                    next = result.next();
1047
                                }
1048
                                if(count == 0) {
1049
                                    //the exception (another object in the chain (has the same series id) that obsoletes the missing object) doesn't exist
1050
                                    // it is a type 2 end
1051 9128 tao
                                    logMetacat.debug(""+guidStr+" is a type 2 end for sid "+sid.getValue());
1052 9119 tao
                                    pid = guid;
1053
                                    endsCount++;
1054
                                } else if (count ==1) {
1055
                                    // it is not end, do nothing;
1056
                                } else {
1057
                                    // something is wrong - there are more than one objects obsolete the missing object!
1058
                                    hasError = true;
1059
                                    break;
1060
                                }
1061
                            }
1062
                        }
1063
                        hasNext = rs.next();
1064
                    }
1065
                    if(endsCount == 1) {
1066
                        //it has one end and it is an ideal chain. We already assign the guid to the pid. So do nothing.
1067 9128 tao
                        logMetacat.info("It is an ideal for sid "+sid.getValue());
1068 9119 tao
                    }
1069
                    if(hasError || endsCount >1) {
1070
                        // 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)
1071 9128 tao
                        logMetacat.info("It is NOT an ideal for sid "+sid.getValue());
1072 9119 tao
                        pid = firstOne;
1073
                    }
1074 9026 tao
                } else {
1075 9119 tao
                    //it is not a sid or at least we don't have anything to match it.
1076
                    //do nothing, so null will be returned
1077 9026 tao
                }
1078 9465 tao
                if(rs != null) {
1079
                    rs.close();
1080
                }
1081 9015 tao
1082
            } catch (SQLException e) {
1083
                logMetacat.error("Error while get the head pid for the sid "+sid.getValue()+" : "
1084
                        + e.getMessage());
1085 9016 tao
                throw e;
1086 9015 tao
            } finally {
1087 9465 tao
                try {
1088
                    if(stmt != null) {
1089
                        stmt.close();
1090
                    }
1091
                } catch (Exception e) {
1092
                    logMetacat.warn("Couldn't close the prepared statement since "+e.getMessage());
1093
                } finally {
1094
                    // Return database connection to the pool
1095
                    DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1096
                }
1097 9015 tao
            }
1098
        }
1099
        return pid;
1100
    }
1101
1102 9016 tao
    /**
1103 9032 tao
     * Check if the specified sid object exists on the serial id field on the system metadata table
1104
     * @param sid
1105
     * @return true if it exists; false otherwise.
1106
     * @throws SQLException
1107
     */
1108
    public boolean systemMetadataSIDExists(Identifier sid) throws SQLException {
1109
        if (sid != null && sid.getValue() != null && !sid.getValue().trim().equals("")) {
1110
            return systemMetadataSIDExists(sid.getValue());
1111
        } else {
1112
            return false;
1113
        }
1114
    }
1115
1116
    /**
1117 9016 tao
     * Check if the specified sid exists on the serial id field on the system metadata table
1118
     * @param id
1119
     * @return true if it exists; false otherwise.
1120
     */
1121 9017 tao
    public boolean systemMetadataSIDExists(String sid) throws SQLException {
1122 9016 tao
        boolean exists = false;
1123 9032 tao
        logMetacat.debug("Check if the  sid: " + sid +" exists on the series_id field of the system metadata table.");
1124 9016 tao
        if(sid != null && !sid.trim().equals("")) {
1125
            String sql = "select guid from systemMetadata where series_id = ?";
1126
            DBConnection dbConn = null;
1127
            int serialNumber = -1;
1128 9465 tao
            PreparedStatement stmt = null;
1129 9016 tao
            try {
1130
                // Get a database connection from the pool
1131
                dbConn = DBConnectionPool.getDBConnection("IdentifierManager.serialIdExists");
1132
                serialNumber = dbConn.getCheckOutSerialNumber();
1133
                // Execute the insert statement
1134 9465 tao
                stmt = dbConn.prepareStatement(sql);
1135 9016 tao
                stmt.setString(1, sid);
1136
                ResultSet rs = stmt.executeQuery();
1137
                if (rs.next())
1138
                {
1139
                    exists = true;
1140
                }
1141 9465 tao
                if(rs != null) {
1142
                    rs.close();
1143
                }
1144 9016 tao
            } catch (SQLException e) {
1145
                logMetacat.error("Error while checking if the sid "+sid+" exists on the series_id field of the system metadata table: "
1146
                        + e.getMessage());
1147
                throw e;
1148
            } finally {
1149 9465 tao
                try {
1150
                    if(stmt != null) {
1151
                        stmt.close();
1152
                    }
1153
                } catch (Exception e) {
1154
                    logMetacat.warn("Couldn't close the prepared statement since "+e.getMessage());
1155
                } finally {
1156
                    // Return database connection to the pool
1157
                    DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1158
                }
1159 9016 tao
            }
1160
        }
1161
        return exists;
1162
    }
1163
1164 9032 tao
    /**
1165
     * Determine if the specified identifier object exists or not.
1166
     * @param pid - the specified identifier
1167
     * @return true if it is exists.
1168
     * @throws SQLException
1169
     * @throws NullPointerException
1170
     */
1171
    public boolean systemMetadataPIDExists(Identifier pid) throws SQLException {
1172
        if (pid != null && pid.getValue() != null && !pid.getValue().trim().equals("")) {
1173
            return systemMetadataPIDExists(pid.getValue());
1174
        } else {
1175
            return false;
1176
        }
1177
    }
1178
1179 9030 tao
    public boolean systemMetadataPIDExists(String guid) throws SQLException {
1180 6123 leinfelder
		logMetacat.debug("looking up system metadata for guid " + guid);
1181
		boolean exists = false;
1182 6337 leinfelder
		String query = "select guid from systemmetadata where guid = ?";
1183 6123 leinfelder
		DBConnection dbConn = null;
1184
		int serialNumber = -1;
1185 9465 tao
		PreparedStatement stmt = null;
1186 9032 tao
		if(guid != null && !guid.trim().equals("")) {
1187
		    try {
1188
	            // Get a database connection from the pool
1189
	            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.systemMetadataExisits");
1190
	            serialNumber = dbConn.getCheckOutSerialNumber();
1191 6123 leinfelder
1192 9032 tao
	            // Execute the insert statement
1193 9465 tao
	            stmt = dbConn.prepareStatement(query);
1194 9032 tao
	            stmt.setString(1, guid);
1195
	            ResultSet rs = stmt.executeQuery();
1196
	            if (rs.next()) {
1197
	                exists = true;
1198
	            }
1199 9465 tao
	            if(rs != null) {
1200
	                rs.close();
1201
	            }
1202 6123 leinfelder
1203 9032 tao
	        } catch (SQLException e) {
1204
	            logMetacat.error("Error while looking up the system metadata: "
1205
	                    + e.getMessage());
1206
	            throw e;
1207
	        } finally {
1208 9465 tao
	            try {
1209
	                if(stmt != null) {
1210
	                    stmt.close();
1211
	                }
1212
	            } catch (Exception e) {
1213
	                logMetacat.warn("Couldn't close the prepared statement since "+e.getMessage());
1214
	            } finally {
1215
	                // Return database connection to the pool
1216
	                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1217
	            }
1218 9032 tao
	        }
1219 6123 leinfelder
		}
1220
		return exists;
1221
	}
1222
1223 5333 berkley
    /**
1224 5887 berkley
     * creates a system metadata mapping and adds additional fields from sysmeta
1225
     * to the table for quick searching.
1226
     *
1227
     * @param guid the id to insert
1228
     * @param localId the systemMetadata object to get the local id for
1229 6108 leinfelder
     * @throws McdbDocNotFoundException
1230 6892 cjones
     * @throws SQLException
1231 6904 cjones
     * @throws InvalidSystemMetadata
1232 5887 berkley
     */
1233 7188 leinfelder
    public void insertOrUpdateSystemMetadata(SystemMetadata sysmeta)
1234 6904 cjones
        throws McdbDocNotFoundException, SQLException, InvalidSystemMetadata {
1235 6277 leinfelder
    	String guid = sysmeta.getIdentifier().getValue();
1236 7188 leinfelder
1237
    	 // Get a database connection from the pool
1238
        DBConnection dbConn = DBConnectionPool.getDBConnection("IdentifierManager.insertSystemMetadata");
1239
        int serialNumber = dbConn.getCheckOutSerialNumber();
1240 6892 cjones
1241 7188 leinfelder
        try {
1242
        	// use a single transaction for it all
1243
        	dbConn.setAutoCommit(false);
1244
1245
	    	// insert the record if needed
1246 9030 tao
        	if (!IdentifierManager.getInstance().systemMetadataPIDExists(guid)) {
1247 7188 leinfelder
    	        insertSystemMetadata(guid, dbConn);
1248
			}
1249
	        // update with the values
1250
	        updateSystemMetadata(sysmeta, dbConn);
1251
1252
	        // commit if we got here with no errors
1253
	        dbConn.commit();
1254
        } catch (Exception e) {
1255
            e.printStackTrace();
1256
            logMetacat.error("Error while creating " + TYPE_SYSTEM_METADATA + " record: " + guid, e );
1257
            dbConn.rollback();
1258 9220 tao
            throw new SQLException("Can't save system metadata "+e.getMessage());
1259 7188 leinfelder
        } finally {
1260
            // Return database connection to the pool
1261
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1262
        }
1263
1264
1265 5887 berkley
    }
1266 6099 leinfelder
1267 5887 berkley
1268
    /**
1269 6079 leinfelder
     * update a mapping
1270
     * @param guid
1271
     * @param localId
1272
     */
1273
    public void updateMapping(String guid, String localId)
1274
    {
1275
1276 6099 leinfelder
        logMetacat.debug("$$$$$$$$$$$$$$ updating mapping table");
1277 5350 berkley
        int serialNumber = -1;
1278
        DBConnection dbConn = null;
1279
        try {
1280
            // Parse the localId into scope and rev parts
1281
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
1282
            String docid = acc.getDocid();
1283
            int rev = 1;
1284
            if(acc.getRev() != null)
1285
            {
1286
              rev = (new Integer(acc.getRev()).intValue());
1287
            }
1288
1289
            // Get a database connection from the pool
1290
            dbConn =
1291 6079 leinfelder
                DBConnectionPool.getDBConnection("IdentifierManager.updateMapping");
1292 5350 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
1293
1294 6099 leinfelder
            // Execute the update statement
1295 6595 leinfelder
            String query = "update " + TYPE_IDENTIFIER + " set (docid, rev) = (?, ?) where guid = ?";
1296 5350 berkley
            PreparedStatement stmt = dbConn.prepareStatement(query);
1297
            stmt.setString(1, docid);
1298
            stmt.setInt(2, rev);
1299 6595 leinfelder
            stmt.setString(3, guid);
1300 5350 berkley
            int rows = stmt.executeUpdate();
1301
1302
            stmt.close();
1303
        } catch (SQLException e) {
1304
            e.printStackTrace();
1305 6079 leinfelder
            logMetacat.error("SQL error while updating a mapping identifier: "
1306 5350 berkley
                    + e.getMessage());
1307
        } catch (NumberFormatException e) {
1308
            e.printStackTrace();
1309 6079 leinfelder
            logMetacat.error("NumberFormat error while updating a mapping identifier: "
1310 5350 berkley
                    + e.getMessage());
1311
        } catch (AccessionNumberException e) {
1312
            e.printStackTrace();
1313 6079 leinfelder
            logMetacat.error("AccessionNumber error while updating a mapping identifier: "
1314 5350 berkley
                    + e.getMessage());
1315
        } finally {
1316
            // Return database connection to the pool
1317
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1318
        }
1319 6099 leinfelder
        logMetacat.debug("done updating mapping");
1320 5350 berkley
    }
1321 6099 leinfelder
1322
    private void updateSystemMetadataFields(long dateUploaded, String rightsHolder,
1323 6892 cjones
        String checksum, String checksumAlgorithm, String originMemberNode,
1324
        String authoritativeMemberNode, long modifiedDate, String submitter,
1325
        String guid, String objectFormat, BigInteger size, boolean archived,
1326
        boolean replicationAllowed, int numberReplicas, String obsoletes,
1327 9230 tao
        String obsoletedBy, BigInteger serialVersion, String seriesId,
1328
        String fileName, MediaType mediaType, DBConnection dbConn) throws SQLException  {
1329
        PreparedStatement stmt = null;
1330
        PreparedStatement stmt2 = null;
1331
        try {
1332
            dbConn.setAutoCommit(false);
1333
            // Execute the insert statement
1334
            String query = "update " + TYPE_SYSTEM_METADATA +
1335
                " set (date_uploaded, rights_holder, checksum, checksum_algorithm, " +
1336
                "origin_member_node, authoritive_member_node, date_modified, " +
1337
                "submitter, object_format, size, archived, replication_allowed, number_replicas, " +
1338 9231 tao
                "obsoletes, obsoleted_by, serial_version, series_id, file_name, media_type) " +
1339 9230 tao
                "= (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?,?) where guid = ?";
1340
            stmt = dbConn.prepareStatement(query);
1341
1342
            //data values
1343
            stmt.setTimestamp(1, new java.sql.Timestamp(dateUploaded));
1344
            stmt.setString(2, rightsHolder);
1345
            stmt.setString(3, checksum);
1346
            stmt.setString(4, checksumAlgorithm);
1347
            stmt.setString(5, originMemberNode);
1348
            stmt.setString(6, authoritativeMemberNode);
1349
            stmt.setTimestamp(7, new java.sql.Timestamp(modifiedDate));
1350
            stmt.setString(8, submitter);
1351
            stmt.setString(9, objectFormat);
1352
            stmt.setString(10, size.toString());
1353
            stmt.setBoolean(11, archived);
1354
            stmt.setBoolean(12, replicationAllowed);
1355
            stmt.setInt(13, numberReplicas);
1356
            stmt.setString(14, obsoletes);
1357
            stmt.setString(15, obsoletedBy);
1358 9342 tao
            if(serialVersion != null) {
1359
                stmt.setString(16, serialVersion.toString());
1360
            } else {
1361
                stmt.setString(16, null);
1362
            }
1363
1364 9230 tao
            stmt.setString(17, seriesId);
1365
            stmt.setString(18, fileName);
1366
            if (mediaType == null) {
1367
                stmt.setString(19, null);
1368
            } else {
1369
                stmt.setString(19, mediaType.getName());
1370
            }
1371
            //where clause
1372
            stmt.setString(20, guid);
1373
            logMetacat.debug("stmt: " + stmt.toString());
1374
            //execute
1375
            int rows = stmt.executeUpdate();
1376
1377
            //insert media type properties into another table
1378
            if(mediaType != null && mediaType.getPropertyList() != null) {
1379
                String sql2 = "insert into smmediatypeproperties " +
1380
                        "(guid, name, value) " + "values (?, ?, ?)";
1381
                stmt2 = dbConn.prepareStatement(sql2);
1382
                for(MediaTypeProperty item : mediaType.getPropertyList()) {
1383
                    if(item != null) {
1384
                        String name = item.getName();
1385
                        String value = item.getValue();
1386
                        stmt2.setString(1, guid);
1387
                        stmt2.setString(2, name);
1388
                        stmt2.setString(3, value);
1389
                        logMetacat.debug("insert media type properties query: " + stmt2.toString());
1390
                        int row =stmt2.executeUpdate();
1391
                    }
1392
1393
                }
1394
            }
1395
            dbConn.commit();
1396
            dbConn.setAutoCommit(true);
1397
        } catch (Exception e) {
1398
            dbConn.rollback();
1399
            dbConn.setAutoCommit(true);
1400 9342 tao
            e.printStackTrace();
1401 9230 tao
            throw new SQLException(e.getMessage());
1402
        } finally {
1403
            if(stmt != null) {
1404
                stmt.close();
1405
            }
1406
            if(stmt2 != null) {
1407
                stmt2.close();
1408
            }
1409
        }
1410 6892 cjones
1411 7188 leinfelder
1412
    }
1413
1414
    private void insertReplicationPolicy(String guid, String policy, List<String> memberNodes, DBConnection dbConn) throws SQLException
1415
    {
1416
1417
        // remove existing values first
1418 7392 leinfelder
        String delete = "delete from smReplicationPolicy " +
1419 7188 leinfelder
        "where guid = ? and policy = ?";
1420
        PreparedStatement stmt = dbConn.prepareStatement(delete);
1421
        //data values
1422
        stmt.setString(1, guid);
1423
        stmt.setString(2, policy);
1424
        //execute
1425
        int deletedCount = stmt.executeUpdate();
1426
        stmt.close();
1427 5957 berkley
1428 7188 leinfelder
        for (String memberNode: memberNodes) {
1429 5887 berkley
            // Execute the insert statement
1430 7392 leinfelder
            String insert = "insert into smReplicationPolicy " +
1431 7188 leinfelder
                "(guid, policy, member_node) " +
1432
                "values (?, ?, ?)";
1433
            PreparedStatement insertStatement = dbConn.prepareStatement(insert);
1434 5887 berkley
1435
            //data values
1436 7188 leinfelder
            insertStatement.setString(1, guid);
1437
            insertStatement.setString(2, policy);
1438
            insertStatement.setString(3, memberNode);
1439
1440 7392 leinfelder
            logMetacat.debug("smReplicationPolicy sql: " + insertStatement.toString());
1441 6375 leinfelder
1442 5887 berkley
            //execute
1443 7188 leinfelder
            int rows = insertStatement.executeUpdate();
1444
            insertStatement.close();
1445 5887 berkley
        }
1446 7188 leinfelder
1447 5887 berkley
    }
1448
1449 7188 leinfelder
    private void insertReplicationStatus(String guid, List<Replica> replicas, DBConnection dbConn) throws SQLException {
1450
1451
        // remove existing values first
1452 7392 leinfelder
        String delete = "delete from smReplicationStatus " +
1453 7188 leinfelder
        "where guid = ?";
1454
        PreparedStatement stmt = dbConn.prepareStatement(delete);
1455
        //data values
1456
        stmt.setString(1, guid);
1457
        //execute
1458
        int deletedCount = stmt.executeUpdate();
1459
        stmt.close();
1460 6107 leinfelder
1461 7188 leinfelder
        if (replicas != null) {
1462
            for (Replica replica: replicas) {
1463 6107 leinfelder
	            // Execute the insert statement
1464 7392 leinfelder
	            String insert = "insert into smReplicationStatus " +
1465 7188 leinfelder
	                "(guid, member_node, status, date_verified) " +
1466
	                "values (?, ?, ?, ?)";
1467 6107 leinfelder
	            PreparedStatement insertStatement = dbConn.prepareStatement(insert);
1468
1469
	            //data values
1470 7188 leinfelder
	            String memberNode = replica.getReplicaMemberNode().getValue();
1471
	            String status = replica.getReplicationStatus().toString();
1472 7399 cjones
	            java.sql.Timestamp sqlDate = new java.sql.Timestamp(replica.getReplicaVerified().getTime());
1473 6107 leinfelder
	            insertStatement.setString(1, guid);
1474 7188 leinfelder
	            insertStatement.setString(2, memberNode);
1475
	            insertStatement.setString(3, status);
1476 7399 cjones
	            insertStatement.setTimestamp(4, sqlDate);
1477 7188 leinfelder
1478 7392 leinfelder
	            logMetacat.debug("smReplicationStatus sql: " + insertStatement.toString());
1479 7102 leinfelder
1480 6107 leinfelder
	            //execute
1481
	            int rows = insertStatement.executeUpdate();
1482
	            insertStatement.close();
1483
            }
1484
        }
1485 7188 leinfelder
1486 6107 leinfelder
    }
1487
1488 5334 berkley
    /**
1489 5887 berkley
     * Insert the system metadata fields into the db
1490
     * @param sm
1491 6108 leinfelder
     * @throws McdbDocNotFoundException
1492 6892 cjones
     * @throws SQLException
1493 6904 cjones
     * @throws InvalidSystemMetadata
1494 7188 leinfelder
     * @throws AccessException
1495 5887 berkley
     */
1496 7188 leinfelder
    public void updateSystemMetadata(SystemMetadata sm, DBConnection dbConn)
1497
      throws McdbDocNotFoundException, SQLException, InvalidSystemMetadata, AccessException {
1498 6107 leinfelder
1499 6892 cjones
      Boolean replicationAllowed = false;
1500
		  Integer numberReplicas = -1;
1501 6107 leinfelder
    	ReplicationPolicy replicationPolicy = sm.getReplicationPolicy();
1502
    	if (replicationPolicy != null) {
1503
    		replicationAllowed = replicationPolicy.getReplicationAllowed();
1504
    		numberReplicas = replicationPolicy.getNumberReplicas();
1505
    		replicationAllowed = replicationAllowed == null ? false: replicationAllowed;
1506
    		numberReplicas = numberReplicas == null ? -1: numberReplicas;
1507
    	}
1508 6904 cjones
1509 6107 leinfelder
    	// the main systemMetadata fields
1510 6892 cjones
		  updateSystemMetadataFields(
1511 6311 leinfelder
				sm.getDateUploaded() == null ? null: sm.getDateUploaded().getTime(),
1512
				sm.getRightsHolder() == null ? null: sm.getRightsHolder().getValue(),
1513
				sm.getChecksum() == null ? null: sm.getChecksum().getValue(),
1514 6397 leinfelder
				sm.getChecksum() == null ? null: sm.getChecksum().getAlgorithm(),
1515 6311 leinfelder
				sm.getOriginMemberNode() == null ? null: sm.getOriginMemberNode().getValue(),
1516
				sm.getAuthoritativeMemberNode() == null ? null: sm.getAuthoritativeMemberNode().getValue(),
1517
				sm.getDateSysMetadataModified() == null ? null: sm.getDateSysMetadataModified().getTime(),
1518
				sm.getSubmitter() == null ? null: sm.getSubmitter().getValue(),
1519 6904 cjones
		    sm.getIdentifier().getValue(),
1520
		    sm.getFormatId() == null ? null: sm.getFormatId().getValue(),
1521
		    sm.getSize(),
1522
		    sm.getArchived() == null ? false: sm.getArchived(),
1523
		    replicationAllowed,
1524
		    numberReplicas,
1525
		    sm.getObsoletes() == null ? null:sm.getObsoletes().getValue(),
1526
		    sm.getObsoletedBy() == null ? null: sm.getObsoletedBy().getValue(),
1527 7188 leinfelder
		    sm.getSerialVersion(),
1528 8810 leinfelder
		    sm.getSeriesId() == null ? null: sm.getSeriesId().getValue(),
1529 9230 tao
		    sm.getFileName() == null ? null: sm.getFileName(),
1530
		    sm.getMediaType() == null ? null: sm.getMediaType(),
1531 7188 leinfelder
		    dbConn
1532 6561 leinfelder
        );
1533 6097 leinfelder
1534
        String guid = sm.getIdentifier().getValue();
1535
1536 6107 leinfelder
        // save replication policies
1537
        if (replicationPolicy != null) {
1538
		    List<String> nodes = null;
1539
		    String policy = null;
1540
1541 6494 leinfelder
		    // check for null
1542
		    if (replicationPolicy.getBlockedMemberNodeList() != null) {
1543
			    nodes = new ArrayList<String>();
1544
			    policy = "blocked";
1545
			    for (NodeReference node: replicationPolicy.getBlockedMemberNodeList()) {
1546
			    	nodes.add(node.getValue());
1547
			    }
1548 7188 leinfelder
			    this.insertReplicationPolicy(guid, policy, nodes, dbConn);
1549 6107 leinfelder
		    }
1550
1551 6494 leinfelder
		    if (replicationPolicy.getPreferredMemberNodeList() != null) {
1552
			    nodes = new ArrayList<String>();
1553
			    policy = "preferred";
1554
			    for (NodeReference node: replicationPolicy.getPreferredMemberNodeList()) {
1555
			    	nodes.add(node.getValue());
1556
			    }
1557 7188 leinfelder
		        this.insertReplicationPolicy(guid, policy, nodes, dbConn);
1558 6107 leinfelder
		    }
1559
        }
1560 6097 leinfelder
1561 6107 leinfelder
        // save replica information
1562 7188 leinfelder
        this.insertReplicationStatus(guid, sm.getReplicaList(), dbConn);
1563 6107 leinfelder
1564 6108 leinfelder
        // save access policy
1565
        AccessPolicy accessPolicy = sm.getAccessPolicy();
1566
        if (accessPolicy != null) {
1567 7188 leinfelder
			this.insertAccessPolicy(guid, accessPolicy);
1568 6108 leinfelder
        }
1569 5887 berkley
    }
1570
1571
    /**
1572 6108 leinfelder
     * Creates Metacat access rules and inserts them
1573
     * @param accessPolicy
1574
     * @throws McdbDocNotFoundException
1575
     * @throws AccessException
1576
     */
1577
    private void insertAccessPolicy(String guid, AccessPolicy accessPolicy) throws McdbDocNotFoundException, AccessException {
1578
1579 6744 leinfelder
    	// check for the existing permOrder so that we remain compatible with it (DataONE does not care)
1580
        XMLAccessAccess accessController  = new XMLAccessAccess();
1581
		String existingPermOrder = AccessControlInterface.ALLOWFIRST;
1582
        Vector<XMLAccessDAO> existingAccess = accessController.getXMLAccessForDoc(guid);
1583
        if (existingAccess != null && existingAccess.size() > 0) {
1584
        	existingPermOrder = existingAccess.get(0).getPermOrder();
1585
        }
1586
1587 6108 leinfelder
    	List<XMLAccessDAO> accessDAOs = new ArrayList<XMLAccessDAO>();
1588
        for (AccessRule accessRule: accessPolicy.getAllowList()) {
1589
        	List<Subject> subjects = accessRule.getSubjectList();
1590
        	List<Permission> permissions = accessRule.getPermissionList();
1591
        	for (Subject subject: subjects) {
1592 6122 leinfelder
    			XMLAccessDAO accessDAO = new XMLAccessDAO();
1593
        		accessDAO.setPrincipalName(subject.getValue());
1594
    			accessDAO.setGuid(guid);
1595
    			accessDAO.setPermType(AccessControlInterface.ALLOW);
1596 6744 leinfelder
				accessDAO.setPermOrder(existingPermOrder);
1597
    			if (permissions != null) {
1598
	    			for (Permission permission: permissions) {
1599
	    				Long metacatPermission = new Long(convertPermission(permission));
1600
	        			accessDAO.addPermission(metacatPermission);
1601
	    			}
1602 6122 leinfelder
    			}
1603
    			accessDAOs.add(accessDAO);
1604 6108 leinfelder
        	}
1605
        }
1606
1607
1608 6744 leinfelder
        // remove all existing allow records
1609
        accessController.deleteXMLAccessForDoc(guid, AccessControlInterface.ALLOW);
1610
        // add the ones we can for this guid
1611
        accessController.insertAccess(guid, accessDAOs);
1612 6108 leinfelder
1613 6744 leinfelder
1614 6108 leinfelder
    }
1615
1616
    /**
1617
     * Lookup access policy from Metacat
1618
     * @param guid
1619
     * @return
1620
     * @throws McdbDocNotFoundException
1621
     * @throws AccessException
1622
     */
1623 6720 leinfelder
    public AccessPolicy getAccessPolicy(String guid) throws McdbDocNotFoundException, AccessException {
1624 6450 leinfelder
        AccessPolicy accessPolicy = new AccessPolicy();
1625
1626 6122 leinfelder
    	// use GUID to look up the access
1627 6744 leinfelder
        XMLAccessAccess accessController  = new XMLAccessAccess();
1628 6720 leinfelder
        List<XMLAccessDAO> accessDAOs = accessController.getXMLAccessForDoc(guid);
1629
1630 6108 leinfelder
        for (XMLAccessDAO accessDAO: accessDAOs) {
1631 6744 leinfelder
        	// only add allow rule
1632
        	if (accessDAO.getPermType().equals(AccessControlInterface.ALLOW)) {
1633
	        	AccessRule accessRule = new AccessRule();
1634
	        	List <Permission> permissions = convertPermission(accessDAO.getPermission().intValue());
1635 7088 leinfelder
	        	// cannot include if we have no permissions
1636
	        	if (permissions == null || permissions.isEmpty()) {
1637
	        		logMetacat.warn("skipping empty access rule permissions for " + guid);
1638
	        		continue;
1639
	        	}
1640 6744 leinfelder
	        	accessRule.setPermissionList(permissions);
1641
	        	Subject subject = new Subject();
1642
	        	subject.setValue(accessDAO.getPrincipalName());
1643
	        	accessRule.addSubject(subject);
1644
	            accessPolicy.addAllow(accessRule);
1645
        	}
1646 6108 leinfelder
        }
1647
        return accessPolicy;
1648
    }
1649
1650
    public int convertPermission(Permission permission) {
1651
    	if (permission.equals(Permission.READ)) {
1652
    		return AccessControlInterface.READ;
1653
    	}
1654
    	if (permission.equals(Permission.WRITE)) {
1655
    		return AccessControlInterface.WRITE;
1656
    	}
1657
    	if (permission.equals(Permission.CHANGE_PERMISSION)) {
1658
    		return AccessControlInterface.CHMOD;
1659
    	}
1660
		return -1;
1661
    }
1662
1663 6722 leinfelder
    public List<Permission> convertPermission(int permission) {
1664 6744 leinfelder
1665 6722 leinfelder
    	List<Permission> permissions = new ArrayList<Permission>();
1666 6744 leinfelder
    	if (permission == AccessControlInterface.ALL) {
1667 6722 leinfelder
    		permissions.add(Permission.READ);
1668
    		permissions.add(Permission.WRITE);
1669 6744 leinfelder
    		permissions.add(Permission.CHANGE_PERMISSION);
1670 6722 leinfelder
    		return permissions;
1671 6108 leinfelder
    	}
1672 6744 leinfelder
1673
    	if ((permission & AccessControlInterface.CHMOD) == AccessControlInterface.CHMOD) {
1674 6722 leinfelder
    		permissions.add(Permission.CHANGE_PERMISSION);
1675 6108 leinfelder
    	}
1676 6744 leinfelder
    	if ((permission & AccessControlInterface.READ) == AccessControlInterface.READ) {
1677 6722 leinfelder
    		permissions.add(Permission.READ);
1678 6744 leinfelder
    	}
1679
    	if ((permission & AccessControlInterface.WRITE) == AccessControlInterface.WRITE) {
1680 6722 leinfelder
    		permissions.add(Permission.WRITE);
1681 6720 leinfelder
    	}
1682 6744 leinfelder
1683
		return permissions;
1684 6108 leinfelder
    }
1685
1686
    /**
1687 6099 leinfelder
     * Lookup a localId given the GUID. If
1688
     * the identifier is not found, throw an exception.
1689
     *
1690
     * @param guid the global identifier to look up
1691
     * @return String containing the corresponding LocalId
1692
     * @throws McdbDocNotFoundException if the identifier is not found
1693 5334 berkley
     */
1694 9024 tao
    public String getLocalId(String guid) throws McdbDocNotFoundException, SQLException {
1695 5334 berkley
1696
      String db_guid = "";
1697
      String docid = "";
1698
      int rev = 0;
1699
1700 6099 leinfelder
      String query = "select guid, docid, rev from " + TYPE_IDENTIFIER + " where guid = ?";
1701 5334 berkley
1702
      DBConnection dbConn = null;
1703 5333 berkley
      int serialNumber = -1;
1704 5334 berkley
      try {
1705
          // Get a database connection from the pool
1706
          dbConn = DBConnectionPool.getDBConnection("Identifier.getLocalId");
1707
          serialNumber = dbConn.getCheckOutSerialNumber();
1708
1709
          // Execute the insert statement
1710
          PreparedStatement stmt = dbConn.prepareStatement(query);
1711
          stmt.setString(1, guid);
1712
          ResultSet rs = stmt.executeQuery();
1713
          if (rs.next()) {
1714
              db_guid = rs.getString(1);
1715
              docid = rs.getString(2);
1716
              rev = rs.getInt(3);
1717
              assert(db_guid.equals(guid));
1718
          } else {
1719
              throw new McdbDocNotFoundException("Document not found:" + guid);
1720
          }
1721
          stmt.close();
1722
      } catch (SQLException e) {
1723
          logMetacat.error("Error while looking up the local identifier: "
1724
                  + e.getMessage());
1725 9024 tao
          throw e;
1726 5334 berkley
      } finally {
1727
          // Return database connection to the pool
1728
          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1729
      }
1730
      return docid + "." + rev;
1731
    }
1732
1733 5377 berkley
    /**
1734 5895 berkley
     * query the systemmetadata table based on the given parameters
1735
     * @param startTime
1736
     * @param endTime
1737
     * @param objectFormat
1738 9249 tao
     * @param nodeId
1739 5895 berkley
     * @param start
1740
     * @param count
1741
     * @return ObjectList
1742 6299 leinfelder
     * @throws SQLException
1743
     * @throws ServiceException
1744
     * @throws PropertyNotFoundException
1745 5895 berkley
     */
1746 6836 cjones
    public ObjectList querySystemMetadata(Date startTime, Date endTime,
1747 9249 tao
        ObjectFormatIdentifier objectFormatId, NodeReference nodeId,
1748 9072 tao
        int start, int count, Identifier identifier, boolean isSID)
1749 6836 cjones
        throws SQLException, PropertyNotFoundException, ServiceException {
1750 5895 berkley
        ObjectList ol = new ObjectList();
1751 5943 berkley
        DBConnection dbConn = null;
1752
        int serialNumber = -1;
1753 9307 tao
        PreparedStatement countStmt=null;
1754
        ResultSet totalResult=null;
1755
        PreparedStatement fieldStmt = null;
1756
        ResultSet rs= null;
1757 6836 cjones
1758 6299 leinfelder
        try {
1759 7452 leinfelder
            String fieldSql = "select guid, date_uploaded, rights_holder, checksum, "
1760 6836 cjones
                    + "checksum_algorithm, origin_member_node, authoritive_member_node, "
1761
                    + "date_modified, submitter, object_format, size from systemmetadata";
1762 7410 leinfelder
1763
            // handle special case quickly
1764
            String countSql = "select count(guid) from systemmetadata";
1765 7452 leinfelder
1766
            // the clause
1767
            String whereClauseSql = "";
1768 9307 tao
1769 6836 cjones
1770 5895 berkley
            boolean f1 = false;
1771
            boolean f2 = false;
1772
            boolean f3 = false;
1773 9072 tao
            boolean f4 = false;
1774 6836 cjones
1775 9072 tao
1776 6299 leinfelder
            if (startTime != null) {
1777 7452 leinfelder
                whereClauseSql += " where systemmetadata.date_modified >= ?";
1778 5895 berkley
                f1 = true;
1779
            }
1780 6836 cjones
1781 6299 leinfelder
            if (endTime != null) {
1782
                if (!f1) {
1783 7452 leinfelder
                    whereClauseSql += " where systemmetadata.date_modified < ?";
1784 6836 cjones
                } else {
1785 7452 leinfelder
                    whereClauseSql += " and systemmetadata.date_modified < ?";
1786 5917 berkley
                }
1787 5895 berkley
                f2 = true;
1788
            }
1789 6836 cjones
1790 6337 leinfelder
            if (objectFormatId != null) {
1791 6299 leinfelder
                if (!f1 && !f2) {
1792 7452 leinfelder
                    whereClauseSql += " where object_format = ?";
1793 6836 cjones
                } else {
1794 7452 leinfelder
                    whereClauseSql += " and object_format = ?";
1795 5917 berkley
                }
1796 5895 berkley
                f3 = true;
1797
            }
1798 9072 tao
1799
            if(identifier != null && identifier.getValue() != null && !identifier.getValue().equals("")) {
1800
                if (!f1 && !f2 && !f3 ) {
1801
                    if(isSID) {
1802
                        whereClauseSql += " where series_id = ?";
1803
                    } else {
1804
                        whereClauseSql += " where guid = ?";
1805
                    }
1806
1807
                } else {
1808
                    if(isSID) {
1809
                        whereClauseSql += " and series_id = ?";
1810
                    } else {
1811
                        whereClauseSql += " and guid = ?";
1812
                    }
1813
                }
1814
                f4 = true;
1815
            }
1816 6836 cjones
1817 9249 tao
            /*if (!replicaStatus) {
1818 7030 cjones
                String currentNodeId = PropertyService.getInstance().getProperty("dataone.nodeId");
1819 9072 tao
                if (!f1 && !f2 && !f3 && !f4) {
1820 7462 leinfelder
                    whereClauseSql += " where authoritive_member_node = '" +
1821 6836 cjones
                        currentNodeId.trim() + "'";
1822
                } else {
1823 7462 leinfelder
                    whereClauseSql += " and authoritive_member_node = '" +
1824 6836 cjones
                        currentNodeId.trim() + "'";
1825 5917 berkley
                }
1826 9249 tao
            }*/
1827
1828
            if (nodeId != null && nodeId.getValue() != null && !nodeId.getValue().trim().equals("")) {
1829
                if (!f1 && !f2 && !f3 && !f4) {
1830
                    whereClauseSql += " where authoritive_member_node = '" +
1831
                        nodeId.getValue().trim() + "'";
1832
                } else {
1833
                    whereClauseSql += " and authoritive_member_node = '" +
1834
                        nodeId.getValue().trim() + "'";
1835
                }
1836 5895 berkley
            }
1837 9072 tao
1838
1839 7452 leinfelder
            // connection
1840 5943 berkley
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.querySystemMetadata");
1841
            serialNumber = dbConn.getCheckOutSerialNumber();
1842 6836 cjones
1843 7452 leinfelder
            // the field query
1844
            String orderBySql = " order by guid ";
1845
            String fieldQuery = fieldSql + whereClauseSql + orderBySql;
1846
            String finalQuery = DatabaseService.getInstance().getDBAdapter().getPagedQuery(fieldQuery, start, count);
1847 9307 tao
            fieldStmt = dbConn.prepareStatement(finalQuery);
1848 7452 leinfelder
1849
            // construct the count query and statment
1850
            String countQuery = countSql + whereClauseSql;
1851 9307 tao
            countStmt = dbConn.prepareStatement(countQuery);
1852 7452 leinfelder
1853 9072 tao
            if (f1 && f2 && f3 && f4) {
1854 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1855
                fieldStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1856
                fieldStmt.setString(3, objectFormatId.getValue());
1857 9072 tao
                fieldStmt.setString(4, identifier.getValue());
1858 7452 leinfelder
                // count
1859
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1860
                countStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1861
                countStmt.setString(3, objectFormatId.getValue());
1862 9072 tao
                countStmt.setString(4, identifier.getValue());
1863
            } if (f1 && f2 && f3 && !f4) {
1864 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1865
                fieldStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1866 9072 tao
                fieldStmt.setString(3, objectFormatId.getValue());
1867 7452 leinfelder
                // count
1868
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1869
                countStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1870 9072 tao
                countStmt.setString(3, objectFormatId.getValue());
1871
            } else if (f1 && f2 && !f3 && f4) {
1872 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1873 9072 tao
                fieldStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1874
                fieldStmt.setString(3, identifier.getValue());
1875
                // count
1876
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1877
                countStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1878
                countStmt.setString(3, identifier.getValue());
1879
            } else if (f1 && f2 && !f3 && !f4) {
1880
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1881
                fieldStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1882
                // count
1883
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1884
                countStmt.setTimestamp(2, new Timestamp(endTime.getTime()));
1885
            } else if (f1 && !f2 && f3 && f4) {
1886
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1887 7452 leinfelder
                fieldStmt.setString(2, objectFormatId.getValue());
1888 9072 tao
                fieldStmt.setString(3, identifier.getValue());
1889 7452 leinfelder
                // count
1890
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1891
                countStmt.setString(2, objectFormatId.getValue());
1892 9072 tao
                countStmt.setString(3, identifier.getValue());
1893
            } else if (f1 && !f2 && f3 && !f4) {
1894 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1895 9072 tao
                fieldStmt.setString(2, objectFormatId.getValue());
1896 7452 leinfelder
                // count
1897
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1898 9072 tao
                countStmt.setString(2, objectFormatId.getValue());
1899
            } else if (f1 && !f2 && !f3 && f4) {
1900
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1901
                fieldStmt.setString(2, identifier.getValue());
1902
                // count
1903
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1904
                countStmt.setString(2, identifier.getValue());
1905
            } else if (f1 && !f2 && !f3 && !f4) {
1906
                fieldStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1907
                // count
1908
                countStmt.setTimestamp(1, new Timestamp(startTime.getTime()));
1909
            } else if (!f1 && f2 && f3 && f4) {
1910 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1911
                fieldStmt.setString(2, objectFormatId.getValue());
1912 9072 tao
                fieldStmt.setString(3, identifier.getValue());
1913 7452 leinfelder
                // count
1914
                countStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1915
                countStmt.setString(2, objectFormatId.getValue());
1916 9072 tao
                countStmt.setString(3, identifier.getValue());
1917
            } else if (!f1 && f2 && f3 && !f4) {
1918
                fieldStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1919
                fieldStmt.setString(2, objectFormatId.getValue());
1920
                // count
1921
                countStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1922
                countStmt.setString(2, objectFormatId.getValue());
1923
            } else if (!f1 && !f2 && f3 && f4) {
1924 7452 leinfelder
                fieldStmt.setString(1, objectFormatId.getValue());
1925 9072 tao
                fieldStmt.setString(2, identifier.getValue());
1926 7452 leinfelder
                // count
1927
                countStmt.setString(1, objectFormatId.getValue());
1928 9072 tao
                countStmt.setString(2, identifier.getValue());
1929
            } else if (!f1 && !f2 && f3 && !f4) {
1930
                fieldStmt.setString(1, objectFormatId.getValue());
1931
                // count
1932
                countStmt.setString(1, objectFormatId.getValue());
1933
            } else if (!f1 && f2 && !f3 && f4) {
1934 7452 leinfelder
                fieldStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1935 9072 tao
                fieldStmt.setString(2, identifier.getValue());
1936 7452 leinfelder
                // count
1937
                countStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1938 9072 tao
                countStmt.setString(2, identifier.getValue());
1939
            } else if (!f1 && f2 && !f3 && !f4) {
1940
                fieldStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1941
                // count
1942
                countStmt.setTimestamp(1, new Timestamp(endTime.getTime()));
1943
            } else if (!f1 && !f2 && !f3 && f4) {
1944
                fieldStmt.setString(1, identifier.getValue());
1945
                // count
1946
                countStmt.setString(1, identifier.getValue());
1947
            } else if (!f1 && !f2 && !f3 && !f4) {
1948
                //do nothing
1949 5895 berkley
            }
1950 6836 cjones
1951 7461 leinfelder
            logMetacat.debug("list objects fieldStmt: " + fieldStmt.toString());
1952
1953
            logMetacat.debug("list objects countStmt: " + countStmt.toString());
1954
1955 7452 leinfelder
            // get the total object count no matter what
1956
            int total = 0;
1957 9307 tao
            totalResult = countStmt.executeQuery();
1958 7452 leinfelder
            if (totalResult.next()) {
1959
            	total = totalResult.getInt(1);
1960 5895 berkley
            }
1961 7438 leinfelder
1962 7461 leinfelder
            logMetacat.debug("list objects total: " + total);
1963
1964 7452 leinfelder
        	// set the totals
1965
        	ol.setStart(start);
1966
            ol.setCount(count);
1967
1968
            // retrieve the actual records if requested
1969
            if (count != 0) {
1970
1971 9307 tao
                rs = fieldStmt.executeQuery();
1972 7410 leinfelder
	            while (rs.next()) {
1973 7438 leinfelder
1974 7410 leinfelder
	                String guid = rs.getString(1);
1975 7461 leinfelder
	                logMetacat.debug("query found object with guid " + guid);
1976 7410 leinfelder
	                // Timestamp dateUploaded = rs.getTimestamp(2);
1977
	                // String rightsHolder = rs.getString(3);
1978
	                String checksum = rs.getString(4);
1979
	                String checksumAlgorithm = rs.getString(5);
1980
	                // String originMemberNode = rs.getString(6);
1981
	                // String authoritiveMemberNode = rs.getString(7);
1982
	                Timestamp dateModified = rs.getTimestamp(8);
1983
	                // String submitter = rs.getString(9);
1984
	                String fmtidStr = rs.getString(10);
1985
	                String sz = rs.getString(11);
1986
	                BigInteger size = new BigInteger("0");
1987
1988
	                if (sz != null && !sz.trim().equals("")) {
1989
	                    size = new BigInteger(rs.getString(11));
1990
	                }
1991
1992
	                ObjectInfo oi = new ObjectInfo();
1993
1994
	                Identifier id = new Identifier();
1995
	                id.setValue(guid);
1996
	                oi.setIdentifier(id);
1997
1998
	                if (dateModified != null) {
1999
	                    oi.setDateSysMetadataModified(dateModified);
2000
	                }
2001
2002
	                Checksum cs = new Checksum();
2003
	                cs.setValue(checksum);
2004
	                try {
2005
	                    // cs.setAlgorithm(ChecksumAlgorithm.valueOf(checksumAlgorithm));
2006
	                    cs.setAlgorithm(checksumAlgorithm);
2007
	                } catch (Exception e) {
2008
	                    logMetacat.error("could not parse checksum algorithm", e);
2009
	                    continue;
2010
	                }
2011
	                oi.setChecksum(cs);
2012
2013
	                // set the format type
2014
	                ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
2015
	                fmtid.setValue(fmtidStr);
2016
	                oi.setFormatId(fmtid);
2017
2018
	                oi.setSize(size);
2019 9307 tao
2020 7438 leinfelder
	                ol.addObjectInfo(oi);
2021
2022 7410 leinfelder
	            }
2023 7452 leinfelder
2024 7461 leinfelder
	            logMetacat.debug("list objects count: " + ol.sizeObjectInfoList());
2025 7452 leinfelder
	            // set the actual count retrieved
2026
	            ol.setCount(ol.sizeObjectInfoList());
2027 9308 tao
2028 7410 leinfelder
2029
	        }
2030 9308 tao
            ol.setTotal(total);
2031 9307 tao
        } finally {
2032 5943 berkley
            // Return database connection to the pool
2033 9307 tao
            try {
2034
                if(totalResult !=null ){
2035
                    totalResult.close();
2036
                }
2037
                if(countStmt!=null ) {
2038
                    countStmt.close();
2039
                }
2040
                if(rs != null) {
2041
                    rs.close();
2042
                }
2043
                if(fieldStmt != null) {
2044
                    fieldStmt.close();
2045
                }
2046
2047
            } catch (SQLException sql) {
2048
2049
            }
2050 5943 berkley
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2051 9307 tao
2052 5943 berkley
        }
2053 9307 tao
        if(ol != null) {
2054
            logMetacat.debug("list objects start(before returning): " + ol.getStart());
2055
            logMetacat.debug("list objects count: " + ol.getCount());
2056
            logMetacat.debug("list objects total: " + ol.getTotal());
2057
        }
2058 5895 berkley
        return ol;
2059
    }
2060
2061
    /**
2062 6099 leinfelder
     * create a mapping in the identifier table
2063 5377 berkley
     * @param guid
2064
     * @param localId
2065
     */
2066 6099 leinfelder
    public void createMapping(String guid, String localId)
2067 5453 berkley
    {
2068 5334 berkley
2069
        int serialNumber = -1;
2070 5333 berkley
        DBConnection dbConn = null;
2071
        try {
2072
2073
            // Parse the localId into scope and rev parts
2074
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
2075
            String docid = acc.getDocid();
2076 5344 berkley
            int rev = 1;
2077 6099 leinfelder
            if (acc.getRev() != null) {
2078 5344 berkley
              rev = (new Integer(acc.getRev()).intValue());
2079
            }
2080 5333 berkley
2081
            // Get a database connection from the pool
2082 6099 leinfelder
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.createMapping");
2083 5333 berkley
            serialNumber = dbConn.getCheckOutSerialNumber();
2084
2085
            // Execute the insert statement
2086 6099 leinfelder
            String query = "insert into " + TYPE_IDENTIFIER + " (guid, docid, rev) values (?, ?, ?)";
2087 5333 berkley
            PreparedStatement stmt = dbConn.prepareStatement(query);
2088
            stmt.setString(1, guid);
2089
            stmt.setString(2, docid);
2090
            stmt.setInt(3, rev);
2091 6099 leinfelder
            logMetacat.debug("mapping query: " + stmt.toString());
2092 5333 berkley
            int rows = stmt.executeUpdate();
2093
2094
            stmt.close();
2095
        } catch (SQLException e) {
2096 5344 berkley
            e.printStackTrace();
2097 6099 leinfelder
            logMetacat.error("createGenericMapping: SQL error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
2098 5333 berkley
                    + e.getMessage());
2099
        } catch (NumberFormatException e) {
2100 5344 berkley
            e.printStackTrace();
2101 6099 leinfelder
            logMetacat.error("createGenericMapping: NumberFormat error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
2102 5333 berkley
                    + e.getMessage());
2103
        } catch (AccessionNumberException e) {
2104 5344 berkley
            e.printStackTrace();
2105 6099 leinfelder
            logMetacat.error("createGenericMapping: AccessionNumber error while creating a mapping to the " + TYPE_IDENTIFIER + " identifier: "
2106 5333 berkley
                    + e.getMessage());
2107
        } finally {
2108
            // Return database connection to the pool
2109
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2110
        }
2111
    }
2112 6099 leinfelder
2113
    /**
2114 7017 leinfelder
     * remove a mapping in the identifier table
2115
     * @param guid
2116
     * @param localId
2117
     */
2118
    public void removeMapping(String guid, String localId)
2119
    {
2120
2121
        int serialNumber = -1;
2122
        DBConnection dbConn = null;
2123
        try {
2124
2125
            // Parse the localId into scope and rev parts
2126
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
2127
            String docid = acc.getDocid();
2128
            int rev = 1;
2129
            if (acc.getRev() != null) {
2130
              rev = (new Integer(acc.getRev()).intValue());
2131
            }
2132
2133
            // Get a database connection from the pool
2134
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.removeMapping");
2135
            serialNumber = dbConn.getCheckOutSerialNumber();
2136
2137
            // Execute the insert statement
2138
            String query = "DELETE FROM " + TYPE_IDENTIFIER + " WHERE guid = ? AND docid = ? AND rev = ?";
2139
            PreparedStatement stmt = dbConn.prepareStatement(query);
2140
            stmt.setString(1, guid);
2141
            stmt.setString(2, docid);
2142
            stmt.setInt(3, rev);
2143
            logMetacat.debug("remove mapping query: " + stmt.toString());
2144
            int rows = stmt.executeUpdate();
2145
2146
            stmt.close();
2147
        } catch (SQLException e) {
2148
            e.printStackTrace();
2149
            logMetacat.error("removeMapping: SQL error while removing a mapping to the " + TYPE_IDENTIFIER + " identifier: "
2150
                    + e.getMessage());
2151
        } catch (NumberFormatException e) {
2152
            e.printStackTrace();
2153
            logMetacat.error("removeMapping: NumberFormat error while removing a mapping to the " + TYPE_IDENTIFIER + " identifier: "
2154
                    + e.getMessage());
2155
        } catch (AccessionNumberException e) {
2156
            e.printStackTrace();
2157
            logMetacat.error("removeMapping: AccessionNumber error while removing a mapping to the " + TYPE_IDENTIFIER + " identifier: "
2158
                    + e.getMessage());
2159
        } finally {
2160
            // Return database connection to the pool
2161
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2162
        }
2163
    }
2164
2165
    /**
2166 6099 leinfelder
     * create the systemmetadata record
2167
     * @param guid
2168 7188 leinfelder
     * @param dbConn
2169
     * @throws SQLException
2170 6099 leinfelder
     */
2171 7188 leinfelder
    private void insertSystemMetadata(String guid, DBConnection dbConn) throws SQLException
2172 6099 leinfelder
    {
2173
2174 7188 leinfelder
        // Execute the insert statement
2175
        String query = "insert into " + TYPE_SYSTEM_METADATA + " (guid) values (?)";
2176
        PreparedStatement stmt = dbConn.prepareStatement(query);
2177
        stmt.setString(1, guid);
2178
        logMetacat.debug("system metadata query: " + stmt.toString());
2179
        int rows = stmt.executeUpdate();
2180 6099 leinfelder
2181 7188 leinfelder
        stmt.close();
2182
2183 6099 leinfelder
    }
2184 6277 leinfelder
2185 8852 tao
    public boolean deleteSystemMetadata(String guid)
2186 6277 leinfelder
    {
2187 8852 tao
        boolean success = false;
2188 6277 leinfelder
        int serialNumber = -1;
2189
        DBConnection dbConn = null;
2190 6648 leinfelder
        String query = null;
2191
        PreparedStatement stmt = null;
2192
        int rows = 0;
2193 6277 leinfelder
        try {
2194
2195 8852 tao
        	 // Get a database connection from the pool
2196 6648 leinfelder
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.deleteSystemMetadata");
2197 6277 leinfelder
            serialNumber = dbConn.getCheckOutSerialNumber();
2198 8852 tao
            dbConn.setAutoCommit(false);
2199
2200 7392 leinfelder
            // remove the smReplicationPolicy
2201
            query = "delete from smReplicationPolicy " +
2202 6648 leinfelder
            "where guid = ?";
2203
            stmt = dbConn.prepareStatement(query);
2204
            stmt.setString(1, guid);
2205 7392 leinfelder
            logMetacat.debug("delete smReplicationPolicy: " + stmt.toString());
2206 6648 leinfelder
            rows = stmt.executeUpdate();
2207
            stmt.close();
2208
2209 7392 leinfelder
            // remove the smReplicationStatus
2210
            query = "delete from smReplicationStatus " +
2211 6648 leinfelder
            "where guid = ?";
2212
            stmt = dbConn.prepareStatement(query);
2213
            stmt.setString(1, guid);
2214 7392 leinfelder
            logMetacat.debug("delete smReplicationStatus: " + stmt.toString());
2215 6648 leinfelder
            rows = stmt.executeUpdate();
2216
            stmt.close();
2217
2218 9230 tao
            // remove the smmediatypeproperties
2219
            query = "delete from smmediatypeproperties " +
2220
                    "where guid = ?";
2221
            stmt = dbConn.prepareStatement(query);
2222
            stmt.setString(1, guid);
2223
            logMetacat.debug("delete smmediatypeproperties: " + stmt.toString());
2224
            rows = stmt.executeUpdate();
2225
            stmt.close();
2226
2227 8852 tao
            // remove main system metadata entry
2228
            query = "delete from " + TYPE_SYSTEM_METADATA + " where guid = ? ";
2229
            stmt = dbConn.prepareStatement(query);
2230
            stmt.setString(1, guid);
2231
            logMetacat.debug("delete system metadata: " + stmt.toString());
2232
            rows = stmt.executeUpdate();
2233
            stmt.close();
2234
2235
            dbConn.commit();
2236
            dbConn.setAutoCommit(true);
2237
            success = true;
2238 6744 leinfelder
            // TODO: remove the access?
2239 6648 leinfelder
            // Metacat keeps "deleted" documents so we should not remove access rules.
2240
2241 6277 leinfelder
        } catch (Exception e) {
2242
            e.printStackTrace();
2243
            logMetacat.error("Error while deleting " + TYPE_SYSTEM_METADATA + " record: " + guid, e );
2244 6648 leinfelder
            try {
2245
				dbConn.rollback();
2246
			} catch (SQLException sqle) {
2247
	            logMetacat.error("Error while rolling back delete for record: " + guid, sqle );
2248
			}
2249 6277 leinfelder
        } finally {
2250
            // Return database connection to the pool
2251
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2252
        }
2253 8852 tao
        return success;
2254 6277 leinfelder
    }
2255 6862 leinfelder
2256
    public void updateAuthoritativeMemberNodeId(String existingMemberNodeId, String newMemberNodeId)
2257
    {
2258
        DBConnection dbConn = null;
2259
        int serialNumber = -1;
2260
2261
        try {
2262
            // Get a database connection from the pool
2263
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.updateAuthoritativeMemberNodeId");
2264
            serialNumber = dbConn.getCheckOutSerialNumber();
2265
2266
            // Execute the insert statement
2267
            String query = "update " + TYPE_SYSTEM_METADATA +
2268
                " set authoritive_member_node = ? " +
2269
                " where authoritive_member_node = ?";
2270
            PreparedStatement stmt = dbConn.prepareStatement(query);
2271
2272
            //data values
2273
            stmt.setString(1, newMemberNodeId);
2274
            stmt.setString(2, existingMemberNodeId);
2275
2276
            logMetacat.debug("stmt: " + stmt.toString());
2277
            //execute
2278
            int rows = stmt.executeUpdate();
2279
2280
            stmt.close();
2281
        } catch (SQLException e) {
2282
            e.printStackTrace();
2283
            logMetacat.error("updateSystemMetadataFields: SQL error while updating system metadata: "
2284
                    + e.getMessage());
2285
        } catch (NumberFormatException e) {
2286
            e.printStackTrace();
2287
            logMetacat.error("updateSystemMetadataFields: NumberFormat error while updating system metadata: "
2288
                    + e.getMessage());
2289
        } finally {
2290
            // Return database connection to the pool
2291
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2292
        }
2293
    }
2294 5282 jones
}