Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2010 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author: jones $'
7
 *     '$Date: 2010-02-03 17:58:12 -0900 (Wed, 03 Feb 2010) $'
8
 * '$Revision: 5211 $'
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 */
24

    
25
package edu.ucsb.nceas.metacat;
26

    
27
import java.util.*;
28

    
29
import java.sql.PreparedStatement;
30
import java.sql.ResultSet;
31
import java.sql.SQLException;
32

    
33
import org.apache.log4j.Logger;
34
import org.dataone.service.types.SystemMetadata;
35

    
36
import edu.ucsb.nceas.metacat.database.DBConnection;
37
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
38
import edu.ucsb.nceas.metacat.properties.PropertyService;
39
import edu.ucsb.nceas.metacat.util.DocumentUtil;
40

    
41
/**
42
 * Manage the relationship between Metacat local identifiers (LocalIDs) that are
43
 * codified as the (docid, rev) pair with globally uniqe string identifiers
44
 * (GUIDs) that are opaque strings.  This class provides methods to manage these
45
 * identifiers, and to search for and look up LocalIDs based on their GUID and
46
 * vice versa. IdentifierManager is a singleton.
47
 * 
48
 * @author Matthew Jones
49
 */
50
public class IdentifierManager {
51
    
52
    public static final String TYPE_SYSTEM_METADATA = "systemmetadata";
53
    public static final String TYPE_IDENTIFIER = "identifier";
54
    public static String DATAONE_SM_DOCTYPE;
55
  
56
    /**
57
     * The single instance of the manager that is always returned.
58
     */
59
    private static IdentifierManager self = null;
60
    private Logger logMetacat = Logger.getLogger(EventLog.class);
61

    
62
    /**
63
     * A private constructor that initializes the class when getInstance() is
64
     * called.
65
     */
66
    private IdentifierManager()
67
    {
68
        try
69
        {
70
            DATAONE_SM_DOCTYPE = PropertyService.getProperty("crudService.listObjects.ReturnDoctype");
71
        }
72
        catch(Exception e)
73
        {
74
            throw new RuntimeException("Error getting System Metadata doctype from " + 
75
                    "the properties file.  Please make sure crudService.listObjects.ReturnDoctype " +
76
                    "exists in metacat.properties.");
77
        }
78
    }
79

    
80
    /**
81
     * Return the single instance of the manager after initializing it if it
82
     * wasn't previously initialized.
83
     * 
84
     * @return the single IdentifierManager instance
85
     */
86
    public static IdentifierManager getInstance()
87
    {
88
        if (self == null) {
89
            self = new IdentifierManager();
90
        }
91
        return self;
92
    }
93
    
94
    /**
95
     * return information on the document with localId.  These are the fields
96
     * from the xml_documents table.  They can be used to contstruct metadata 
97
     * about the object that is stored.
98
     * @param localId
99
     * @return
100
     * @throws McdbDocNotFoundException
101
     */
102
    public Hashtable<String, Object> getDocumentInfo(String localId)
103
        throws McdbDocNotFoundException
104
    {
105
        try
106
        {
107
            AccessionNumber acc = new AccessionNumber(localId, "NONE");
108
            localId = acc.getDocid();
109
        }
110
        catch(Exception e)
111
        {
112
            //do nothing. just try the localId as it is
113
        }
114
        Hashtable<String, Object> h = new Hashtable<String, Object>();
115
        String sql = "select docname, doctype, user_owner, user_updated, " +
116
            "server_location, rev, date_created, date_updated from " + 
117
            "xml_documents where docid like '" + localId + "'";
118
        DBConnection dbConn = null;
119
        int serialNumber = -1;
120
        try 
121
        {
122
            // Get a database connection from the pool
123
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getDocumentInfo");
124
            serialNumber = dbConn.getCheckOutSerialNumber();
125

    
126
            // Execute the insert statement
127
            PreparedStatement stmt = dbConn.prepareStatement(sql);
128
            ResultSet rs = stmt.executeQuery();
129
            if (rs.next()) 
130
            {
131
                String docname = rs.getString(1);
132
                String doctype = rs.getString(2);
133
                String user_owner = rs.getString(3);
134
                String user_updated = rs.getString(4);
135
                String server_location = rs.getString(5);
136
                int rev = rs.getInt(6);
137
                String date_created = rs.getString(7);
138
                String date_updated = rs.getString(8);
139
                h.put("docname", docname);
140
                h.put("doctype", doctype);
141
                h.put("user_owner", user_owner);
142
                h.put("user_updated", user_updated);
143
                h.put("server_location", server_location);
144
                h.put("rev", new Integer(rev).toString());
145
                h.put("date_created", date_created);
146
                h.put("date_updated", date_updated);
147
                
148
                stmt.close();
149
            } 
150
            else
151
            {
152
                stmt.close();
153
                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
154
                throw new McdbDocNotFoundException("2Could not find document " + localId);
155
            }
156
            
157
            String sql2 = "select principal_name, permission, perm_type, perm_order from xml_access " +
158
            "where docid like '" + localId + "'";
159
            System.out.println("executing sql: " + sql2);
160
            PreparedStatement stmt2 = dbConn.prepareStatement(sql2);
161
            rs = stmt2.executeQuery();
162
            Vector accessVector = new Vector();
163
            while(rs.next())
164
            {
165
                Hashtable accessHash = new Hashtable();
166
                String principal_name = rs.getString(1);
167
                String permission = rs.getString(2);
168
                String permissionType = rs.getString(3);
169
                String permissionOrder = rs.getString(4);
170
                accessHash.put("principal_name", principal_name);
171
                accessHash.put("permission", permission);
172
                accessHash.put("permission_type", permissionType);
173
                accessHash.put("permission_order", permissionOrder);
174
                System.out.println("accessHash: " + accessHash.toString());
175
                accessVector.add(accessHash);
176
            }
177
            h.put("access", accessVector);
178
        } 
179
        catch (SQLException e) 
180
        {
181
            e.printStackTrace();
182
            logMetacat.error("Error while getting document info for localid " + localId + " : "  
183
                    + e.getMessage());
184
        } 
185
        finally 
186
        {
187
            // Return database connection to the pool
188
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
189
        }
190
        return h;
191
    }
192
    
193
    /**
194
     * return the newest rev for a given localId
195
     * @param localId
196
     * @return
197
     */
198
    public int getLatestRevForLocalId(String localId)
199
        throws McdbDocNotFoundException
200
    {
201
        try
202
        {
203
            AccessionNumber acc = new AccessionNumber(localId, "NONE");
204
            localId = acc.getDocid();
205
        }
206
        catch(Exception e)
207
        {
208
            //do nothing. just try the localId as it is
209
        }
210
        int rev = 0;
211
        String sql = "select rev from xml_documents where docid like '" + localId + "'";
212
        DBConnection dbConn = null;
213
        int serialNumber = -1;
214
        try 
215
        {
216
            // Get a database connection from the pool
217
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getLatestRevForLocalId");
218
            serialNumber = dbConn.getCheckOutSerialNumber();
219

    
220
            // Execute the insert statement
221
            PreparedStatement stmt = dbConn.prepareStatement(sql);
222
            ResultSet rs = stmt.executeQuery();
223
            if (rs.next()) 
224
            {
225
                rev = rs.getInt(1);
226
                stmt.close();
227
            } 
228
            else
229
            {
230
                stmt.close();
231
                DBConnectionPool.returnDBConnection(dbConn, serialNumber);
232
                throw new McdbDocNotFoundException("While trying to get the latest rev, could not find document " + localId);
233
            }
234
        } 
235
        catch (SQLException e) 
236
        {
237
            logMetacat.error("Error while looking up the guid: " 
238
                    + e.getMessage());
239
        } 
240
        finally 
241
        {
242
            // Return database connection to the pool
243
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
244
        }
245
        return rev;
246
    }
247
    
248
    /**
249
     * return all local ids in the object store that do not have associated
250
     * system metadata and are not themselves system metadata
251
     */
252
    public List<String> getLocalIdsWithNoSystemMetadata()
253
    {
254
        Vector<String> ids = new Vector<String>();
255
        //String sql = "select docid from identifier where guid in (select guid from systemmetadata)"; 
256
        //String sql = "select docid from xml_documents where docid not " +
257
        //    "in (select docid from identifier where guid in (select guid from systemmetadata)) " +
258
        //    "and doctype not like '" + DATAONE_SM_DOCTYPE + "'";
259
        String sql = "select docid, rev from xml_documents where docid not in " +
260
            "(select docid from systemmetadata) and (docid not in " +
261
            "(select docid from identifier where guid in (select guid from systemmetadata)))";
262
        DBConnection dbConn = null;
263
        int serialNumber = -1;
264
        try 
265
        {
266
            // Get a database connection from the pool
267
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getLocalIdsWithNoSystemMetadata");
268
            serialNumber = dbConn.getCheckOutSerialNumber();
269

    
270
            // Execute the insert statement
271
            PreparedStatement stmt = dbConn.prepareStatement(sql);
272
            ResultSet rs = stmt.executeQuery();
273
            while (rs.next()) 
274
            {
275
                String localid = rs.getString(1);
276
                String rev = rs.getString(2);
277
                localid += "." + rev;
278
                System.out.println("id to add SM for: " + localid);
279
                ids.add(localid);
280
            } 
281
            stmt.close();
282
        } 
283
        catch (SQLException e) 
284
        {
285
            logMetacat.error("Error while looking up the guid: " 
286
                    + e.getMessage());
287
        } 
288
        finally 
289
        {
290
            // Return database connection to the pool
291
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
292
        }
293
        
294
        return ids;
295
    }
296
    
297
    /**
298
     * return a listing of all local ids in the object store
299
     * @return a list of all local ids in metacat
300
     */
301
    public List<String> getAllLocalIds()
302
       throws Exception
303
    {
304
        Vector<String> ids = new Vector<String>();
305
        String sql = "select docid from xml_documents";
306
        DBConnection dbConn = null;
307
        int serialNumber = -1;
308
        try 
309
        {
310
            // Get a database connection from the pool
311
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getAllLocalIds");
312
            serialNumber = dbConn.getCheckOutSerialNumber();
313

    
314
            // Execute the insert statement
315
            PreparedStatement stmt = dbConn.prepareStatement(sql);
316
            ResultSet rs = stmt.executeQuery();
317
            while (rs.next()) 
318
            {
319
                String localid = rs.getString(1);
320
                ids.add(localid);
321
            } 
322
            stmt.close();
323
        } 
324
        catch (SQLException e) 
325
        {
326
            logMetacat.error("Error while looking up the guid: " 
327
                    + e.getMessage());
328
        } 
329
        finally 
330
        {
331
            // Return database connection to the pool
332
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
333
        }
334
        return ids;
335
    }
336
    
337
    /**
338
     * Lookup a GUID from the database, and return the associated LocalID. If
339
     * the identifier is not found, throw an exception.
340
     * 
341
     * @param guid the global identifier to look up
342
     * @return String containing the corresponding LocalId
343
     * @throws McdbDocNotFoundException if the identifier is not found
344
     */
345
    public String getLocalId(String guid) throws McdbDocNotFoundException
346
    {
347
        return this.getLocalId(guid, TYPE_IDENTIFIER);
348
    }
349
    
350
    /**
351
     * Determine if an identifier exists already, returning true if so.
352
     * 
353
     * @param guid the global identifier to look up
354
     * @return boolean true if the identifier exists
355
     */
356
    public boolean identifierExists(String guid)
357
    {
358
        boolean idExists = false;
359
        try {
360
            String id = getLocalId(guid);
361
            if (id != null) {
362
                idExists = true;
363
            }
364
        } catch (McdbDocNotFoundException e) {
365
            idExists = false;
366
        }
367
        return idExists;
368
    }
369
    
370
    /**
371
     * Create a mapping between two identifiers, one representing an 
372
     * unconstrained, globally unique string (guid), and one a localId 
373
     * in the Metacat docid format (scope.id.revision). 
374
     * This mapping allows one to find the global id (guid) from the localId.
375
     * 
376
     * @param guid the global string identifier to be mapped
377
     * @param localId the local identifier to be mapped
378
     */
379
    public void createMapping(String guid, String localId)
380
    {   
381
        createGenericMapping(guid, localId, TYPE_IDENTIFIER);
382
    }
383
    
384
    /**
385
     * 
386
     * @param guid
387
     * @param rev
388
     * @return
389
     */
390
    public String generateLocalId(String guid, int rev)
391
    {
392
        return generateLocalId(guid, rev, false);
393
    }
394

    
395
    /**
396
     * Given a global identifier (guid), create a suitable local identifier that
397
     * follows Metacat's docid semantics and format (scope.id.rev), and create
398
     * a mapping between these two identifiers.  This effectively reserves both
399
     * the global and the local identifier, as they will now be present in the
400
     * identifier mapping table.  If the incoming guid has the syntax of a
401
     * Metacat docid (scope.id.rev), then simply use it.
402
     * 
403
     * @param guid the global string identifier
404
     * @param rev the revision number to be used in the localId
405
     * @return String containing the localId to be used for Metacat operations
406
     */
407
    public String generateLocalId(String guid, int rev, boolean isSystemMetadata) 
408
    {
409
        String localId = "";
410
        boolean conformsToDocidFormat = false;
411
        
412
        // Check if the guid passed in is already in docid (scope.id.rev) format
413
        try {
414
            AccessionNumber acc = new AccessionNumber(guid, "NONE");
415
            if (new Integer(acc.getRev()).intValue() > 0) {
416
                conformsToDocidFormat = true;
417
            }
418
        } catch (NumberFormatException e) {
419
            // No action needed, simply detecting invalid AccessionNumbers
420
        } catch (AccessionNumberException e) {
421
            // No action needed, simply detecting invalid AccessionNumbers
422
        } catch (SQLException e) {
423
            // No action needed, simply detecting invalid AccessionNumbers
424
        }
425
        
426
        if (conformsToDocidFormat) {
427
            // if it conforms, use it for both guid and localId
428
            localId = guid;
429
        } else {
430
            // if not, then generate a new unique localId
431
            localId = DocumentUtil.generateDocumentId(rev);
432
        }
433
        
434
        // Register this new pair in the identifier mapping table
435
        System.out.println("creating mapping in generateLocalId");
436
        if(!isSystemMetadata)
437
        { //don't do this if we're generating for system metadata
438
            createMapping(guid, localId);
439
        }
440
        
441
        return localId;
442
    }
443
    
444
    /**
445
     * given a local identifer, look up the guid.  Throw McdbDocNotFoundException
446
     * if the docid, rev is not found in the identifiers or systemmetadata tables
447
     *
448
     * @param docid the docid to look up
449
     * @param rev the revision of the docid to look up
450
     * @return String containing the mapped guid
451
     * @throws McdbDocNotFoundException if the docid, rev is not found
452
     */
453
    public String getGUID(String docid, int rev)
454
      throws McdbDocNotFoundException
455
    {
456
        System.out.println("getting guid for " + docid);
457
        String query = "select guid from identifier where docid = ? and rev = ?";
458
        String guid = null;
459
        boolean found = false;
460
        
461
        DBConnection dbConn = null;
462
        int serialNumber = -1;
463
        try {
464
            // Get a database connection from the pool
465
            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getGUID");
466
            serialNumber = dbConn.getCheckOutSerialNumber();
467
            
468
            // Execute the insert statement
469
            PreparedStatement stmt = dbConn.prepareStatement(query);
470
            stmt.setString(1, docid);
471
            stmt.setInt(2, rev);
472
            ResultSet rs = stmt.executeQuery();
473
            if (rs.next()) 
474
            {
475
                guid = rs.getString(1);
476
            } 
477
            else
478
            {
479
                query = "select guid from systemmetadata where docid = ? and rev = ?";
480
                stmt = dbConn.prepareStatement(query);
481
                stmt.setString(1, docid);
482
                stmt.setInt(2, rev);
483
                rs = stmt.executeQuery();
484
                if(rs.next())
485
                {
486
                    guid = rs.getString(1);
487
                }
488
                else
489
                {
490
                    throw new McdbDocNotFoundException("No guid registered for docid " + docid + "." + rev);
491
                }
492
            }
493
            
494
        } catch (SQLException e) {
495
            logMetacat.error("Error while looking up the guid: " 
496
                    + e.getMessage());
497
        } finally {
498
            // Return database connection to the pool
499
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
500
        }
501
        
502
        return guid;
503
    }
504
    
505
    /**
506
     * creates a mapping for a system metadata document, but DOES NOT add any
507
     * of the extra system metadata information to the table.  You must call 
508
     * insertAdditionalSystemMetadataFields to complete the entry
509
     * 
510
     * @param guid the id to insert
511
     * @param localId the systemMetadata object to get the local id for
512
     */
513
    public void createSystemMetadataMapping(String guid, String localId)
514
    {
515
        createGenericMapping(guid, localId, TYPE_SYSTEM_METADATA);
516
    }
517
    
518
    /**
519
     * creates a system metadata mapping and adds additional fields from sysmeta
520
     * to the table for quick searching.
521
     * 
522
     * @param guid the id to insert
523
     * @param localId the systemMetadata object to get the local id for
524
     */
525
    public void createSystemMetadataMapping(SystemMetadata sysmeta, String localId)
526
    {
527
        createGenericMapping(sysmeta.getIdentifier().getValue(), localId, TYPE_SYSTEM_METADATA);
528
        insertAdditionalSystemMetadataFields(sysmeta);
529
    }
530
    
531
    /**
532
     * update a mapping
533
     * @param guid
534
     * @param localId
535
     */
536
    public void updateSystemMetadataMapping(String guid, String localId)
537
    {
538
        int serialNumber = -1;
539
        DBConnection dbConn = null;
540
        try {
541
            // Parse the localId into scope and rev parts
542
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
543
            String docid = acc.getDocid();
544
            int rev = 1;
545
            if(acc.getRev() != null)
546
            {
547
              rev = (new Integer(acc.getRev()).intValue());
548
            }
549

    
550
            // Get a database connection from the pool
551
            dbConn = 
552
                DBConnectionPool.getDBConnection("IdentifierManager.createMapping");
553
            serialNumber = dbConn.getCheckOutSerialNumber();
554

    
555
            // Execute the insert statement
556
            String query = "update systemmetadata set (docid, rev) = (?, ?) where guid='" + guid + "'";
557
            //System.out.println("query: " + query + " for params: (guid:" + guid + ", docid=" + docid + ", rev=" + rev + ")");
558
            PreparedStatement stmt = dbConn.prepareStatement(query);
559
            stmt.setString(1, docid);
560
            stmt.setInt(2, rev);
561
            int rows = stmt.executeUpdate();
562

    
563
            stmt.close();
564
        } catch (SQLException e) {
565
            e.printStackTrace();
566
            logMetacat.error("SQL error while updating a mapping to the system metadata identifier: " 
567
                    + e.getMessage());
568
        } catch (NumberFormatException e) {
569
            e.printStackTrace();
570
            logMetacat.error("NumberFormat error while updating a mapping to the system metadata identifier: " 
571
                    + e.getMessage());
572
        } catch (AccessionNumberException e) {
573
            e.printStackTrace();
574
            logMetacat.error("AccessionNumber error while updating a mapping to the system metadata identifier: " 
575
                    + e.getMessage());
576
        } finally {
577
            // Return database connection to the pool
578
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
579
        }
580
    }
581
    
582
    /**
583
     * return the localId of a system metadata document based on its guid
584
     */
585
    public String getSystemMetadataLocalId(String guid)
586
      throws McdbDocNotFoundException
587
    {
588
      return this.getLocalId(guid, TYPE_SYSTEM_METADATA);
589
    }
590
    
591
    public void insertAdditionalSystemMetadataFields(long dateUploaded, String rightsHolder,
592
            String checksum, String checksumAlgorithm, String originMemberNode,
593
            String authoritativeMemberNode, long modifiedDate, String submitter, String guid)
594
    {
595
        DBConnection dbConn = null;
596
        int serialNumber = -1;
597
        try {
598
            // Get a database connection from the pool
599
            dbConn = 
600
                DBConnectionPool.getDBConnection("IdentifierManager.createMapping");
601
            serialNumber = dbConn.getCheckOutSerialNumber();
602

    
603
            // Execute the insert statement
604
            String query = "update " + TYPE_SYSTEM_METADATA + 
605
                " set (date_uploaded, rights_holder, checksum, checksum_algorithm, " +
606
                "origin_member_node, authoritive_member_node, date_modified, submitter) " +
607
                "= (?, ?, ?, ?, ?, ?, ?, ?) where guid = ?";
608
            PreparedStatement stmt = dbConn.prepareStatement(query);
609
            
610
            //data values
611
            stmt.setTimestamp(1, new java.sql.Timestamp(dateUploaded));
612
            stmt.setString(2, rightsHolder);
613
            stmt.setString(3, checksum);
614
            stmt.setString(4, checksumAlgorithm);
615
            stmt.setString(5, originMemberNode);
616
            stmt.setString(6, authoritativeMemberNode);
617
            stmt.setTimestamp(7, new java.sql.Timestamp(modifiedDate));
618
            stmt.setString(8, submitter);
619
            //where clause
620
            stmt.setString(9, guid);
621
            System.out.println("stmt: " + stmt.toString());
622
            //execute
623
            int rows = stmt.executeUpdate();
624

    
625
            stmt.close();
626
        } catch (SQLException e) {
627
            e.printStackTrace();
628
            logMetacat.error("SQL error while creating a mapping to the system metadata identifier: " 
629
                    + e.getMessage());
630
        } catch (NumberFormatException e) {
631
            e.printStackTrace();
632
            logMetacat.error("NumberFormat error while creating a mapping to the system metadata identifier: " 
633
                    + e.getMessage());
634
        } finally {
635
            // Return database connection to the pool
636
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
637
        }
638
    }
639
    
640
    /**
641
     * Insert the system metadata fields into the db
642
     * @param sm
643
     */
644
    public void insertAdditionalSystemMetadataFields(SystemMetadata sm)
645
    {
646
        insertAdditionalSystemMetadataFields(
647
                sm.getDateUploaded().getTime(),
648
                sm.getRightsHolder().getValue(), 
649
                sm.getChecksum().getValue(), 
650
                sm.getChecksum().getAlgorithm().name(), 
651
                sm.getOriginMemberNode().getValue(),
652
                sm.getAuthoritativeMemberNode().getValue(), 
653
                sm.getDateSysMetadataModified().getTime(),
654
                sm.getSubmitter().getValue(), 
655
                sm.getIdentifier().getValue());
656
    }
657
    
658
    /**
659
     * return a localId based on a guid.  The type can either be 'identifier' 
660
     * to get an id from the identifier table or 'systemmetadata' to get
661
     * the identifier from the systemidentifier table
662
     */
663
    private String getLocalId(String guid, String type)
664
      throws McdbDocNotFoundException
665
    {
666
      if(!type.equals(TYPE_IDENTIFIER) &&
667
        !type.equals(TYPE_SYSTEM_METADATA))
668
      {
669
        throw new RuntimeException("cannot lookup the identifier for type " + type +
670
          ".  Please choose 'identifier' or 'systemmetadata'.");
671
      }
672
      
673
      String db_guid = "";
674
      String docid = "";
675
      int rev = 0;
676
      
677
      String query = "select guid, docid, rev from " + type + " where guid = ?";
678
      //System.out.println("query: " + query + " for params: (" + guid + ")");
679
      
680
      DBConnection dbConn = null;
681
      int serialNumber = -1;
682
      try {
683
          // Get a database connection from the pool
684
          dbConn = DBConnectionPool.getDBConnection("Identifier.getLocalId");
685
          serialNumber = dbConn.getCheckOutSerialNumber();
686
          
687
          // Execute the insert statement
688
          PreparedStatement stmt = dbConn.prepareStatement(query);
689
          stmt.setString(1, guid);
690
          ResultSet rs = stmt.executeQuery();
691
          if (rs.next()) {
692
              db_guid = rs.getString(1);
693
              docid = rs.getString(2);
694
              rev = rs.getInt(3);
695
              assert(db_guid.equals(guid));
696
          } else {
697
              throw new McdbDocNotFoundException("Document not found:" + guid);
698
          }
699
          stmt.close();
700
      } catch (SQLException e) {
701
          logMetacat.error("Error while looking up the local identifier: " 
702
                  + e.getMessage());
703
      } finally {
704
          // Return database connection to the pool
705
          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
706
      }
707
      return docid + "." + rev;
708
    }
709
    
710
    /**
711
     * create a mapping in the systemmetadata or identifier table
712
     * @param guid
713
     * @param localId
714
     * @param type
715
     */
716
    private void createGenericMapping(String guid, String localId, String type)
717
    {        
718
        if(!type.equals(TYPE_IDENTIFIER) &&
719
        !type.equals(TYPE_SYSTEM_METADATA))
720
        {
721
          throw new RuntimeException("Cannot create mapping for type " + type +
722
            ".  Please choose 'identifier' or 'systemmetadata'.");
723
        }
724
        
725
        int serialNumber = -1;
726
        DBConnection dbConn = null;
727
        try {
728

    
729
            // Parse the localId into scope and rev parts
730
            AccessionNumber acc = new AccessionNumber(localId, "NOACTION");
731
            String docid = acc.getDocid();
732
            int rev = 1;
733
            if(acc.getRev() != null)
734
            {
735
              rev = (new Integer(acc.getRev()).intValue());
736
            }
737

    
738
            // Get a database connection from the pool
739
            dbConn = 
740
                DBConnectionPool.getDBConnection("IdentifierManager.createMapping");
741
            serialNumber = dbConn.getCheckOutSerialNumber();
742

    
743
            // Execute the insert statement
744
            String query = "insert into " + type + " (guid, docid, rev) values (?, ?, ?)";
745
            //System.out.println("query: " + query + " for params: (" + guid + ", " + docid + ", " + rev + ")");
746
            PreparedStatement stmt = dbConn.prepareStatement(query);
747
            stmt.setString(1, guid);
748
            stmt.setString(2, docid);
749
            stmt.setInt(3, rev);
750
            System.out.println("generic mapping query: " + stmt.toString());
751
            int rows = stmt.executeUpdate();
752

    
753
            stmt.close();
754
        } catch (SQLException e) {
755
            e.printStackTrace();
756
            logMetacat.warn("SQL error while creating a mapping to the system metadata identifier: " 
757
                    + e.getMessage());
758
        } catch (NumberFormatException e) {
759
            e.printStackTrace();
760
            logMetacat.error("NumberFormat error while creating a mapping to the system metadata identifier: " 
761
                    + e.getMessage());
762
        } catch (AccessionNumberException e) {
763
            e.printStackTrace();
764
            logMetacat.error("AccessionNumber error while creating a mapping to the system metadata identifier: " 
765
                    + e.getMessage());
766
        } finally {
767
            // Return database connection to the pool
768
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
769
        }
770
    }
771
}
772

    
(37-37/65)