Revision 6705
Added by ben leinfelder almost 13 years ago
src/edu/ucsb/nceas/metacat/MetacatHandler.java | ||
---|---|---|
41 | 41 |
import java.io.StringReader; |
42 | 42 |
import java.io.UnsupportedEncodingException; |
43 | 43 |
import java.io.Writer; |
44 |
import java.math.BigInteger; |
|
45 | 44 |
import java.net.MalformedURLException; |
46 | 45 |
import java.net.URL; |
47 |
import java.security.NoSuchAlgorithmException; |
|
48 | 46 |
import java.sql.PreparedStatement; |
49 | 47 |
import java.sql.ResultSet; |
50 | 48 |
import java.sql.SQLException; |
... | ... | |
57 | 55 |
import java.util.Hashtable; |
58 | 56 |
import java.util.Iterator; |
59 | 57 |
import java.util.Map; |
60 |
import java.util.TimeZone; |
|
61 | 58 |
import java.util.Timer; |
62 | 59 |
import java.util.TimerTask; |
63 | 60 |
import java.util.Vector; |
... | ... | |
69 | 66 |
import javax.servlet.http.HttpServletRequest; |
70 | 67 |
import javax.servlet.http.HttpServletResponse; |
71 | 68 |
import javax.servlet.http.HttpSession; |
72 |
import javax.xml.parsers.ParserConfigurationException; |
|
73 |
import javax.xml.xpath.XPathExpressionException; |
|
74 | 69 |
|
75 |
import org.apache.commons.io.IOUtils; |
|
76 | 70 |
import org.apache.commons.io.input.XmlStreamReader; |
77 | 71 |
import org.apache.log4j.Logger; |
78 |
import org.dataone.client.ObjectFormatCache; |
|
79 |
import org.dataone.service.exceptions.BaseException; |
|
80 |
import org.dataone.service.exceptions.NotFound; |
|
81 |
import org.dataone.service.types.v1.Checksum; |
|
82 |
import org.dataone.service.types.v1.Identifier; |
|
83 |
import org.dataone.service.types.v1.NodeReference; |
|
84 |
import org.dataone.service.types.v1.ObjectFormatIdentifier; |
|
85 |
import org.dataone.service.types.v1.Subject; |
|
86 | 72 |
import org.dataone.service.types.v1.SystemMetadata; |
87 |
import org.dataone.service.types.v1.util.ChecksumUtil; |
|
88 |
import org.ecoinformatics.datamanager.DataManager; |
|
89 |
import org.ecoinformatics.datamanager.database.DatabaseConnectionPoolInterface; |
|
90 |
import org.ecoinformatics.datamanager.parser.DataPackage; |
|
91 | 73 |
import org.ecoinformatics.eml.EMLParser; |
92 |
import org.jibx.runtime.JiBXException; |
|
93 |
import org.xml.sax.SAXException; |
|
94 | 74 |
|
95 | 75 |
import au.com.bytecode.opencsv.CSVWriter; |
96 | 76 |
|
... | ... | |
107 | 87 |
import edu.ucsb.nceas.metacat.client.InsufficientKarmaException; |
108 | 88 |
import edu.ucsb.nceas.metacat.database.DBConnection; |
109 | 89 |
import edu.ucsb.nceas.metacat.database.DBConnectionPool; |
90 |
import edu.ucsb.nceas.metacat.dataone.SystemMetadataFactory; |
|
110 | 91 |
import edu.ucsb.nceas.metacat.dataone.hazelcast.HazelcastService; |
111 | 92 |
import edu.ucsb.nceas.metacat.dataquery.DataQuery; |
112 |
import edu.ucsb.nceas.metacat.dataquery.MetacatDatabaseConnectionPoolFactory; |
|
113 | 93 |
import edu.ucsb.nceas.metacat.event.MetacatDocumentEvent; |
114 | 94 |
import edu.ucsb.nceas.metacat.event.MetacatEventService; |
115 | 95 |
import edu.ucsb.nceas.metacat.properties.PropertyService; |
... | ... | |
1871 | 1851 |
// handle inserts |
1872 | 1852 |
try { |
1873 | 1853 |
// create the system metadata |
1874 |
sysMeta = createSystemMetadata(newdocid); |
|
1854 |
sysMeta = SystemMetadataFactory.createSystemMetadata(newdocid);
|
|
1875 | 1855 |
|
1876 | 1856 |
// save it to the map |
1877 | 1857 |
HazelcastService.getInstance().getSystemMetadataMap().put(sysMeta.getIdentifier(), sysMeta); |
... | ... | |
3015 | 2995 |
username, groupnames); |
3016 | 2996 |
|
3017 | 2997 |
// generate system metadata about the doc |
3018 |
SystemMetadata sm = createSystemMetadata(docid); |
|
2998 |
SystemMetadata sm = SystemMetadataFactory.createSystemMetadata(docid);
|
|
3019 | 2999 |
|
3020 | 3000 |
// manage it in the store |
3021 | 3001 |
HazelcastService.getInstance().getSystemMetadataMap().put(sm.getIdentifier(), sm); |
... | ... | |
3515 | 3495 |
_sitemapScheduled = sitemapScheduled; |
3516 | 3496 |
} |
3517 | 3497 |
|
3518 |
/** |
|
3519 |
* Creates a system metadata object for insertion into metacat |
|
3520 |
* |
|
3521 |
* @param localId The local document identifier |
|
3522 |
* @param user The user submitting the system metadata document |
|
3523 |
* @param groups The groups the user belongs to |
|
3524 |
* |
|
3525 |
* @return sysMeta The system metadata object created |
|
3526 |
*/ |
|
3527 |
public static SystemMetadata createSystemMetadata(String localId) |
|
3528 |
throws McdbException, McdbDocNotFoundException, SQLException, |
|
3529 |
IOException, AccessionNumberException, ClassNotFoundException, |
|
3530 |
InsufficientKarmaException, ParseLSIDException, PropertyNotFoundException, |
|
3531 |
BaseException, NoSuchAlgorithmException, JiBXException |
|
3532 |
{ |
|
3533 |
logMetacat.debug("MetacatHandler.createSystemMetadata() called."); |
|
3534 |
logMetacat.debug("provided localId: " + localId); |
|
3535 |
|
|
3536 |
// create system metadata for the document |
|
3537 |
SystemMetadata sysMeta = new SystemMetadata(); |
|
3538 |
sysMeta.setSerialVersion(BigInteger.valueOf(1)); |
|
3539 |
int rev = IdentifierManager.getInstance().getLatestRevForLocalId(localId); |
|
3540 |
AccessionNumber accNum = new AccessionNumber(localId, "NONE"); |
|
3541 |
String guid = null; |
|
3542 |
try { |
|
3543 |
// get the guid if it exists |
|
3544 |
guid = IdentifierManager.getInstance().getGUID(accNum.getDocid(), rev); |
|
3545 |
} catch ( McdbDocNotFoundException dnfe ) { |
|
3546 |
// otherwise create the mapping |
|
3547 |
logMetacat.debug("There was a problem getting the guid from " + |
|
3548 |
"the given localId (docid and revision). The error message was: " + dnfe.getMessage()); |
|
3549 |
logMetacat.debug("No guid in the identifier table. adding it for " + localId); |
|
3550 |
IdentifierManager.getInstance().createMapping(localId, localId); |
|
3551 |
logMetacat.debug("Mapping created for " + localId); |
|
3552 |
logMetacat.debug("accessionNumber: " + accNum); |
|
3553 |
guid = IdentifierManager.getInstance().getGUID(accNum.getDocid(), rev); |
|
3554 |
} |
|
3555 |
Identifier identifier = new Identifier(); |
|
3556 |
identifier.setValue(guid); |
|
3557 |
|
|
3558 |
//set the id |
|
3559 |
sysMeta.setIdentifier(identifier); |
|
3560 |
|
|
3561 |
// get the data or metadata object |
|
3562 |
InputStream inputStream; |
|
3563 |
try { |
|
3564 |
inputStream = read(localId); |
|
3565 |
} catch ( ParseLSIDException ple ) { |
|
3566 |
logMetacat.debug("There was a problem parsing the LSID from " + |
|
3567 |
localId + ". The error message was: " + ple.getMessage()); |
|
3568 |
throw ple; |
|
3569 |
|
|
3570 |
} catch ( PropertyNotFoundException pnfe ) { |
|
3571 |
logMetacat.debug("There was a problem finding a property. " + |
|
3572 |
"The error message was: " + pnfe.getMessage()); |
|
3573 |
throw pnfe; |
|
3574 |
|
|
3575 |
} catch ( McdbException me ) { |
|
3576 |
logMetacat.debug("There was a Metacat problem. " + |
|
3577 |
"The error message was: " + me.getMessage()); |
|
3578 |
throw me; |
|
3579 |
|
|
3580 |
} catch ( SQLException sqle ) { |
|
3581 |
logMetacat.debug("There was a SQL problem. " + |
|
3582 |
"The error message was: " + sqle.getMessage()); |
|
3583 |
throw sqle; |
|
3584 |
|
|
3585 |
} catch ( ClassNotFoundException cnfe ) { |
|
3586 |
logMetacat.debug("There was a problem finding a class. " + |
|
3587 |
"The error message was: " + cnfe.getMessage()); |
|
3588 |
throw cnfe; |
|
3589 |
|
|
3590 |
} catch ( IOException ioe ) { |
|
3591 |
logMetacat.debug("There was an I/O exception. " + |
|
3592 |
"The error message was: " + ioe.getMessage()); |
|
3593 |
throw ioe; |
|
3594 |
|
|
3595 |
} // end try() |
|
3596 |
|
|
3597 |
// get additional docinfo |
|
3598 |
Hashtable<String, Object> docInfo = IdentifierManager.getInstance().getDocumentInfo(localId); |
|
3599 |
//set the default object format |
|
3600 |
String doctype = (String) docInfo.get("doctype"); |
|
3601 |
ObjectFormatIdentifier fmtid = null; |
|
3602 |
|
|
3603 |
// set the object format, fall back to defaults |
|
3604 |
try { |
|
3605 |
fmtid = ObjectFormatCache.getInstance().getFormat(doctype).getFormatId(); |
|
3606 |
|
|
3607 |
} catch (NotFound nfe) { |
|
3608 |
|
|
3609 |
try { |
|
3610 |
// format is not registered, use default |
|
3611 |
if (doctype.trim().equals("BIN")) { |
|
3612 |
fmtid = ObjectFormatCache.getInstance().getFormat( |
|
3613 |
"application/octet-stream").getFormatId(); |
|
3614 |
|
|
3615 |
} else { |
|
3616 |
fmtid = ObjectFormatCache.getInstance().getFormat("text/plain").getFormatId(); |
|
3617 |
} |
|
3618 |
|
|
3619 |
} catch (NotFound nf) { |
|
3620 |
logMetacat.error("There was a problem getting the default format " + |
|
3621 |
"from the ObjectFormatCache: " + nf.getMessage()); |
|
3622 |
throw nf; |
|
3623 |
} |
|
3624 |
|
|
3625 |
} |
|
3626 |
|
|
3627 |
sysMeta.setFormatId(fmtid); |
|
3628 |
logMetacat.debug("The ObjectFormat for " + localId + " is " + fmtid.getValue()); |
|
3629 |
|
|
3630 |
// further parse EML documents to get data object format, |
|
3631 |
// describes and describedBy information |
|
3632 |
if ( fmtid == ObjectFormatCache.getInstance().getFormat("eml://ecoinformatics.org/eml-2.0.0").getFormatId() || |
|
3633 |
fmtid == ObjectFormatCache.getInstance().getFormat("eml://ecoinformatics.org/eml-2.0.1").getFormatId() || |
|
3634 |
fmtid == ObjectFormatCache.getInstance().getFormat("eml://ecoinformatics.org/eml-2.1.0").getFormatId() || |
|
3635 |
fmtid == ObjectFormatCache.getInstance().getFormat("eml://ecoinformatics.org/eml-2.1.1").getFormatId() ) { |
|
3636 |
|
|
3637 |
try { |
|
3638 |
|
|
3639 |
DatabaseConnectionPoolInterface connectionPool = MetacatDatabaseConnectionPoolFactory.getDatabaseConnectionPoolInterface(); |
|
3640 |
DataManager dataManager = DataManager.getInstance(connectionPool, connectionPool.getDBAdapterName()); |
|
3641 |
DataPackage dataPackage = dataManager.parseMetadata(inputStream); |
|
3642 |
|
|
3643 |
// iterate through the data objects in the EML doc and add sysmeta |
|
3644 |
logMetacat.debug("In createSystemMetadata() the number of data " + |
|
3645 |
"entities is: " + dataPackage.getEntityNumber()); |
|
3646 |
|
|
3647 |
// iterate through data objects described by the EML |
|
3648 |
for (int j = 0; j < dataPackage.getEntityList().length; j++) { |
|
3649 |
|
|
3650 |
|
|
3651 |
String dataDocUrl = dataPackage.getEntityList()[j].getURL(); |
|
3652 |
String dataDocMimeType = dataPackage.getEntityList()[j].getDataFormat(); |
|
3653 |
// default to binary |
|
3654 |
if (dataDocMimeType == null) { |
|
3655 |
dataDocMimeType = |
|
3656 |
ObjectFormatCache.getInstance().getFormat("application/octet-stream").getFormatId().getValue(); |
|
3657 |
} |
|
3658 |
String dataDocLocalId = ""; |
|
3659 |
logMetacat.debug("Data local ID: " + dataDocLocalId); |
|
3660 |
logMetacat.debug("Data URL : " + dataDocUrl); |
|
3661 |
logMetacat.debug("Data mime : " + dataDocMimeType); |
|
3662 |
|
|
3663 |
//we only handle ecogrid urls right now |
|
3664 |
String ecogridPrefix = "ecogrid://knb/"; |
|
3665 |
if ( dataDocUrl.trim().startsWith(ecogridPrefix) ) { |
|
3666 |
dataDocLocalId = |
|
3667 |
dataDocUrl.substring(dataDocUrl.indexOf(ecogridPrefix) + ecogridPrefix.length()); |
|
3668 |
|
|
3669 |
// look up the guid for the data |
|
3670 |
String dataDocid = DocumentUtil.getSmartDocId(dataDocLocalId); |
|
3671 |
int dataRev = DocumentUtil.getRevisionFromAccessionNumber(dataDocLocalId); |
|
3672 |
|
|
3673 |
SystemMetadata dataSysMeta = null; |
|
3674 |
// check if data system metadata exists |
|
3675 |
String dataGuidString = null; |
|
3676 |
try { |
|
3677 |
dataGuidString = IdentifierManager.getInstance().getGUID(dataDocid, dataRev); |
|
3678 |
dataSysMeta = IdentifierManager.getInstance().getSystemMetadata(dataGuidString); |
|
3679 |
} catch ( McdbDocNotFoundException nf ) { |
|
3680 |
// System metadata for data doesn't exist yet, so create it |
|
3681 |
logMetacat.debug("There was not an existing system metadata " + "document for " + dataDocLocalId); |
|
3682 |
try { |
|
3683 |
logMetacat.debug("Creating a system metadata " + "document for " + dataDocLocalId); |
|
3684 |
dataSysMeta = createSystemMetadata(dataDocLocalId); |
|
3685 |
|
|
3686 |
// now look it up again |
|
3687 |
dataGuidString = IdentifierManager.getInstance().getGUID(dataDocid, dataRev); |
|
3688 |
|
|
3689 |
//set the guid |
|
3690 |
Identifier dataGuid = new Identifier(); |
|
3691 |
dataGuid.setValue(dataGuidString); |
|
3692 |
|
|
3693 |
// set object format |
|
3694 |
logMetacat.debug("Updating system metadata for " + dataGuid.getValue() + " to " + dataDocMimeType); |
|
3695 |
try { |
|
3696 |
ObjectFormatIdentifier fmt = |
|
3697 |
ObjectFormatCache.getInstance().getFormat(dataDocMimeType).getFormatId(); |
|
3698 |
dataSysMeta.setFormatId(fmt); |
|
3699 |
|
|
3700 |
} catch (NotFound nfe) { |
|
3701 |
logMetacat.debug("Couldn't find format identifier for: " + |
|
3702 |
dataDocMimeType + ". Setting it to application/octet-stream."); |
|
3703 |
ObjectFormatIdentifier newFmtid = new ObjectFormatIdentifier(); |
|
3704 |
newFmtid.setValue("application/octet-stream"); |
|
3705 |
|
|
3706 |
} |
|
3707 |
|
|
3708 |
// update the values |
|
3709 |
HazelcastService.getInstance().getSystemMetadataMap().put(dataSysMeta.getIdentifier(), dataSysMeta); |
|
3710 |
|
|
3711 |
} catch ( McdbDocNotFoundException mdnf) { |
|
3712 |
mdnf.printStackTrace(); |
|
3713 |
throw mdnf; |
|
3714 |
} catch ( NumberFormatException nfe) { |
|
3715 |
nfe.printStackTrace(); |
|
3716 |
throw nfe; |
|
3717 |
} catch ( AccessionNumberException ane) { |
|
3718 |
ane.printStackTrace(); |
|
3719 |
throw ane; |
|
3720 |
} catch ( SQLException sqle) { |
|
3721 |
sqle.printStackTrace(); |
|
3722 |
throw sqle; |
|
3723 |
} catch ( NoSuchAlgorithmException nsae) { |
|
3724 |
nsae.printStackTrace(); |
|
3725 |
throw nsae; |
|
3726 |
} catch ( IOException ioe) { |
|
3727 |
ioe.printStackTrace(); |
|
3728 |
throw ioe; |
|
3729 |
} catch ( PropertyNotFoundException pnfe) { |
|
3730 |
pnfe.printStackTrace(); |
|
3731 |
throw pnfe; |
|
3732 |
} catch ( BaseException be) { |
|
3733 |
be.printStackTrace(); |
|
3734 |
throw be; |
|
3735 |
} |
|
3736 |
} |
|
3737 |
|
|
3738 |
} // end if() |
|
3739 |
|
|
3740 |
} // end for() |
|
3741 |
|
|
3742 |
} catch ( ParserConfigurationException pce ) { |
|
3743 |
logMetacat.debug("There was a problem parsing the EML document. " + |
|
3744 |
"The error message was: " + pce.getMessage()); |
|
3745 |
|
|
3746 |
} catch ( SAXException saxe ) { |
|
3747 |
logMetacat.debug("There was a problem traversing the EML document. " + |
|
3748 |
"The error message was: " + saxe.getMessage()); |
|
3749 |
|
|
3750 |
} catch ( XPathExpressionException xpee ) { |
|
3751 |
logMetacat.debug("There was a problem searching the EML document. " + |
|
3752 |
"The error message was: " + xpee.getMessage()); |
|
3753 |
} catch ( Exception e ) { |
|
3754 |
logMetacat.debug("There was a problem creating System Metadata. " + |
|
3755 |
"The error message was: " + e.getMessage()); |
|
3756 |
} // end try() |
|
3757 |
|
|
3758 |
} // end if() |
|
3759 |
|
|
3760 |
|
|
3761 |
//create the checksum |
|
3762 |
inputStream = read(localId); |
|
3763 |
String algorithm = "MD5"; |
|
3764 |
Checksum checksum = ChecksumUtil.checksum(inputStream, algorithm); |
|
3765 |
sysMeta.setChecksum(checksum); |
|
3766 |
|
|
3767 |
//set the size |
|
3768 |
inputStream = read(localId); |
|
3769 |
String sizeStr = new Long(sizeOfStream(inputStream)).toString(); |
|
3770 |
sysMeta.setSize(new BigInteger(sizeStr)); |
|
3771 |
|
|
3772 |
//submitter |
|
3773 |
Subject subject = new Subject(); |
|
3774 |
subject.setValue((String) docInfo.get("user_owner")); |
|
3775 |
sysMeta.setSubmitter(subject); |
|
3776 |
sysMeta.setRightsHolder(subject); |
|
3777 |
|
|
3778 |
try { |
|
3779 |
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-DD"); |
|
3780 |
dateFormat.setTimeZone(TimeZone.getDefault()); |
|
3781 |
|
|
3782 |
Date dateCreated = dateFormat.parse((String) docInfo.get("date_created")); |
|
3783 |
sysMeta.setDateUploaded(dateCreated); |
|
3784 |
Date dateUpdated = dateFormat.parse((String) docInfo.get("date_updated")); |
|
3785 |
sysMeta.setDateSysMetadataModified(dateUpdated); |
|
3786 |
|
|
3787 |
} catch (ParseException pe) { |
|
3788 |
logMetacat.debug("There was a problem parsing a Metacat date. The " + |
|
3789 |
"error message was: " + pe.getMessage()); |
|
3790 |
Date dateCreated = new Date(); |
|
3791 |
sysMeta.setDateUploaded(dateCreated); |
|
3792 |
Date dateUpdated = new Date(); |
|
3793 |
sysMeta.setDateSysMetadataModified(dateUpdated); |
|
3794 |
|
|
3795 |
} |
|
3796 |
NodeReference nr = new NodeReference(); |
|
3797 |
nr.setValue(PropertyService.getProperty("dataone.memberNodeId")); |
|
3798 |
sysMeta.setOriginMemberNode(nr); |
|
3799 |
sysMeta.setAuthoritativeMemberNode(nr); |
|
3800 |
|
|
3801 |
return sysMeta; |
|
3802 |
} |
|
3803 |
|
|
3804 |
/* |
|
3805 |
* Find the size (in bytes) of a stream. Note: This needs to refactored out |
|
3806 |
* of MetacatHandler and into a utility when stream i/o in Metacat is |
|
3807 |
* evaluated. |
|
3808 |
* |
|
3809 |
* @param is The InputStream of bytes |
|
3810 |
* @return size The size in bytes of the input stream as a long |
|
3811 |
* @throws IOException |
|
3812 |
*/ |
|
3813 |
private static long sizeOfStream(InputStream is) |
|
3814 |
throws IOException { |
|
3815 |
|
|
3816 |
long size = 0; |
|
3817 |
byte[] b = new byte[1024]; |
|
3818 |
int numread = is.read(b, 0, 1024); |
|
3819 |
while(numread != -1) |
|
3820 |
{ |
|
3821 |
size += numread; |
|
3822 |
numread = is.read(b, 0, 1024); |
|
3823 |
} |
|
3824 |
return size; |
|
3825 |
|
|
3826 |
} |
|
3827 | 3498 |
|
3828 | 3499 |
} |
src/edu/ucsb/nceas/metacat/dataone/SystemMetadataFactory.java | ||
---|---|---|
1 |
/** |
|
2 |
* '$RCSfile$' |
|
3 |
* Purpose: A Class for upgrading the database to version 1.5 |
|
4 |
* Copyright: 2000 Regents of the University of California and the |
|
5 |
* National Center for Ecological Analysis and Synthesis |
|
6 |
* Authors: Saurabh Garg |
|
7 |
* |
|
8 |
* '$Author$' |
|
9 |
* '$Date$' |
|
10 |
* '$Revision$' |
|
11 |
* |
|
12 |
* This program is free software; you can redistribute it and/or modify |
|
13 |
* it under the terms of the GNU General Public License as published by |
|
14 |
* the Free Software Foundation; either version 2 of the License, or |
|
15 |
* (at your option) any later version. |
|
16 |
* |
|
17 |
* This program is distributed in the hope that it will be useful, |
|
18 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
19 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
20 |
* GNU General Public License for more details. |
|
21 |
* |
|
22 |
* You should have received a copy of the GNU General Public License |
|
23 |
* along with this program; if not, write to the Free Software |
|
24 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
25 |
*/ |
|
26 |
package edu.ucsb.nceas.metacat.dataone; |
|
27 |
|
|
28 |
import java.io.IOException; |
|
29 |
import java.io.InputStream; |
|
30 |
import java.math.BigInteger; |
|
31 |
import java.security.NoSuchAlgorithmException; |
|
32 |
import java.sql.SQLException; |
|
33 |
import java.text.ParseException; |
|
34 |
import java.text.SimpleDateFormat; |
|
35 |
import java.util.Date; |
|
36 |
import java.util.Hashtable; |
|
37 |
import java.util.TimeZone; |
|
38 |
|
|
39 |
import javax.xml.parsers.ParserConfigurationException; |
|
40 |
import javax.xml.xpath.XPathExpressionException; |
|
41 |
|
|
42 |
import org.apache.log4j.Logger; |
|
43 |
import org.dataone.client.ObjectFormatCache; |
|
44 |
import org.dataone.service.exceptions.BaseException; |
|
45 |
import org.dataone.service.exceptions.NotFound; |
|
46 |
import org.dataone.service.types.v1.Checksum; |
|
47 |
import org.dataone.service.types.v1.Identifier; |
|
48 |
import org.dataone.service.types.v1.NodeReference; |
|
49 |
import org.dataone.service.types.v1.ObjectFormatIdentifier; |
|
50 |
import org.dataone.service.types.v1.Subject; |
|
51 |
import org.dataone.service.types.v1.SystemMetadata; |
|
52 |
import org.dataone.service.types.v1.util.ChecksumUtil; |
|
53 |
import org.ecoinformatics.datamanager.DataManager; |
|
54 |
import org.ecoinformatics.datamanager.database.DatabaseConnectionPoolInterface; |
|
55 |
import org.ecoinformatics.datamanager.parser.DataPackage; |
|
56 |
import org.jibx.runtime.JiBXException; |
|
57 |
import org.xml.sax.SAXException; |
|
58 |
|
|
59 |
import edu.ucsb.nceas.metacat.AccessionNumber; |
|
60 |
import edu.ucsb.nceas.metacat.AccessionNumberException; |
|
61 |
import edu.ucsb.nceas.metacat.IdentifierManager; |
|
62 |
import edu.ucsb.nceas.metacat.McdbDocNotFoundException; |
|
63 |
import edu.ucsb.nceas.metacat.McdbException; |
|
64 |
import edu.ucsb.nceas.metacat.MetacatHandler; |
|
65 |
import edu.ucsb.nceas.metacat.client.InsufficientKarmaException; |
|
66 |
import edu.ucsb.nceas.metacat.dataone.hazelcast.HazelcastService; |
|
67 |
import edu.ucsb.nceas.metacat.dataquery.MetacatDatabaseConnectionPoolFactory; |
|
68 |
import edu.ucsb.nceas.metacat.properties.PropertyService; |
|
69 |
import edu.ucsb.nceas.metacat.util.DocumentUtil; |
|
70 |
import edu.ucsb.nceas.utilities.ParseLSIDException; |
|
71 |
import edu.ucsb.nceas.utilities.PropertyNotFoundException; |
|
72 |
|
|
73 |
public class SystemMetadataFactory { |
|
74 |
|
|
75 |
private static Logger logMetacat = Logger.getLogger(SystemMetadataFactory.class); |
|
76 |
|
|
77 |
/** |
|
78 |
* Creates a system metadata object for insertion into metacat |
|
79 |
* |
|
80 |
* @param localId The local document identifier |
|
81 |
* @param user The user submitting the system metadata document |
|
82 |
* @param groups The groups the user belongs to |
|
83 |
* |
|
84 |
* @return sysMeta The system metadata object created |
|
85 |
*/ |
|
86 |
public static SystemMetadata createSystemMetadata(String localId) |
|
87 |
throws McdbException, McdbDocNotFoundException, SQLException, |
|
88 |
IOException, AccessionNumberException, ClassNotFoundException, |
|
89 |
InsufficientKarmaException, ParseLSIDException, PropertyNotFoundException, |
|
90 |
BaseException, NoSuchAlgorithmException, JiBXException |
|
91 |
{ |
|
92 |
logMetacat.debug("MetacatHandler.createSystemMetadata() called."); |
|
93 |
logMetacat.debug("provided localId: " + localId); |
|
94 |
|
|
95 |
// create system metadata for the document |
|
96 |
SystemMetadata sysMeta = new SystemMetadata(); |
|
97 |
sysMeta.setSerialVersion(BigInteger.valueOf(1)); |
|
98 |
int rev = IdentifierManager.getInstance().getLatestRevForLocalId(localId); |
|
99 |
AccessionNumber accNum = new AccessionNumber(localId, "NONE"); |
|
100 |
String guid = null; |
|
101 |
try { |
|
102 |
// get the guid if it exists |
|
103 |
guid = IdentifierManager.getInstance().getGUID(accNum.getDocid(), rev); |
|
104 |
} catch ( McdbDocNotFoundException dnfe ) { |
|
105 |
// otherwise create the mapping |
|
106 |
logMetacat.debug("There was a problem getting the guid from " + |
|
107 |
"the given localId (docid and revision). The error message was: " + dnfe.getMessage()); |
|
108 |
logMetacat.debug("No guid in the identifier table. adding it for " + localId); |
|
109 |
IdentifierManager.getInstance().createMapping(localId, localId); |
|
110 |
logMetacat.debug("Mapping created for " + localId); |
|
111 |
logMetacat.debug("accessionNumber: " + accNum); |
|
112 |
guid = IdentifierManager.getInstance().getGUID(accNum.getDocid(), rev); |
|
113 |
} |
|
114 |
Identifier identifier = new Identifier(); |
|
115 |
identifier.setValue(guid); |
|
116 |
|
|
117 |
//set the id |
|
118 |
sysMeta.setIdentifier(identifier); |
|
119 |
|
|
120 |
// get the data or metadata object |
|
121 |
InputStream inputStream; |
|
122 |
try { |
|
123 |
inputStream = MetacatHandler.read(localId); |
|
124 |
} catch ( ParseLSIDException ple ) { |
|
125 |
logMetacat.debug("There was a problem parsing the LSID from " + |
|
126 |
localId + ". The error message was: " + ple.getMessage()); |
|
127 |
throw ple; |
|
128 |
|
|
129 |
} catch ( PropertyNotFoundException pnfe ) { |
|
130 |
logMetacat.debug("There was a problem finding a property. " + |
|
131 |
"The error message was: " + pnfe.getMessage()); |
|
132 |
throw pnfe; |
|
133 |
|
|
134 |
} catch ( McdbException me ) { |
|
135 |
logMetacat.debug("There was a Metacat problem. " + |
|
136 |
"The error message was: " + me.getMessage()); |
|
137 |
throw me; |
|
138 |
|
|
139 |
} catch ( SQLException sqle ) { |
|
140 |
logMetacat.debug("There was a SQL problem. " + |
|
141 |
"The error message was: " + sqle.getMessage()); |
|
142 |
throw sqle; |
|
143 |
|
|
144 |
} catch ( ClassNotFoundException cnfe ) { |
|
145 |
logMetacat.debug("There was a problem finding a class. " + |
|
146 |
"The error message was: " + cnfe.getMessage()); |
|
147 |
throw cnfe; |
|
148 |
|
|
149 |
} catch ( IOException ioe ) { |
|
150 |
logMetacat.debug("There was an I/O exception. " + |
|
151 |
"The error message was: " + ioe.getMessage()); |
|
152 |
throw ioe; |
|
153 |
|
|
154 |
} // end try() |
|
155 |
|
|
156 |
// get additional docinfo |
|
157 |
Hashtable<String, Object> docInfo = IdentifierManager.getInstance().getDocumentInfo(localId); |
|
158 |
//set the default object format |
|
159 |
String doctype = (String) docInfo.get("doctype"); |
|
160 |
ObjectFormatIdentifier fmtid = null; |
|
161 |
|
|
162 |
// set the object format, fall back to defaults |
|
163 |
try { |
|
164 |
fmtid = ObjectFormatCache.getInstance().getFormat(doctype).getFormatId(); |
|
165 |
|
|
166 |
} catch (NotFound nfe) { |
|
167 |
|
|
168 |
try { |
|
169 |
// format is not registered, use default |
|
170 |
if (doctype.trim().equals("BIN")) { |
|
171 |
fmtid = ObjectFormatCache.getInstance().getFormat( |
|
172 |
"application/octet-stream").getFormatId(); |
|
173 |
|
|
174 |
} else { |
|
175 |
fmtid = ObjectFormatCache.getInstance().getFormat("text/plain").getFormatId(); |
|
176 |
} |
|
177 |
|
|
178 |
} catch (NotFound nf) { |
|
179 |
logMetacat.error("There was a problem getting the default format " + |
|
180 |
"from the ObjectFormatCache: " + nf.getMessage()); |
|
181 |
throw nf; |
|
182 |
} |
|
183 |
|
|
184 |
} |
|
185 |
|
|
186 |
sysMeta.setFormatId(fmtid); |
|
187 |
logMetacat.debug("The ObjectFormat for " + localId + " is " + fmtid.getValue()); |
|
188 |
|
|
189 |
// further parse EML documents to get data object format, |
|
190 |
// describes and describedBy information |
|
191 |
if ( fmtid == ObjectFormatCache.getInstance().getFormat("eml://ecoinformatics.org/eml-2.0.0").getFormatId() || |
|
192 |
fmtid == ObjectFormatCache.getInstance().getFormat("eml://ecoinformatics.org/eml-2.0.1").getFormatId() || |
|
193 |
fmtid == ObjectFormatCache.getInstance().getFormat("eml://ecoinformatics.org/eml-2.1.0").getFormatId() || |
|
194 |
fmtid == ObjectFormatCache.getInstance().getFormat("eml://ecoinformatics.org/eml-2.1.1").getFormatId() ) { |
|
195 |
|
|
196 |
try { |
|
197 |
|
|
198 |
DatabaseConnectionPoolInterface connectionPool = MetacatDatabaseConnectionPoolFactory.getDatabaseConnectionPoolInterface(); |
|
199 |
DataManager dataManager = DataManager.getInstance(connectionPool, connectionPool.getDBAdapterName()); |
|
200 |
DataPackage dataPackage = dataManager.parseMetadata(inputStream); |
|
201 |
|
|
202 |
// iterate through the data objects in the EML doc and add sysmeta |
|
203 |
logMetacat.debug("In createSystemMetadata() the number of data " + |
|
204 |
"entities is: " + dataPackage.getEntityNumber()); |
|
205 |
|
|
206 |
// iterate through data objects described by the EML |
|
207 |
for (int j = 0; j < dataPackage.getEntityList().length; j++) { |
|
208 |
|
|
209 |
|
|
210 |
String dataDocUrl = dataPackage.getEntityList()[j].getURL(); |
|
211 |
String dataDocMimeType = dataPackage.getEntityList()[j].getDataFormat(); |
|
212 |
// default to binary |
|
213 |
if (dataDocMimeType == null) { |
|
214 |
dataDocMimeType = |
|
215 |
ObjectFormatCache.getInstance().getFormat("application/octet-stream").getFormatId().getValue(); |
|
216 |
} |
|
217 |
String dataDocLocalId = ""; |
|
218 |
logMetacat.debug("Data local ID: " + dataDocLocalId); |
|
219 |
logMetacat.debug("Data URL : " + dataDocUrl); |
|
220 |
logMetacat.debug("Data mime : " + dataDocMimeType); |
|
221 |
|
|
222 |
//we only handle ecogrid urls right now |
|
223 |
String ecogridPrefix = "ecogrid://knb/"; |
|
224 |
if ( dataDocUrl.trim().startsWith(ecogridPrefix) ) { |
|
225 |
dataDocLocalId = |
|
226 |
dataDocUrl.substring(dataDocUrl.indexOf(ecogridPrefix) + ecogridPrefix.length()); |
|
227 |
|
|
228 |
// look up the guid for the data |
|
229 |
String dataDocid = DocumentUtil.getSmartDocId(dataDocLocalId); |
|
230 |
int dataRev = DocumentUtil.getRevisionFromAccessionNumber(dataDocLocalId); |
|
231 |
|
|
232 |
SystemMetadata dataSysMeta = null; |
|
233 |
// check if data system metadata exists |
|
234 |
String dataGuidString = null; |
|
235 |
try { |
|
236 |
dataGuidString = IdentifierManager.getInstance().getGUID(dataDocid, dataRev); |
|
237 |
dataSysMeta = IdentifierManager.getInstance().getSystemMetadata(dataGuidString); |
|
238 |
} catch ( McdbDocNotFoundException nf ) { |
|
239 |
// System metadata for data doesn't exist yet, so create it |
|
240 |
logMetacat.debug("There was not an existing system metadata " + "document for " + dataDocLocalId); |
|
241 |
try { |
|
242 |
logMetacat.debug("Creating a system metadata " + "document for " + dataDocLocalId); |
|
243 |
dataSysMeta = createSystemMetadata(dataDocLocalId); |
|
244 |
|
|
245 |
// now look it up again |
|
246 |
dataGuidString = IdentifierManager.getInstance().getGUID(dataDocid, dataRev); |
|
247 |
|
|
248 |
//set the guid |
|
249 |
Identifier dataGuid = new Identifier(); |
|
250 |
dataGuid.setValue(dataGuidString); |
|
251 |
|
|
252 |
// set object format |
|
253 |
logMetacat.debug("Updating system metadata for " + dataGuid.getValue() + " to " + dataDocMimeType); |
|
254 |
try { |
|
255 |
ObjectFormatIdentifier fmt = |
|
256 |
ObjectFormatCache.getInstance().getFormat(dataDocMimeType).getFormatId(); |
|
257 |
dataSysMeta.setFormatId(fmt); |
|
258 |
|
|
259 |
} catch (NotFound nfe) { |
|
260 |
logMetacat.debug("Couldn't find format identifier for: " + |
|
261 |
dataDocMimeType + ". Setting it to application/octet-stream."); |
|
262 |
ObjectFormatIdentifier newFmtid = new ObjectFormatIdentifier(); |
|
263 |
newFmtid.setValue("application/octet-stream"); |
|
264 |
|
|
265 |
} |
|
266 |
|
|
267 |
// update the values |
|
268 |
HazelcastService.getInstance().getSystemMetadataMap().put(dataSysMeta.getIdentifier(), dataSysMeta); |
|
269 |
|
|
270 |
} catch ( McdbDocNotFoundException mdnf) { |
|
271 |
mdnf.printStackTrace(); |
|
272 |
throw mdnf; |
|
273 |
} catch ( NumberFormatException nfe) { |
|
274 |
nfe.printStackTrace(); |
|
275 |
throw nfe; |
|
276 |
} catch ( AccessionNumberException ane) { |
|
277 |
ane.printStackTrace(); |
|
278 |
throw ane; |
|
279 |
} catch ( SQLException sqle) { |
|
280 |
sqle.printStackTrace(); |
|
281 |
throw sqle; |
|
282 |
} catch ( NoSuchAlgorithmException nsae) { |
|
283 |
nsae.printStackTrace(); |
|
284 |
throw nsae; |
|
285 |
} catch ( IOException ioe) { |
|
286 |
ioe.printStackTrace(); |
|
287 |
throw ioe; |
|
288 |
} catch ( PropertyNotFoundException pnfe) { |
|
289 |
pnfe.printStackTrace(); |
|
290 |
throw pnfe; |
|
291 |
} catch ( BaseException be) { |
|
292 |
be.printStackTrace(); |
|
293 |
throw be; |
|
294 |
} |
|
295 |
} |
|
296 |
|
|
297 |
} // end if() |
|
298 |
|
|
299 |
} // end for() |
|
300 |
|
|
301 |
} catch ( ParserConfigurationException pce ) { |
|
302 |
logMetacat.debug("There was a problem parsing the EML document. " + |
|
303 |
"The error message was: " + pce.getMessage()); |
|
304 |
|
|
305 |
} catch ( SAXException saxe ) { |
|
306 |
logMetacat.debug("There was a problem traversing the EML document. " + |
|
307 |
"The error message was: " + saxe.getMessage()); |
|
308 |
|
|
309 |
} catch ( XPathExpressionException xpee ) { |
|
310 |
logMetacat.debug("There was a problem searching the EML document. " + |
|
311 |
"The error message was: " + xpee.getMessage()); |
|
312 |
} catch ( Exception e ) { |
|
313 |
logMetacat.debug("There was a problem creating System Metadata. " + |
|
314 |
"The error message was: " + e.getMessage()); |
|
315 |
} // end try() |
|
316 |
|
|
317 |
} // end if() |
|
318 |
|
|
319 |
|
|
320 |
//create the checksum |
|
321 |
inputStream = MetacatHandler.read(localId); |
|
322 |
String algorithm = "MD5"; |
|
323 |
Checksum checksum = ChecksumUtil.checksum(inputStream, algorithm); |
|
324 |
sysMeta.setChecksum(checksum); |
|
325 |
|
|
326 |
//set the size |
|
327 |
inputStream = MetacatHandler.read(localId); |
|
328 |
String sizeStr = new Long(sizeOfStream(inputStream)).toString(); |
|
329 |
sysMeta.setSize(new BigInteger(sizeStr)); |
|
330 |
|
|
331 |
//submitter |
|
332 |
Subject subject = new Subject(); |
|
333 |
subject.setValue((String) docInfo.get("user_owner")); |
|
334 |
sysMeta.setSubmitter(subject); |
|
335 |
sysMeta.setRightsHolder(subject); |
|
336 |
|
|
337 |
try { |
|
338 |
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-DD"); |
|
339 |
dateFormat.setTimeZone(TimeZone.getDefault()); |
|
340 |
|
|
341 |
Date dateCreated = dateFormat.parse((String) docInfo.get("date_created")); |
|
342 |
sysMeta.setDateUploaded(dateCreated); |
|
343 |
Date dateUpdated = dateFormat.parse((String) docInfo.get("date_updated")); |
|
344 |
sysMeta.setDateSysMetadataModified(dateUpdated); |
|
345 |
|
|
346 |
} catch (ParseException pe) { |
|
347 |
logMetacat.debug("There was a problem parsing a Metacat date. The " + |
|
348 |
"error message was: " + pe.getMessage()); |
|
349 |
Date dateCreated = new Date(); |
|
350 |
sysMeta.setDateUploaded(dateCreated); |
|
351 |
Date dateUpdated = new Date(); |
|
352 |
sysMeta.setDateSysMetadataModified(dateUpdated); |
|
353 |
|
|
354 |
} |
|
355 |
NodeReference nr = new NodeReference(); |
|
356 |
nr.setValue(PropertyService.getProperty("dataone.memberNodeId")); |
|
357 |
sysMeta.setOriginMemberNode(nr); |
|
358 |
sysMeta.setAuthoritativeMemberNode(nr); |
|
359 |
|
|
360 |
return sysMeta; |
|
361 |
} |
|
362 |
|
|
363 |
/* |
|
364 |
* Find the size (in bytes) of a stream. Note: This needs to refactored out |
|
365 |
* of MetacatHandler and into a utility when stream i/o in Metacat is |
|
366 |
* evaluated. |
|
367 |
* |
|
368 |
* @param is The InputStream of bytes |
|
369 |
* @return size The size in bytes of the input stream as a long |
|
370 |
* @throws IOException |
|
371 |
*/ |
|
372 |
private static long sizeOfStream(InputStream is) |
|
373 |
throws IOException { |
|
374 |
|
|
375 |
long size = 0; |
|
376 |
byte[] b = new byte[1024]; |
|
377 |
int numread = is.read(b, 0, 1024); |
|
378 |
while(numread != -1) |
|
379 |
{ |
|
380 |
size += numread; |
|
381 |
numread = is.read(b, 0, 1024); |
|
382 |
} |
|
383 |
return size; |
|
384 |
|
|
385 |
} |
|
386 |
} |
|
0 | 387 |
src/edu/ucsb/nceas/metacat/admin/upgrade/GenerateSystemMetadata.java | ||
---|---|---|
44 | 44 |
import edu.ucsb.nceas.metacat.AccessionNumberException; |
45 | 45 |
import edu.ucsb.nceas.metacat.IdentifierManager; |
46 | 46 |
import edu.ucsb.nceas.metacat.McdbDocNotFoundException; |
47 |
import edu.ucsb.nceas.metacat.MetacatHandler; |
|
48 | 47 |
import edu.ucsb.nceas.metacat.admin.AdminException; |
48 |
import edu.ucsb.nceas.metacat.dataone.SystemMetadataFactory; |
|
49 | 49 |
import edu.ucsb.nceas.metacat.properties.PropertyService; |
50 | 50 |
import edu.ucsb.nceas.utilities.PropertyNotFoundException; |
51 | 51 |
import edu.ucsb.nceas.utilities.SortedProperties; |
... | ... | |
138 | 138 |
|
139 | 139 |
//generate required system metadata fields from the document |
140 | 140 |
try { |
141 |
sm = MetacatHandler.createSystemMetadata(localId);
|
|
141 |
sm = SystemMetadataFactory.createSystemMetadata(localId);
|
|
142 | 142 |
} catch (Exception e1) { |
143 | 143 |
e1.printStackTrace(); |
144 | 144 |
ServiceFailure sf = new ServiceFailure("00","Exception in generateMissingSystemMetadata: " + |
Also available in: Unified diff
refactor SystemMetadata creation into separate class from the MetacatHandler -- this will be shared by upgrade code and normal metacat api.