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