Project

General

Profile

« Previous | Next » 

Revision 5962

Added by Chris Jones over 13 years ago

Modified MetacatHandler, added createSystemMetadata() - generates SystemMetadata objects for newly inserted data or documents. This is intended to be used from handleInsertOrUpdateAction(), and only for documents being inserted from clients that don't support the DataONE interface. The method parses EML documents to discover data entities, and updates the system metadata for those entries, with support for describes and describedBy metadata. Currently doesn't handle FGDC, etc. documents.
Added sizeOfStream() - Find the size (in bytes) of a stream. Note: This needs to refactored out of MetacatHandler and into a utility when stream i/o in Metacat is evaluated.

View differences:

src/edu/ucsb/nceas/metacat/MetacatHandler.java
3280 3280
      return sysmetaOut;
3281 3281
    }
3282 3282
    
3283
    /**
3284
     * Creates a system metadata object for insertion into metacat
3285
     *
3286
     * @param localId  The local document identifier
3287
     * @param user  The user submitting the system metadata document
3288
     * @param groups  The groups the user belongs to
3289
     *
3290
     * @return sysMeta  The system metadata object created
3291
     */
3292
    public SystemMetadata createSystemMetadata(Identifier identifier,
3293
      String username, String[] groups) 
3294
      throws McdbException, McdbDocNotFoundException, SQLException, 
3295
      IOException, AccessionNumberException, ClassNotFoundException,
3296
      InsufficientKarmaException, ParseLSIDException, PropertyNotFoundException,
3297
      BaseException, NoSuchAlgorithmException
