Revision 5298
Added by Matt Jones about 14 years ago
MetacatHandler.java | ||
---|---|---|
29 | 29 |
import java.io.FileInputStream; |
30 | 30 |
import java.io.FileReader; |
31 | 31 |
import java.io.IOException; |
32 |
import java.io.OutputStream; |
|
32 | 33 |
import java.io.OutputStreamWriter; |
33 | 34 |
import java.io.PrintWriter; |
34 | 35 |
import java.io.StringReader; |
... | ... | |
71 | 72 |
import edu.ucsb.nceas.metacat.accesscontrol.AccessControlForSingleFile; |
72 | 73 |
import edu.ucsb.nceas.metacat.accesscontrol.AccessControlInterface; |
73 | 74 |
import edu.ucsb.nceas.metacat.cart.CartManager; |
75 |
import edu.ucsb.nceas.metacat.client.InsufficientKarmaException; |
|
74 | 76 |
import edu.ucsb.nceas.metacat.database.DBConnection; |
75 | 77 |
import edu.ucsb.nceas.metacat.database.DBConnectionPool; |
76 | 78 |
import edu.ucsb.nceas.metacat.dataquery.DataQuery; |
... | ... | |
720 | 722 |
String[] docs = new String[0]; |
721 | 723 |
String docid = ""; |
722 | 724 |
String qformat = ""; |
723 |
String abstrpath = null; |
|
724 | 725 |
|
725 | 726 |
// read the params |
726 | 727 |
if (params.containsKey("docid")) { |
... | ... | |
763 | 764 |
if (zip) { |
764 | 765 |
addDocToZip(request, docid, providedFileName, zout, user, groups); |
765 | 766 |
} else { |
766 |
readFromMetacat(request, response, docid, qformat, |
|
767 |
abstrpath, user, groups, zip, zout, |
|
768 |
withInlineData, params); |
|
767 |
readFromMetacat(request.getRemoteAddr(), response, response.getOutputStream(), docid, qformat, |
|
768 |
user, groups, withInlineData, params); |
|
769 | 769 |
} |
770 | 770 |
|
771 | 771 |
// case docid="http://.../filename" |
... | ... | |
783 | 783 |
if (zip) { |
784 | 784 |
addDocToZip(request, docid, providedFileName, zout, user, groups); |
785 | 785 |
} else { |
786 |
readFromMetacat(request, response, docid, qformat, |
|
787 |
abstrpath, user, groups, zip, zout, |
|
788 |
withInlineData, params); |
|
786 |
readFromMetacat(request.getRemoteAddr(), response, response.getOutputStream(), docid, qformat, |
|
787 |
user, groups, withInlineData, params); |
|
789 | 788 |
} |
790 | 789 |
} |
791 | 790 |
} |
... | ... | |
896 | 895 |
} |
897 | 896 |
|
898 | 897 |
/** read metadata or data from Metacat |
898 |
* @throws PropertyNotFoundException |
|
899 |
* @throws ParseLSIDException |
|
900 |
* @throws InsufficientKarmaException |
|
899 | 901 |
*/ |
900 |
private void readFromMetacat(HttpServletRequest request,
|
|
901 |
HttpServletResponse response, String docid, String qformat, |
|
902 |
String abstrpath, String user, String[] groups, boolean zip,
|
|
903 |
ZipOutputStream zout, boolean withInlineData, Hashtable<String, String[]> params)
|
|
904 |
throws ClassNotFoundException, IOException, SQLException,
|
|
905 |
McdbException, Exception {
|
|
902 |
public void readFromMetacat(String ipAddress,
|
|
903 |
HttpServletResponse response, OutputStream out, String docid, String qformat,
|
|
904 |
String user, String[] groups, boolean withInlineData,
|
|
905 |
Hashtable<String, String[]> params) throws ClassNotFoundException,
|
|
906 |
IOException, SQLException, McdbException, PropertyNotFoundException,
|
|
907 |
ParseLSIDException, InsufficientKarmaException {
|
|
906 | 908 |
|
907 |
Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
|
|
909 |
Logger logMetacat = Logger.getLogger(MetacatHandler.class);
|
|
908 | 910 |
try { |
909 | 911 |
|
910 | 912 |
if (docid.startsWith("urn:")) { |
... | ... | |
923 | 925 |
|
924 | 926 |
//check the permission for read |
925 | 927 |
if (!DocumentImpl.hasReadPermission(user, groups, docid)) { |
926 |
Exception e = new Exception("User " + user
|
|
928 |
InsufficientKarmaException e = new InsufficientKarmaException("User " + user
|
|
927 | 929 |
+ " does not have permission" |
928 | 930 |
+ " to read the document with the docid " + docid); |
929 |
|
|
930 | 931 |
throw e; |
931 | 932 |
} |
932 | 933 |
|
933 | 934 |
if (doc.getRootNodeID() == 0) { |
934 |
// this is data file |
|
935 |
// this is data file, so find the path on disk for the file
|
|
935 | 936 |
String filepath = PropertyService.getProperty("application.datafilepath"); |
936 | 937 |
if (!filepath.endsWith("/")) { |
937 | 938 |
filepath += "/"; |
... | ... | |
940 | 941 |
FileInputStream fin = null; |
941 | 942 |
fin = new FileInputStream(filename); |
942 | 943 |
|
943 |
//MIME type |
|
944 |
String contentType = servletContext.getMimeType(filename); |
|
945 |
if (contentType == null) { |
|
946 |
ContentTypeProvider provider = new ContentTypeProvider( |
|
947 |
docid); |
|
948 |
contentType = provider.getContentType(); |
|
949 |
logMetacat.info("MetaCatServlet.readFromMetacat - Final contenttype is: " |
|
950 |
+ contentType); |
|
951 |
} |
|
952 |
|
|
953 |
response.setContentType(contentType); |
|
954 |
// if we decide to use "application/octet-stream" for all data |
|
955 |
// returns |
|
956 |
// response.setContentType("application/octet-stream"); |
|
944 |
if (response != null) { |
|
945 |
// MIME type |
|
946 |
String contentType = servletContext.getMimeType(filename); |
|
947 |
if (contentType == null) { |
|
948 |
ContentTypeProvider provider = new ContentTypeProvider( |
|
949 |
docid); |
|
950 |
contentType = provider.getContentType(); |
|
951 |
logMetacat.info("MetaCatServlet.readFromMetacat - Final contenttype is: " |
|
952 |
+ contentType); |
|
953 |
} |
|
954 |
response.setContentType(contentType); |
|
957 | 955 |
|
958 |
// check for the existence of a metadatadocid parameter, |
|
959 |
// if this is sent, then send a filename which contains both |
|
960 |
// the metadata docid and the data docid, so the link with |
|
961 |
// metadata is explicitly encoded in the filename. |
|
962 |
String metadatadocid = null; |
|
963 |
Vector<String> nameparts = new Vector<String>(); |
|
964 |
|
|
965 |
if(params.containsKey("metadatadocid")) { |
|
966 |
metadatadocid = params.get("metadatadocid")[0]; |
|
956 |
// Set the output filename on the response |
|
957 |
String outputname = generateOutputName(docid, params, doc); |
|
958 |
response.setHeader("Content-Disposition", |
|
959 |
"attachment; filename=\"" + outputname + "\""); |
|
967 | 960 |
} |
968 |
if (metadatadocid != null && !metadatadocid.equals("")) { |
|
969 |
nameparts.add(metadatadocid); |
|
970 |
} |
|
971 |
// we'll always have the docid, include it in the name |
|
972 |
String doctype = doc.getDoctype(); |
|
973 |
// TODO: fix this to lookup the associated FGDC metadata document, |
|
974 |
// and grab the doctype tag for it. These should be set to something |
|
975 |
// consistent, not 'metadata' as it stands... |
|
976 |
//if (!doctype.equals("metadata")) { |
|
977 |
// nameparts.add(docid); |
|
978 |
//} |
|
979 |
nameparts.add(docid); |
|
980 |
// Set the name of the data file to the entity name plus docid, |
|
981 |
// or if that is unavailable, use the docid alone |
|
982 |
String docname = doc.getDocname(); |
|
983 |
if (docname != null && !docname.equals("")) { |
|
984 |
nameparts.add(docname); |
|
985 |
} |
|
986 |
// combine the name elements with a dash, using a 'join' equivalent |
|
987 |
String outputname = null; |
|
988 |
String delimiter = "-"; |
|
989 |
Iterator<String> iter = nameparts.iterator(); |
|
990 |
StringBuffer buffer = new StringBuffer(iter.next()); |
|
991 |
while (iter.hasNext()) buffer.append(delimiter).append(iter.next()); |
|
992 |
outputname = buffer.toString(); |
|
993 | 961 |
|
994 |
response.setHeader("Content-Disposition", |
|
995 |
"attachment; filename=\"" + outputname + "\""); |
|
996 |
|
|
962 |
// Write the data to the output stream |
|
997 | 963 |
try { |
998 |
ServletOutputStream out = response.getOutputStream(); |
|
999 | 964 |
byte[] buf = new byte[4 * 1024]; // 4K buffer |
1000 | 965 |
int b = fin.read(buf); |
1001 | 966 |
while (b != -1) { |
... | ... | |
1008 | 973 |
|
1009 | 974 |
} else { |
1010 | 975 |
// this is metadata doc |
1011 |
ServletOutputStream streamOut = response.getOutputStream(); |
|
1012 | 976 |
if (qformat.equals("xml") || qformat.equals("")) { |
1013 | 977 |
// if equals "", that means no qformat is specified. hence |
1014 | 978 |
// by default the document should be returned in xml format |
1015 | 979 |
// set content type first |
1016 |
response.setContentType("text/xml"); //MIME type |
|
1017 |
response.setHeader("Content-Disposition", |
|
1018 |
"attachment; filename=" + docid + ".xml"); |
|
1019 | 980 |
|
981 |
if (response != null) { |
|
982 |
response.setContentType("text/xml"); //MIME type |
|
983 |
response.setHeader("Content-Disposition", |
|
984 |
"attachment; filename=" + docid + ".xml"); |
|
985 |
} |
|
986 |
|
|
1020 | 987 |
// Try to get the metadata file from disk. If it isn't |
1021 | 988 |
// found, create it from the db and write it to disk then. |
1022 | 989 |
try { |
1023 |
PrintWriter out = new PrintWriter(streamOut);
|
|
1024 |
doc.toXml(out, user, groups, withInlineData);
|
|
1025 |
} catch (Exception e) { |
|
990 |
PrintWriter pw = new PrintWriter(out);
|
|
991 |
doc.toXml(pw, user, groups, withInlineData);
|
|
992 |
} catch (McdbException e) {
|
|
1026 | 993 |
// any exceptions in reading the xml from disc, and we go back to the |
1027 | 994 |
// old way of creating the xml directly. |
1028 | 995 |
logMetacat.error("MetaCatServlet.readFromMetacat - could not read from document file " + docid |
1029 | 996 |
+ ": " + e.getMessage()); |
1030 |
PrintWriter out = new PrintWriter(streamOut);
|
|
1031 |
doc.toXmlFromDb(out, user, groups, withInlineData);
|
|
997 |
PrintWriter pw = new PrintWriter(out);
|
|
998 |
doc.toXmlFromDb(pw, user, groups, withInlineData);
|
|
1032 | 999 |
} |
1033 | 1000 |
} else { |
1034 | 1001 |
// TODO MCD, this should read from disk as well? |
... | ... | |
1041 | 1008 |
params.put("publicRead", new String[] {"false"}); |
1042 | 1009 |
} |
1043 | 1010 |
|
1044 |
response.setContentType("text/html"); //MIME type |
|
1045 |
PrintWriter out = new PrintWriter(streamOut); |
|
1011 |
if (response != null) { |
|
1012 |
response.setContentType("text/html"); //MIME type |
|
1013 |
} |
|
1046 | 1014 |
|
1015 |
PrintWriter pw = new PrintWriter(out); |
|
1016 |
|
|
1047 | 1017 |
// Look up the document type |
1048 | 1018 |
String doctype = doc.getDoctype(); |
1049 | 1019 |
// Transform the document to the new doctype |
1050 | 1020 |
DBTransform dbt = new DBTransform(); |
1051 | 1021 |
dbt.transformXMLDocument(doc.toString(user, groups, |
1052 | 1022 |
withInlineData), doctype, "-//W3C//HTML//EN", |
1053 |
qformat, out, params, null);
|
|
1023 |
qformat, pw, params, null);
|
|
1054 | 1024 |
} |
1055 | 1025 |
|
1056 | 1026 |
} |
1057 |
EventLog.getInstance().log(request.getRemoteAddr(), user, |
|
1058 |
docid, "read"); |
|
1059 |
} catch (Exception except) { |
|
1027 |
EventLog.getInstance().log(ipAddress, user, docid, "read"); |
|
1028 |
} catch (PropertyNotFoundException except) { |
|
1060 | 1029 |
throw except; |
1061 | 1030 |
} |
1062 | 1031 |
} |
1032 |
|
|
1033 |
/** |
|
1034 |
* Create a filename to be used for naming a downloaded document |
|
1035 |
* @param docid the identifier of the document to be named |
|
1036 |
* @param params the parameters of the request |
|
1037 |
* @param doc the DocumentImpl of the document to be named |
|
1038 |
* @return String containing a name for the download |
|
1039 |
*/ |
|
1040 |
private String generateOutputName(String docid, |
|
1041 |
Hashtable<String, String[]> params, DocumentImpl doc) { |
|
1042 |
String outputname = null; |
|
1043 |
// check for the existence of a metadatadocid parameter, |
|
1044 |
// if this is sent, then send a filename which contains both |
|
1045 |
// the metadata docid and the data docid, so the link with |
|
1046 |
// metadata is explicitly encoded in the filename. |
|
1047 |
String metadatadocid = null; |
|
1048 |
Vector<String> nameparts = new Vector<String>(); |
|
1049 |
|
|
1050 |
if(params.containsKey("metadatadocid")) { |
|
1051 |
metadatadocid = params.get("metadatadocid")[0]; |
|
1052 |
} |
|
1053 |
if (metadatadocid != null && !metadatadocid.equals("")) { |
|
1054 |
nameparts.add(metadatadocid); |
|
1055 |
} |
|
1056 |
// we'll always have the docid, include it in the name |
|
1057 |
String doctype = doc.getDoctype(); |
|
1058 |
// TODO: fix this to lookup the associated FGDC metadata document, |
|
1059 |
// and grab the doctype tag for it. These should be set to something |
|
1060 |
// consistent, not 'metadata' as it stands... |
|
1061 |
//if (!doctype.equals("metadata")) { |
|
1062 |
// nameparts.add(docid); |
|
1063 |
//} |
|
1064 |
nameparts.add(docid); |
|
1065 |
// Set the name of the data file to the entity name plus docid, |
|
1066 |
// or if that is unavailable, use the docid alone |
|
1067 |
String docname = doc.getDocname(); |
|
1068 |
if (docname != null && !docname.equals("")) { |
|
1069 |
nameparts.add(docname); |
|
1070 |
} |
|
1071 |
// combine the name elements with a dash, using a 'join' equivalent |
|
1072 |
String delimiter = "-"; |
|
1073 |
Iterator<String> iter = nameparts.iterator(); |
|
1074 |
StringBuffer buffer = new StringBuffer(iter.next()); |
|
1075 |
while (iter.hasNext()) buffer.append(delimiter).append(iter.next()); |
|
1076 |
outputname = buffer.toString(); |
|
1077 |
return outputname; |
|
1078 |
} |
|
1063 | 1079 |
|
1064 | 1080 |
/** |
1065 | 1081 |
* read data from URLConnection |
... | ... | |
2796 | 2812 |
* If the given docid only have one seperter, we need |
2797 | 2813 |
* append rev for it. The rev come from xml_documents |
2798 | 2814 |
*/ |
2799 |
private static String appendRev(String docid) throws Exception { |
|
2815 |
private static String appendRev(String docid) throws PropertyNotFoundException, SQLException, McdbDocNotFoundException {
|
|
2800 | 2816 |
// Logger logMetacat = Logger.getLogger(MetaCatServlet.class); |
2801 | 2817 |
String newAccNum = null; |
2802 | 2818 |
String separator = PropertyService.getProperty("document.accNumSeparator"); |
... | ... | |
2807 | 2823 |
//only one seperater |
2808 | 2824 |
int rev = DBUtil.getLatestRevisionInDocumentTable(docid); |
2809 | 2825 |
if (rev == -1) { |
2810 |
throw new Exception("the requested docid '" |
|
2826 |
throw new McdbDocNotFoundException("the requested docid '"
|
|
2811 | 2827 |
+ docid+ "' does not exist"); |
2812 | 2828 |
} else { |
2813 | 2829 |
newAccNum = docid+ separator+ rev; |
Also available in: Unified diff
Modified readFromMetacat() to pass most exceptions up the call stack, which
allows creation of new entry points for calling reads. Still need to
continue factoring out the HTTPServletResponse that is passed in in order to
make entrypoints that are not servlet based possible. Problem now is in
setting the content type properly on the servlet response before writing to
the output stream.
Added new dataone interface implementation for the CRUD service, but it is incomplete -- most interfaces thrown NotImplemented for now . The get() method should work but is not tested.