Revision 10292
Added by Jing Tao over 7 years ago
src/edu/ucsb/nceas/metacat/DocumentImpl.java | ||
---|---|---|
42 | 42 |
import java.io.Writer; |
43 | 43 |
import java.math.BigInteger; |
44 | 44 |
import java.net.URL; |
45 |
import java.security.DigestOutputStream; |
|
46 |
import java.security.MessageDigest; |
|
47 |
import java.security.NoSuchAlgorithmException; |
|
45 | 48 |
import java.sql.PreparedStatement; |
46 | 49 |
import java.sql.ResultSet; |
47 | 50 |
import java.sql.SQLException; |
... | ... | |
90 | 93 |
import org.apache.commons.io.IOUtils; |
91 | 94 |
import org.apache.commons.io.input.XmlStreamReader; |
92 | 95 |
import org.apache.log4j.Logger; |
96 |
import org.dataone.service.exceptions.InvalidSystemMetadata; |
|
97 |
import org.dataone.service.types.v1.Checksum; |
|
93 | 98 |
import org.dataone.service.types.v1.Identifier; |
94 | 99 |
import org.dataone.service.types.v2.SystemMetadata; |
95 | 100 |
import org.xml.sax.ContentHandler; |
... | ... | |
1500 | 1505 |
* @param accNumber |
1501 | 1506 |
* the document id which is used to name the output file |
1502 | 1507 |
*/ |
1503 |
private static void writeToFileSystem(byte[] xml, String accNumber) throws McdbException {
|
|
1508 |
private static void writeToFileSystem(byte[] xml, String accNumber, Checksum checksum) throws McdbException, InvalidSystemMetadata {
|
|
1504 | 1509 |
|
1505 | 1510 |
// write the document to disk |
1506 | 1511 |
String documentDir = null; |
1507 | 1512 |
String documentPath = null; |
1513 |
boolean needCalculateChecksum = false; |
|
1514 |
String checksumValue = null; |
|
1515 |
MessageDigest md = null; |
|
1508 | 1516 |
|
1509 | 1517 |
try { |
1510 | 1518 |
documentDir = PropertyService.getProperty("application.documentfilepath"); |
... | ... | |
1526 | 1534 |
if (accNumber != null |
1527 | 1535 |
&& (FileUtil.getFileStatus(documentPath) == FileUtil.DOES_NOT_EXIST |
1528 | 1536 |
|| FileUtil.getFileSize(documentPath) == 0)) { |
1537 |
if(checksum != null) { |
|
1538 |
needCalculateChecksum = true; |
|
1539 |
checksumValue = checksum.getValue(); |
|
1540 |
logMetacat.info("DocumentImple.writeToFileSystem - the checksum from the system metadata is "+checksumValue); |
|
1541 |
if(checksumValue == null || checksumValue.trim().equals("")) { |
|
1542 |
logMetacat.error("DocumentImple.writeToFileSystem - the checksum value from the system metadata shouldn't be null or blank"); |
|
1543 |
throw new InvalidSystemMetadata("1180", "The checksum value from the system metadata shouldn't be null or blank."); |
|
1544 |
} |
|
1545 |
String algorithm = checksum.getAlgorithm(); |
|
1546 |
logMetacat.info("DocumentImple.writeToFileSystem - the algorithm to calculate the checksum from the system metadata is "+algorithm); |
|
1547 |
if(algorithm == null || algorithm.trim().equals("")) { |
|
1548 |
logMetacat.error("DocumentImple.writeToFileSystem - the algorithm to calculate the checksum from the system metadata shouldn't be null or blank"); |
|
1549 |
throw new InvalidSystemMetadata("1180", "The algorithm to calculate the checksum from the system metadata shouldn't be null or blank."); |
|
1550 |
} |
|
1551 |
try { |
|
1552 |
md = MessageDigest.getInstance(algorithm); |
|
1553 |
} catch (NoSuchAlgorithmException ee) { |
|
1554 |
logMetacat.error("DocumentImple.writeToFileSystem - we don't support the algorithm "+algorithm+" to calculate the checksum.", ee); |
|
1555 |
throw new InvalidSystemMetadata("1180", "The algorithm "+algorithm+" to calculate the checksum is not supported: "+ee.getMessage()); |
|
1556 |
} |
|
1557 |
} |
|
1529 | 1558 |
|
1530 |
FileOutputStream fos = null;
|
|
1559 |
OutputStream fos = null; |
|
1531 | 1560 |
try { |
1532 |
fos = new FileOutputStream(documentPath); |
|
1561 |
if(needCalculateChecksum) { |
|
1562 |
logMetacat.info("DocumentImple.writeToFileSystem - we need to compute the checksum since it is from DataONE API"); |
|
1563 |
fos = new DigestOutputStream(new FileOutputStream(documentPath), md); |
|
1564 |
} else { |
|
1565 |
logMetacat.info("DocumentImple.writeToFileSystem - we don't need to compute the checksum since it is from Metacat API"); |
|
1566 |
fos = new FileOutputStream(documentPath); |
|
1567 |
} |
|
1568 |
|
|
1533 | 1569 |
IOUtils.write(xml, fos); |
1534 |
|
|
1535 | 1570 |
fos.flush(); |
1536 | 1571 |
fos.close(); |
1572 |
if(needCalculateChecksum) { |
|
1573 |
String localChecksum = DatatypeConverter.printHexBinary(md.digest()); |
|
1574 |
logMetacat.info("DocumentImple.writeToFileSystem - the check sum calculated from the saved local file is "+localChecksum); |
|
1575 |
if(localChecksum == null || localChecksum.trim().equals("") || !localChecksum.equalsIgnoreCase(checksumValue)) { |
|
1576 |
logMetacat.error("DocumentImple.writeToFileSystem - the check sum calculated from the saved local file is "+localChecksum+ ". But it doesn't match the value from the system metadata "+checksumValue); |
|
1577 |
File newFile = new File(documentPath); |
|
1578 |
boolean success = newFile.delete(); |
|
1579 |
logMetacat.info("Delete the file "+newFile.getAbsolutePath()+" sucessfully? "+success); |
|
1580 |
throw new InvalidSystemMetadata("1180", "The checksum calculated from the saved local file is "+localChecksum+ ". But it doesn't match the value from the system metadata "+checksumValue+"."); |
|
1581 |
} |
|
1582 |
} |
|
1537 | 1583 |
} catch (IOException ioe) { |
1538 | 1584 |
throw new McdbException("Could not write file: " + documentPath + " : " + ioe.getMessage()); |
1539 | 1585 |
} finally { |
... | ... | |
2659 | 2705 |
|
2660 | 2706 |
public static String write(DBConnection conn, String xmlString, String pub, |
2661 | 2707 |
Reader dtd, String action, String docid, String user, |
2662 |
String[] groups, String ruleBase, boolean needValidation, boolean writeAccessRules, byte[] xmlBytes, String schemaLocation) |
|
2708 |
String[] groups, String ruleBase, boolean needValidation, boolean writeAccessRules, byte[] xmlBytes, String schemaLocation, Checksum checksum)
|
|
2663 | 2709 |
throws Exception |
2664 | 2710 |
{ |
2665 | 2711 |
//this method will be called in handleUpdateOrInsert method |
... | ... | |
2667 | 2713 |
// get server location for this doc |
2668 | 2714 |
int serverLocation = getServerLocationNumber(docid); |
2669 | 2715 |
return write(conn, xmlString, pub, dtd, action, docid, user, groups, |
2670 |
serverLocation, false, ruleBase, needValidation, writeAccessRules, xmlBytes, schemaLocation); |
|
2716 |
serverLocation, false, ruleBase, needValidation, writeAccessRules, xmlBytes, schemaLocation, checksum);
|
|
2671 | 2717 |
} |
2672 | 2718 |
|
2673 | 2719 |
/** |
... | ... | |
2704 | 2750 |
public static String write(DBConnection conn, String xmlString, String pub, |
2705 | 2751 |
Reader dtd, String action, String accnum, String user, |
2706 | 2752 |
String[] groups, int serverCode, boolean override, String ruleBase, |
2707 |
boolean needValidation, boolean writeAccessRules, byte[] xmlBytes, String schemaLocation) throws Exception |
|
2753 |
boolean needValidation, boolean writeAccessRules, byte[] xmlBytes, String schemaLocation, Checksum checksum) throws Exception
|
|
2708 | 2754 |
{ |
2709 | 2755 |
// NEW - WHEN CLIENT ALWAYS PROVIDE ACCESSION NUMBER INCLUDING REV IN IT |
2710 | 2756 |
|
... | ... | |
2798 | 2844 |
conn.setAutoCommit(false); |
2799 | 2845 |
logMetacat.debug("DocumentImpl.write - parsing xml"); |
2800 | 2846 |
parser.parse(new InputSource(xmlReader)); |
2801 |
conn.commit(); |
|
2802 |
conn.setAutoCommit(true); |
|
2803 | 2847 |
|
2804 | 2848 |
// update the node data to include numeric and date values |
2805 | 2849 |
updateNodeValues(conn, docid); |
2806 | 2850 |
|
2807 | 2851 |
//write the file to disk |
2808 | 2852 |
logMetacat.debug("DocumentImpl.write - Writing xml to file system"); |
2809 |
writeToFileSystem(xmlBytes, accnum); |
|
2853 |
writeToFileSystem(xmlBytes, accnum, checksum); |
|
2854 |
|
|
2855 |
conn.commit(); |
|
2856 |
conn.setAutoCommit(true); |
|
2810 | 2857 |
|
2811 | 2858 |
// write to xml_node complete. start the indexing thread. |
2812 | 2859 |
addDocidToIndexingQueue(docid, rev); |
... | ... | |
2904 | 2951 |
//logMetacat.debug("DocumentImpl.write - XML to be parsed: " + xmlString); |
2905 | 2952 |
parser.parse(new InputSource(xmlReader)); |
2906 | 2953 |
|
2907 |
conn.commit(); |
|
2908 |
conn.setAutoCommit(true); |
|
2909 |
|
|
2910 | 2954 |
//update nodes |
2911 | 2955 |
updateNodeValues(conn, docid); |
2912 | 2956 |
|
2913 | 2957 |
//write the file to disk |
2914 |
writeToFileSystem(xmlBytes, accnum); |
|
2958 |
writeToFileSystem(xmlBytes, accnum, checksum); |
|
2959 |
|
|
2960 |
conn.commit(); |
|
2961 |
conn.setAutoCommit(true); |
|
2915 | 2962 |
|
2916 | 2963 |
addDocidToIndexingQueue(docid, rev); |
2917 | 2964 |
if (guidsToSync.size() > 0) { |
... | ... | |
3116 | 3163 |
|
3117 | 3164 |
// Write the file to disk |
3118 | 3165 |
//byte[] bytes = xmlString.getBytes(encoding); |
3119 |
writeToFileSystem(xmlBytes, accnum); |
|
3166 |
Checksum checksum = null; |
|
3167 |
writeToFileSystem(xmlBytes, accnum, checksum); |
|
3120 | 3168 |
|
3121 | 3169 |
// write to xml_node complete. start the indexing thread. |
3122 | 3170 |
// this only for xml_documents |
Also available in: Unified diff
Add the code to computer the checksum.