3298
    {
3299
      logMetacat.debug("MetacatHandler.createSystemMetadata() called.");
3300
      
3301
      // create system metadata for the document
3302
      IdentifierManager im = IdentifierManager.getInstance();
3303
      Hashtable<String, Object> docInfo;
3304
      SystemMetadata sysMeta = new SystemMetadata();
3305
      String localId = "";
3306
      InputStream inputStream;
3307
      //set the id
3308
      sysMeta.setIdentifier(identifier);
3309
      
3310
      // get the data or metadata object
3311
      try {
3312
        localId = im.getLocalId(identifier.getValue());
3313
        docInfo = im.getDocumentInfo(localId);
3314
        inputStream = this.read(localId, username, groups);
3315
        
3316
      } catch ( McdbDocNotFoundException dnfe ) {
3317
        logMetacat.debug("There was a problem getting the localId from " +
3318
          "the given guid. The error message was: " + dnfe.getMessage());
3319
        throw dnfe;
3320
          
3321
      } catch ( InsufficientKarmaException ike ) {
3322
        logMetacat.debug("There was an access problem reading " +
3323
          localId + ". The error message was: " + ike.getMessage());
3324
        throw ike;
3325
        
3326
      } catch ( ParseLSIDException ple ) {
3327
        logMetacat.debug("There was a problem parsing the LSID from " +
3328
          localId + ". The error message was: " + ple.getMessage());
3329
        throw ple;
3330
      
3331
      } catch ( PropertyNotFoundException pnfe ) {
3332
        logMetacat.debug("There was a problem finding a property. " +
3333
          "The error message was: " + pnfe.getMessage());
3334
        throw pnfe;
3335
        
3336
      } catch ( McdbException me ) {
3337
        logMetacat.debug("There was a Metacat problem. " +
3338
          "The error message was: " + me.getMessage());
3339
        throw me;
3340
        
3341
      } catch ( SQLException sqle ) {
3342
        logMetacat.debug("There was a SQL problem. " +
3343
          "The error message was: " + sqle.getMessage());
3344
        throw sqle;
3345
        
3346
      } catch ( ClassNotFoundException cnfe ) {
3347
        logMetacat.debug("There was a problem finding a class. " +
3348
          "The error message was: " + cnfe.getMessage());
3349
        throw cnfe;
3350
        
3351
      } catch ( IOException ioe ) {
3352
        logMetacat.debug("There was an I/O exception. " +
3353
          "The error message was: " + ioe.getMessage());
3354
        throw ioe;
3355
        
3356
      } // end try()
3357
    
3358
      //set the default object format
3359
      String doctype = (String) docInfo.get("doctype");
3360
      ObjectFormat format = ObjectFormat.convert(doctype);
3361
      if (format == null) {
3362
          if (doctype.trim().equals("BIN")) {
3363
              format = ObjectFormat.OCTET_STREAM;
3364
          } else {
3365
              format = ObjectFormat.convert("text/plain");
3366
          }
3367
      }
3368
      sysMeta.setObjectFormat(format);
3369
      logMetacat.debug("The ObjectFormat for " + localId + 
3370
                       " is " + format.toString());
3371
      
3372
      // further parse EML documents to get data object format,
3373
      // describes and describedBy information
3374
      if ( format == ObjectFormat.EML_2_0_0 ||
3375
           format == ObjectFormat.EML_2_0_1 ||
3376
           format == ObjectFormat.EML_2_1_0 ) {
3377
        
3378
        try {
3379
          DataoneEMLParser emlParser = DataoneEMLParser.getInstance();
3380
          EMLDocument emlDocument = emlParser.parseDocument(inputStream);
3381
          
3382
          // iterate through the data objects in the EML doc and add sysmeta
3383
          logMetacat.debug("In createSystemMetadata() the number of data " + 
3384
            "entities is: " + emlDocument.distributionMetadata.size());
3385
                          
3386
          // iterate through data objects described by the EML
3387
          for( int j = 0; j < emlDocument.distributionMetadata.size(); j++ ) {
3388
            
3389
            DistributionMetadata distMetadata = 
3390
              emlDocument.distributionMetadata.elementAt(j);
3391
            String dataDocUrl = distMetadata.url;
3392
            String dataDocMimeType = distMetadata.mimeType;
3393
            String dataDocLocalId = "";
3394
            logMetacat.debug("Data local ID: " + dataDocLocalId);
3395
            logMetacat.debug("Data URL     : " + dataDocUrl);
3396
            logMetacat.debug("Data mime    : " + dataDocMimeType);
3397
            
3398
            //we only handle ecogrid urls right now
3399
            if ( dataDocUrl.trim().startsWith("ecogrid://knb/") ) {
3400
              dataDocLocalId = 
3401
                dataDocUrl.substring(dataDocUrl.indexOf("ecogrid://knb/") + 
3402
                "ecogrid://knb/".length(), dataDocUrl.length());
3403
              
3404
              //set the id
3405
              Identifier dataDocId = new Identifier();
3406
              dataDocId.setValue(dataDocLocalId);
3407
              
3408
              // add describes into EML system metadata
3409
              sysMeta.addDescribe(dataDocId);
3410
              
3411
              SystemMetadata dataSysMeta = new SystemMetadata();
3412
              // check if data system metadata exists
3413
              try {
3414
                logMetacat.debug("Checking for existing system metadata for " + 
3415
                  dataDocId.getValue());
3416
                dataSysMeta = this.getSystemMetadata(dataDocId);
3417
                // add describedBy sysmeta
3418
                logMetacat.debug("Setting describedBy for " + dataDocId.getValue() +
3419
                                 " to " + identifier.getValue());
3420
                dataSysMeta.addDescribedBy(identifier);
3421
                dataSysMeta.setObjectFormat(ObjectFormat.convert(dataDocMimeType));
3422
                this.updateSystemMetadata(dataSysMeta, username, groups);
3423
                
3424
              } catch ( NotFound nf ) {
3425
                // System metadata for data doesn't exist
3426
                logMetacat.debug("There was not an existing system metadata " + 
3427
                  "document for " + dataDocId.getValue());
3428
                try {
3429
                  logMetacat.debug("Creating a system metadata " + 
3430
                    "document for " + dataDocId.getValue());
3431
                  dataSysMeta = 
3432
                    this.createSystemMetadata(dataDocId, username, groups);
3433
                  
3434
                  logMetacat.debug("Setting describedBy for " + 
3435
                    dataDocId.getValue() + " to " + identifier.getValue());
3436
                  dataSysMeta.addDescribedBy(identifier);
3437
                  
3438
                  logMetacat.debug("Setting mimeType for " + 
3439
                    dataDocId.getValue() + " to " + dataDocMimeType);
3440
                  dataSysMeta.setObjectFormat(ObjectFormat.convert(dataDocMimeType));
3441
                  
3442
                  logMetacat.debug("Updating system metadata for " + 
3443
                    dataDocId.getValue() + " to " + dataDocMimeType);
3444
                  this.updateSystemMetadata(dataSysMeta, username, groups);
3445
                  
3446
                } catch ( McdbDocNotFoundException mdnf) {
3447
                  mdnf.printStackTrace();
3448
                  throw mdnf;
3449
                } catch ( NumberFormatException nfe) {
3450
                  nfe.printStackTrace();
3451
                  throw nfe;
3452
                } catch ( AccessionNumberException ane) {
3453
                  ane.printStackTrace();
3454
                  throw ane;
3455
                } catch ( SQLException sqle) {
3456
                  sqle.printStackTrace();
3457
                  throw sqle;
3458
                } catch ( NoSuchAlgorithmException nsae) {
3459
                  nsae.printStackTrace();
3460
                  throw nsae;
3461
                } catch ( IOException ioe) {
3462
                  ioe.printStackTrace();
3463
                  throw ioe;
3464
                } catch ( PropertyNotFoundException pnfe) {
3465
                  pnfe.printStackTrace();
3466
                  throw pnfe;
3467
                } catch ( BaseException be) {
3468
                  be.printStackTrace();
3469
                  throw be;
3470
                  
3471
                }
3472
                
3473
              }
3474
              
3475
            } // end if()
3476
            
3477
          } // end for()
3478
         
3479
        } catch ( ParserConfigurationException pce ) {
3480
          logMetacat.debug("There was a problem parsing the EML document. " +
3481
                           "The error message was: " + pce.getMessage());
3482
        
3483
        } catch ( SAXException saxe ) {
3484
          logMetacat.debug("There was a problem traversing the EML document. " +
3485
                           "The error message was: " + saxe.getMessage());
3486
        
3487
        } catch ( XPathExpressionException xpee ) {
3488
          logMetacat.debug("There was a problem searching the EML document. " +
3489
                           "The error message was: " + xpee.getMessage());
3490
        } // end try()
3491
         
3492
      } // end if()
3493
      
3494
      
3495
      //create the checksum
3496
      inputStream = this.read(localId, username, groups);
3497
      ChecksumAlgorithm algorithm = ChecksumAlgorithm.convert("MD5");
3498
      Checksum checksum = ServiceTypeUtil.checksum(inputStream, algorithm);
3499
      sysMeta.setChecksum(checksum);
3500
      
3501
      //set the size
3502
      inputStream = this.read(localId, username, groups);
3503
      sysMeta.setSize(sizeOfStream(inputStream));
3504
      
3505
      //submitter
3506
      Principal principal = new Principal();
3507
      principal.setValue((String) docInfo.get("user_owner"));
3508
      sysMeta.setSubmitter(principal);
3509
      sysMeta.setRightsHolder(principal);
3510

  
3511
      try {
3512
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-DD");
3513
        dateFormat.setTimeZone(TimeZone.getDefault());
3514
        
3515
        Date dateCreated = dateFormat.parse((String) docInfo.get("date_created"));
3516
        sysMeta.setDateUploaded(dateCreated);
3517
        Date dateUpdated = dateFormat.parse((String) docInfo.get("date_updated"));
3518
        sysMeta.setDateSysMetadataModified(dateUpdated);
3519
      
3520
      } catch (ParseException pe) {
3521
        logMetacat.debug("There was a problem parsing a Metacat date. The " + 
3522
          "error message was: " + pe.getMessage());
3523
        Date dateCreated = new Date();
3524
        sysMeta.setDateUploaded(dateCreated);
3525
        Date dateUpdated = new Date();
3526
        sysMeta.setDateSysMetadataModified(dateUpdated);
3527
      
3528
      }
3529
      NodeReference nr = new NodeReference();
3530
      nr.setValue(PropertyService.getProperty("dataone.memberNodeId"));
3531
      sysMeta.setOriginMemberNode(nr);
3532
      sysMeta.setAuthoritativeMemberNode(nr);
3533
      
3534
      return sysMeta;
3535
    }
3536
    
3283 3537
    /*
3284 3538
     * Inserts or updates system metadata documents in Metacat. Note: This
3285 3539
     * needs to be refactored out of MetacatHandler and into a utitlity when 
......
3518 3772
       
3519 3773
    }
3520 3774
    
3775
    /*
3776
     * Find the size (in bytes) of a stream. Note: This needs to refactored out
3777
     * of MetacatHandler and into a utility when stream i/o in Metacat is
3778
     * evaluated.
3779
     *
3780
     * @param is  The InputStream of bytes
3781
     * @return size  The size in bytes of the input stream as a long
3782
     * @throws IOException
3783
     */
3784
    private long sizeOfStream(InputStream is)
3785
      throws IOException {
3786
      
3787
      long size = 0;
3788
      byte[] b = new byte[1024];
3789
      int numread = is.read(b, 0, 1024);
3790
      while(numread != -1)
3791
      {
3792
          size += numread;
3793
          numread = is.read(b, 0, 1024);
3794
      }
3795
      return size;
3796
      
3797
    }
3798
    
3521 3799
}

Also available in: Unified diff