Revision 6097
Added by ben leinfelder almost 13 years ago
MetacatHandler.java | ||
---|---|---|
123 | 123 |
import org.jibx.runtime.BindingDirectory; |
124 | 124 |
import org.jibx.runtime.IBindingFactory; |
125 | 125 |
import org.jibx.runtime.IMarshallingContext; |
126 |
import org.jibx.runtime.IUnmarshallingContext; |
|
127 | 126 |
import org.jibx.runtime.JiBXException; |
128 | 127 |
|
129 | 128 |
import org.xml.sax.SAXException; |
... | ... | |
133 | 132 |
import com.oreilly.servlet.multipart.ParamPart; |
134 | 133 |
import com.oreilly.servlet.multipart.Part; |
135 | 134 |
|
136 |
import org.dataone.service.types.AuthToken; |
|
137 | 135 |
import org.dataone.service.types.Checksum; |
138 | 136 |
import org.dataone.service.types.ChecksumAlgorithm; |
139 | 137 |
import org.dataone.service.types.Identifier; |
... | ... | |
1867 | 1865 |
try { |
1868 | 1866 |
// handle updates |
1869 | 1867 |
identifier.setValue(im.getGUID(newdocid, rev)); |
1870 |
sysMeta = getSystemMetadata(identifier, user, groups); |
|
1871 |
sysMetaLocalId = insertOrUpdateSystemMetadata( |
|
1872 |
sysMeta, "update", user, groups); |
|
1868 |
sysMeta = getSystemMetadata(identifier); |
|
1869 |
IdentifierManager.getInstance().insertAdditionalSystemMetadataFields(sysMeta); |
|
1873 | 1870 |
|
1874 |
} catch ( PropertyNotFoundException pnfe) { |
|
1875 |
logMetacat.error("There was a problem getting the server " + |
|
1876 |
"url properties: " + pnfe.getMessage()); |
|
1877 |
|
|
1878 | 1871 |
} catch ( McdbDocNotFoundException mnfe) { |
1879 | 1872 |
|
1880 | 1873 |
// handle inserts |
1881 | 1874 |
try { |
1882 | 1875 |
sysMeta = createSystemMetadata(newdocid, user, groups); |
1883 |
sysMetaLocalId = insertOrUpdateSystemMetadata( |
|
1884 |
sysMeta, "insert", user, groups); |
|
1876 |
IdentifierManager.getInstance().insertAdditionalSystemMetadataFields(sysMeta); |
|
1885 | 1877 |
|
1886 | 1878 |
} catch ( McdbDocNotFoundException dnfe ) { |
1887 | 1879 |
logMetacat.debug( |
... | ... | |
3516 | 3508 |
} |
3517 | 3509 |
|
3518 | 3510 |
/** |
3519 |
* Serialize a system metadata doc. Note: This needs to refactored out |
|
3520 |
* of MetacatHandler and into a utitlity when stream i/o in Metacat is |
|
3521 |
* evaluated. |
|
3522 |
* |
|
3523 |
* @param sysmeta The system metadata object to be serialized |
|
3524 |
* @return sysMetaOut The system metadata XML document as a ByteArrayOutputStream |
|
3525 |
* @throws JiBXException |
|
3526 |
*/ |
|
3527 |
private static ByteArrayOutputStream serializeSystemMetadata(SystemMetadata sysmeta) |
|
3528 |
throws JiBXException { |
|
3529 |
|
|
3530 |
IBindingFactory bfact; |
|
3531 |
ByteArrayOutputStream sysmetaOut = null; |
|
3532 |
|
|
3533 |
try { |
|
3534 |
bfact = BindingDirectory.getFactory(SystemMetadata.class); |
|
3535 |
IMarshallingContext mctx = bfact.createMarshallingContext(); |
|
3536 |
sysmetaOut = new ByteArrayOutputStream(); |
|
3537 |
mctx.marshalDocument(sysmeta, "UTF-8", null, sysmetaOut); |
|
3538 |
} catch (JiBXException jxe) { |
|
3539 |
throw jxe; |
|
3540 |
|
|
3541 |
} |
|
3542 |
|
|
3543 |
return sysmetaOut; |
|
3544 |
} |
|
3545 |
|
|
3546 |
/** |
|
3547 | 3511 |
* Creates a system metadata object for insertion into metacat |
3548 | 3512 |
* |
3549 | 3513 |
* @param localId The local document identifier |
... | ... | |
3570 | 3534 |
SystemMetadata sysMeta = new SystemMetadata(); |
3571 | 3535 |
InputStream inputStream; |
3572 | 3536 |
int rev = im.getLatestRevForLocalId(localId); |
3537 |
AccessionNumber accNum = new AccessionNumber(localId, "NONE"); |
|
3573 | 3538 |
Identifier identifier = new Identifier(); |
3574 | 3539 |
|
3575 | 3540 |
try { |
3576 | 3541 |
// get the identifier if it exists |
3577 |
identifier.setValue(im.getGUID(localId, rev));
|
|
3542 |
identifier.setValue(im.getGUID(accNum.getDocid(), rev));
|
|
3578 | 3543 |
|
3579 | 3544 |
} catch ( McdbDocNotFoundException dnfe ) { |
3580 | 3545 |
// otherwise create the mapping |
... | ... | |
3583 | 3548 |
logMetacat.debug("No guid in the identifier table. adding it for " + localId); |
3584 | 3549 |
im.createMapping(localId, localId); |
3585 | 3550 |
logMetacat.debug("Mapping created for " + localId); |
3586 |
AccessionNumber accNum = new AccessionNumber(localId, "NONE"); |
|
3587 |
logMetacat.debug("accessionNumber: " + accNum); |
|
3551 |
logMetacat.debug("accessionNumber: " + accNum); |
|
3588 | 3552 |
identifier.setValue(im.getGUID(accNum.getDocid(), rev)); |
3589 | 3553 |
|
3590 | 3554 |
} |
... | ... | |
3692 | 3656 |
try { |
3693 | 3657 |
logMetacat.debug("Checking for existing system metadata for " + |
3694 | 3658 |
dataDocId.getValue()); |
3695 |
dataSysMeta = this.getSystemMetadata(dataDocId, username, groups);
|
|
3659 |
dataSysMeta = this.getSystemMetadata(dataDocId); |
|
3696 | 3660 |
// add describedBy sysmeta |
3697 | 3661 |
logMetacat.debug("Setting describedBy for " + dataDocId.getValue() + |
3698 | 3662 |
" to " + identifier.getValue()); |
... | ... | |
3702 | 3666 |
f = ObjectFormat.OCTET_STREAM; |
3703 | 3667 |
} |
3704 | 3668 |
dataSysMeta.setObjectFormat(f); |
3705 |
dataSysMetaId = insertOrUpdateSystemMetadata( |
|
3706 |
dataSysMeta, "update", username, groups); |
|
3669 |
IdentifierManager.getInstance().insertAdditionalSystemMetadataFields(dataSysMeta); |
|
3707 | 3670 |
|
3708 | 3671 |
} catch ( McdbDocNotFoundException nf ) { |
3709 | 3672 |
// System metadata for data doesn't exist |
... | ... | |
3729 | 3692 |
|
3730 | 3693 |
logMetacat.debug("Updating system metadata for " + |
3731 | 3694 |
dataDocId.getValue() + " to " + dataDocMimeType); |
3732 |
dataSysMetaId = insertOrUpdateSystemMetadata( |
|
3733 |
dataSysMeta, "insert", username, groups); |
|
3695 |
IdentifierManager.getInstance().insertAdditionalSystemMetadataFields(dataSysMeta); |
|
3734 | 3696 |
|
3735 | 3697 |
} catch ( McdbDocNotFoundException mdnf) { |
3736 | 3698 |
mdnf.printStackTrace(); |
... | ... | |
3759 | 3721 |
|
3760 | 3722 |
} |
3761 | 3723 |
|
3762 |
} catch ( InsufficientKarmaException ike ) { |
|
3763 |
logMetacat.debug("There was an access problem reading " + |
|
3764 |
localId + ". The error message was: " + ike.getMessage()); |
|
3765 |
throw ike; |
|
3766 |
|
|
3767 | 3724 |
} catch ( McdbException me ) { |
3768 | 3725 |
logMetacat.debug("There was a Metacat problem. " + |
3769 | 3726 |
"The error message was: " + me.getMessage()); |
3770 | 3727 |
throw me; |
3771 | 3728 |
|
3772 |
} catch ( JiBXException jxe ) { |
|
3773 |
logMetacat.debug("There was a problem deserializing the system " + |
|
3774 |
"metadata XML. The error message was: " + jxe.getMessage()); |
|
3775 |
throw jxe; |
|
3776 |
|
|
3777 | 3729 |
} // end try() |
3778 | 3730 |
|
3779 | 3731 |
} // end if() |
... | ... | |
3838 | 3790 |
return sysMeta; |
3839 | 3791 |
} |
3840 | 3792 |
|
3841 |
/* |
|
3842 |
* Inserts or updates system metadata documents in Metacat. Note: This |
|
3843 |
* needs to be refactored out of MetacatHandler and into a utitlity when |
|
3844 |
* stream i/o in Metacat is evaluated. |
|
3845 |
* |
|
3846 |
* @param sysMeta The system metadata object to process |
|
3847 |
* @param action The action to perform, insert or update |
|
3848 |
* @param user The username doing the document insert or update |
|
3849 |
* @param groups The groups the user belongs in |
|
3850 |
* |
|
3851 |
* @return localId The new docid of the inserted or updated document |
|
3852 |
* |
|
3853 |
* @throws SQLException |
|
3854 |
*/ |
|
3855 |
private String insertOrUpdateSystemMetadata(SystemMetadata sysMeta, |
|
3856 |
String action, String user, String[] groups) |
|
3857 |
throws SQLException, InsufficientKarmaException, JiBXException, |
|
3858 |
PropertyNotFoundException, McdbException, McdbDocNotFoundException { |
|
3859 |
|
|
3860 |
logMetacat.debug("MetacatHandler.insertOrUpdateSystemMetadata() called."); |
|
3861 |
|
|
3862 |
String metacatUrl = ""; |
|
3863 |
action = action.toUpperCase(); |
|
3864 |
|
|
3865 |
try { |
|
3866 |
String server = PropertyService.getProperty("server.name"); |
|
3867 |
String port = PropertyService.getProperty("server.httpPort"); |
|
3868 |
String context = PropertyService.getProperty("application.context"); |
|
3869 |
metacatUrl = "http://" + server + ":" + port + "/" + context; |
|
3870 |
|
|
3871 |
} catch ( PropertyNotFoundException pnfe ) { |
|
3872 |
logMetacat.error("Couldn't get the server url properties: " + |
|
3873 |
pnfe.getMessage()); |
|
3874 |
throw pnfe; |
|
3875 |
|
|
3876 |
} |
|
3877 |
|
|
3878 |
DocumentImplWrapper docImpl = new DocumentImplWrapper("", false); |
|
3879 |
DBConnection dbConn = null; |
|
3880 |
int serialNumber = -1; |
|
3881 |
String qformat = "xml"; |
|
3882 |
String xml = null; |
|
3883 |
String doc = null; |
|
3884 |
String localId = null; |
|
3885 |
String newAccNumber = null; |
|
3886 |
String pub = null; |
|
3887 |
StringReader dtd = null; |
|
3888 |
|
|
3889 |
IdentifierManager im = IdentifierManager.getInstance(); |
|
3890 |
Identifier sysMetaGuid = new Identifier(); |
|
3891 |
sysMetaGuid.setValue(DocumentUtil.generateDocumentId(1)); |
|
3892 |
sysMeta.setDateSysMetadataModified(new Date()); |
|
3893 |
|
|
3894 |
// either generate or get a system metadata localId |
|
3895 |
try { |
|
3896 |
if ( action.equals("INSERT") ) { |
|
3897 |
localId = im.generateLocalId(sysMetaGuid.getValue(), 1, true); |
|
3898 |
|
|
3899 |
} else if ( action.equals("UPDATE") ) { |
|
3900 |
localId = im.getSystemMetadataLocalId(sysMetaGuid.getValue()); |
|
3901 |
String docid = localId.substring(0, localId.lastIndexOf(".")); |
|
3902 |
String revString = |
|
3903 |
localId.substring(localId.lastIndexOf(".") + 1, localId.length()); |
|
3904 |
int rev = new Integer(revString).intValue(); |
|
3905 |
rev++; |
|
3906 |
docid = docid + "." + rev; |
|
3907 |
localId = docid; |
|
3908 |
logMetacat.debug("Incremented system metadata localId: " + localId); |
|
3909 |
|
|
3910 |
} |
|
3911 |
|
|
3912 |
} catch ( McdbDocNotFoundException mnfe ) { |
|
3913 |
throw mnfe; |
|
3914 |
|
|
3915 |
} |
|
3916 |
|
|
3917 |
// get the xml from the sytem metadata object |
|
3918 |
try { |
|
3919 |
xml = new String(serializeSystemMetadata(sysMeta).toByteArray()); |
|
3920 |
|
|
3921 |
} catch ( JiBXException jxe ) { |
|
3922 |
throw jxe; |
|
3923 |
|
|
3924 |
} |
|
3925 |
|
|
3926 |
logMetacat.debug("SystemMetadata to insert or update: " + xml); |
|
3927 |
|
|
3928 |
// ensure user can insert or update |
|
3929 |
try { |
|
3930 |
|
|
3931 |
if ( !(AuthUtil.canInsertOrUpdate(user, groups)) ) { |
|
3932 |
throw new InsufficientKarmaException("The user " + user + |
|
3933 |
"does not have permission to insert or update system metadata."); |
|
3934 |
|
|
3935 |
} |
|
3936 |
|
|
3937 |
} catch (MetacatUtilException ue) { |
|
3938 |
throw new InsufficientKarmaException("Couldn't determine if user " + user + |
|
3939 |
"has permission to insert or update system metadata."); |
|
3940 |
|
|
3941 |
} |
|
3942 |
|
|
3943 |
try { |
|
3944 |
|
|
3945 |
// get a database connection from the pool |
|
3946 |
dbConn = |
|
3947 |
DBConnectionPool.getDBConnection( |
|
3948 |
"MetacatHandler.insertOrUpdateSystemMetadata"); |
|
3949 |
serialNumber = dbConn.getCheckOutSerialNumber(); |
|
3950 |
|
|
3951 |
// write the document to the database and disk |
|
3952 |
logMetacat.debug("MetacatHandler.insertOrUpdateSystemMetadata(): " + |
|
3953 |
"Begin writing XML to Metacat for " + action + |
|
3954 |
" operation."); |
|
3955 |
|
|
3956 |
// write the system metadata document |
|
3957 |
newAccNumber = docImpl.write(dbConn, xml, pub, dtd, |
|
3958 |
action, localId, user, groups); |
|
3959 |
|
|
3960 |
logMetacat.debug("MetacatHandler.insertOrUpdateSystemMetadata(): " + |
|
3961 |
"Wrote XML to Metacat for " + action + |
|
3962 |
" operation."); |
|
3963 |
|
|
3964 |
if ( action.equals("INSERT") ) { |
|
3965 |
IdentifierManager.getInstance().createSystemMetadataMapping( |
|
3966 |
sysMeta, sysMetaGuid.getValue()); |
|
3967 |
setAccess(metacatUrl, user, newAccNumber, |
|
3968 |
"public", "4", "allow", "allowFirst"); |
|
3969 |
|
|
3970 |
} else if ( action.equals("UPDATE") ) { |
|
3971 |
IdentifierManager.getInstance().updateSystemMetadataMapping( |
|
3972 |
sysMeta.getIdentifier().getValue(), localId); |
|
3973 |
IdentifierManager.getInstance().insertAdditionalSystemMetadataFields( |
|
3974 |
sysMeta.getDateUploaded().getTime(), |
|
3975 |
sysMeta.getRightsHolder().getValue(), |
|
3976 |
sysMeta.getChecksum().getValue(), |
|
3977 |
sysMeta.getChecksum().getAlgorithm().name(), |
|
3978 |
sysMeta.getOriginMemberNode().getValue(), |
|
3979 |
sysMeta.getAuthoritativeMemberNode().getValue(), |
|
3980 |
sysMeta.getDateSysMetadataModified().getTime(), |
|
3981 |
sysMeta.getSubmitter().getValue(), |
|
3982 |
sysMeta.getIdentifier().getValue(), |
|
3983 |
sysMeta.getObjectFormat().toString(), |
|
3984 |
sysMeta.getSize()); |
|
3985 |
|
|
3986 |
} |
|
3987 |
// unfortunately DocumentImplWrapper only raises a general exception |
|
3988 |
} catch (Exception e ) { |
|
3989 |
throw new McdbException(e.getMessage()); |
|
3990 |
|
|
3991 |
} finally { |
|
3992 |
// Return db connection |
|
3993 |
DBConnectionPool.returnDBConnection(dbConn, serialNumber); |
|
3994 |
|
|
3995 |
} |
|
3996 |
|
|
3997 |
return newAccNumber; |
|
3998 |
} |
|
3999 |
|
|
4000 | 3793 |
/** |
4001 | 3794 |
* Get the system metadata for a document with a specified guid |
4002 | 3795 |
* |
... | ... | |
4004 | 3797 |
* |
4005 | 3798 |
* @return sysMeta The desired SystemMetadata object |
4006 | 3799 |
*/ |
4007 |
private SystemMetadata getSystemMetadata(Identifier guid, |
|
4008 |
String user, String[] groups) |
|
4009 |
throws McdbDocNotFoundException, InsufficientKarmaException, |
|
4010 |
JiBXException, ParseLSIDException, PropertyNotFoundException, |
|
4011 |
McdbException, SQLException, IOException, ClassNotFoundException { |
|
3800 |
private SystemMetadata getSystemMetadata(Identifier guid) |
|
3801 |
throws McdbDocNotFoundException { |
|
4012 | 3802 |
|
4013 | 3803 |
logMetacat.debug("MetacatHandler.getSystemMetadata() called."); |
4014 | 3804 |
|
4015 |
SystemMetadata sysMeta = new SystemMetadata(); |
|
4016 |
InputStream inputStream; |
|
3805 |
SystemMetadata sysMeta = null; |
|
4017 | 3806 |
|
4018 | 3807 |
try { |
4019 |
IdentifierManager im = IdentifierManager.getInstance(); |
|
4020 |
String localId = im.getSystemMetadataLocalId(guid.getValue()); |
|
4021 |
|
|
4022 |
try { |
|
4023 |
inputStream = this.read(localId); |
|
4024 |
|
|
4025 |
} catch ( McdbDocNotFoundException dnfe ) { |
|
4026 |
throw dnfe; |
|
4027 |
|
|
4028 |
} catch ( ParseLSIDException ple ) { |
|
4029 |
throw ple; |
|
4030 |
|
|
4031 |
} catch ( PropertyNotFoundException pnfe ) { |
|
4032 |
throw pnfe; |
|
4033 |
|
|
4034 |
} catch ( McdbException me ) { |
|
4035 |
throw me; |
|
4036 |
|
|
4037 |
} catch ( SQLException sqle ) { |
|
4038 |
throw sqle; |
|
4039 |
|
|
4040 |
} catch ( ClassNotFoundException cnfe ) { |
|
4041 |
throw cnfe; |
|
4042 |
|
|
4043 |
} catch ( IOException ioe ) { |
|
4044 |
throw ioe; |
|
4045 |
|
|
4046 |
} // end try() |
|
4047 |
|
|
4048 |
try { |
|
4049 |
sysMeta = deserializeSystemMetadata(inputStream); |
|
4050 |
return sysMeta; |
|
4051 |
|
|
4052 |
} catch ( JiBXException jxe ) { |
|
4053 |
logMetacat.debug("There was a problem deserializing the system " + |
|
4054 |
"metadata XML. The error message was: " + jxe.getMessage()); |
|
4055 |
throw jxe; |
|
4056 |
|
|
4057 |
} |
|
3808 |
String localId = IdentifierManager.getInstance().getSystemMetadataLocalId(guid.getValue()); |
|
3809 |
sysMeta = IdentifierManager.getInstance().getSystemMetadata(localId); |
|
4058 | 3810 |
} catch ( McdbDocNotFoundException dnfe ) { |
4059 | 3811 |
logMetacat.debug("There was a problem getting the system " + |
4060 | 3812 |
"metadata local id. The error was: " + dnfe.getMessage()); |
4061 | 3813 |
throw dnfe; |
4062 |
|
|
4063 | 3814 |
} |
3815 |
return sysMeta; |
|
3816 |
|
|
4064 | 3817 |
} |
4065 |
|
|
4066 |
/** |
|
4067 |
* deserialize a system metadata doc. Note: This needs to refactored out |
|
4068 |
* of MetacatHandler and into a utitlity when stream i/o in Metacat is |
|
4069 |
* evaluated. |
|
4070 |
* @param xml The xml to be deserialized |
|
4071 |
* @return sysmeta The SystemMetadata object to be returned |
|
4072 |
* @throws JiBXException |
|
4073 |
*/ |
|
4074 |
private static SystemMetadata deserializeSystemMetadata(InputStream xml) |
|
4075 |
throws JiBXException { |
|
4076 |
|
|
4077 |
try { |
|
4078 |
IBindingFactory bfact = |
|
4079 |
BindingDirectory.getFactory(SystemMetadata.class); |
|
4080 |
IUnmarshallingContext uctx = bfact.createUnmarshallingContext(); |
|
4081 |
SystemMetadata sysmeta = |
|
4082 |
(SystemMetadata) uctx.unmarshalDocument(xml, null); |
|
4083 |
return sysmeta; |
|
4084 |
|
|
4085 |
} catch (JiBXException jxe) { |
|
4086 |
throw jxe; |
|
4087 |
|
|
4088 |
} |
|
4089 | 3818 |
|
4090 |
} |
|
4091 |
|
|
4092 | 3819 |
/* |
4093 | 3820 |
* Find the size (in bytes) of a stream. Note: This needs to refactored out |
4094 | 3821 |
* of MetacatHandler and into a utility when stream i/o in Metacat is |
Also available in: Unified diff
do not use XML files for storing SystemMetadata - use DB tables only.