Revision 3300
Added by barteau over 17 years ago
src/edu/ucsb/nceas/metacat/client/MetacatClient.java | ||
---|---|---|
41 | 41 |
import java.net.URL; |
42 | 42 |
import java.util.HashMap; |
43 | 43 |
import java.util.Iterator; |
44 |
import java.util.Map; |
|
44 | 45 |
import java.util.Properties; |
46 |
import java.util.TreeMap; |
|
45 | 47 |
import java.util.Vector; |
48 |
import javax.servlet.ServletContext; |
|
49 |
import javax.servlet.http.HttpServletRequest; |
|
50 |
import javax.servlet.http.HttpServletResponse; |
|
46 | 51 |
import javax.xml.xpath.XPath; |
47 | 52 |
import javax.xml.xpath.XPathFactory; |
48 | 53 |
import org.w3c.dom.Document; |
... | ... | |
72 | 77 |
/** The session identifier for the session */ |
73 | 78 |
private String sessionId; |
74 | 79 |
|
80 |
/** |
|
81 |
* Identifies the FGDC DTD. |
|
82 |
*/ |
|
75 | 83 |
public static final String FGDC_SYSTEM_ID = "http://www.fgdc.gov/metadata/fgdc-std-001-1998.dtd"; |
76 | 84 |
private static XPath xpath = XPathFactory.newInstance().newXPath(); |
77 | 85 |
private Document loginResponse = null, metadataDoc = null; |
... | ... | |
1055 | 1063 |
} |
1056 | 1064 |
|
1057 | 1065 |
/** |
1066 |
* JSP API: Get the user's name. This will be what was entered for the user name, |
|
1067 |
* and is not the LDAP user name. |
|
1068 |
* @return String of the users name. |
|
1069 |
*/ |
|
1070 |
public String getUser() { |
|
1071 |
return(user); |
|
1072 |
} |
|
1073 |
|
|
1074 |
/** |
|
1058 | 1075 |
* JSP API: After calling "login(ldapUserName, pwd)", call this with the username |
1059 | 1076 |
* and servers response message. You can than use isLoggedIn() to determine if |
1060 | 1077 |
* the user is logged in, getLoginResponseElement(), etc. The user name will also |
... | ... | |
1063 | 1080 |
* @param serverResponse XML login response sent from Metacat. |
1064 | 1081 |
*/ |
1065 | 1082 |
public void setUser(String userName, String serverResponse) { |
1066 |
if (serverResponse != null && serverResponse.contains("login")) |
|
1083 |
|
|
1084 |
if (serverResponse != null && serverResponse.contains("login")) { |
|
1067 | 1085 |
user = userName; |
1068 |
else |
|
1086 |
System.out.println("MetacatClient.setUser: getSessionId() = " + getSessionId()); |
|
1087 |
} else { |
|
1069 | 1088 |
user = null; |
1089 |
} |
|
1070 | 1090 |
} |
1071 | 1091 |
|
1072 | 1092 |
/** |
... | ... | |
1086 | 1106 |
MultipartParser multipartParser; |
1087 | 1107 |
InputStream inputStream; |
1088 | 1108 |
Node newBranch, metaRootNode; |
1089 |
HashMap dataDocIDs; |
|
1109 |
HashMap dataDocIDs, paramsMap;
|
|
1090 | 1110 |
|
1111 |
|
|
1112 |
ServletContext cntxt = request.getSession().getServletContext().getContext("/knb/metacat"); |
|
1113 |
String servletName = cntxt.getServletContextName(); |
|
1114 |
|
|
1091 | 1115 |
//*** Only process request if a file upload. |
1092 | 1116 |
contentType = request.getContentType(); |
1093 | 1117 |
if (isLoggedIn() && contentType != null && contentType.contains("multipart/form-data")) { |
... | ... | |
1097 | 1121 |
multipartParser = new MultipartParser(request, sizeLimit * 1024 * 1024); |
1098 | 1122 |
|
1099 | 1123 |
//*** Get the First file, which should be the metadata file. |
1100 |
inputStream = getNextInputStream(multipartParser, fileName); |
|
1124 |
paramsMap = new HashMap(); |
|
1125 |
inputStream = getNextInputStream(multipartParser, fileName, paramsMap); |
|
1101 | 1126 |
if (fileName.toString().toLowerCase().endsWith(".xml")) { |
1102 | 1127 |
setMetadataDoc(inputStream); |
1103 | 1128 |
|
... | ... | |
1109 | 1134 |
//*** Loop thru all of the data files, get fileName and inputStream. |
1110 | 1135 |
dataDocIDs = new HashMap(); |
1111 | 1136 |
fileName = new StringBuilder(); |
1112 |
while ((inputStream = getNextInputStream(multipartParser, fileName)) != null) { |
|
1137 |
while ((inputStream = getNextInputStream(multipartParser, fileName, paramsMap)) != null) {
|
|
1113 | 1138 |
//*** Get the data file's DOC ID. |
1114 | 1139 |
nextDocId = nextDocId(lastDocId); |
1115 | 1140 |
//*** Set the file format (just using file extension for now). |
... | ... | |
1135 | 1160 |
reader = XMLUtilities.getDOMTreeAsReader(metadataDoc.getDocumentElement(), false); |
1136 | 1161 |
insert(metaDocId, reader, null); |
1137 | 1162 |
|
1138 |
result = "MetaCat Package Inserted: Metadata Doc ID #" + metaDocId;
|
|
1163 |
result = "MetaCat Package Inserted: the Document Identifier is " + metaDocId;
|
|
1139 | 1164 |
reader.close(); |
1165 |
|
|
1166 |
//*** One last detail...grant the public read access. |
|
1167 |
if (paramsMap.containsKey("publicAccess")) |
|
1168 |
setAccess(metaDocId, "public", "read", "allow", "allowFirst"); |
|
1169 |
|
|
1140 | 1170 |
} else { |
1141 | 1171 |
System.out.println("MetacatClient.doUpload: not an FGDC file = " + fileName); |
1142 | 1172 |
result = fileName + " is not an FGDC file. Files not uploaded."; |
... | ... | |
1162 | 1192 |
return(result); |
1163 | 1193 |
} |
1164 | 1194 |
|
1165 |
private InputStream getNextInputStream(MultipartParser multipartParser, StringBuilder fileName) throws IOException { |
|
1195 |
private InputStream getNextInputStream(MultipartParser multipartParser, StringBuilder fileName, HashMap paramsMap) |
|
1196 |
throws IOException { |
|
1166 | 1197 |
InputStream result = null; |
1167 | 1198 |
Part part; |
1168 | 1199 |
String parmName = null, value = null, fnam; |
... | ... | |
1171 | 1202 |
if (part.isParam()) { |
1172 | 1203 |
parmName = part.getName(); |
1173 | 1204 |
value = ((ParamPart) part).getStringValue(); |
1205 |
paramsMap.put(parmName, value); |
|
1174 | 1206 |
System.out.println("MetacatClient.doUpload: parmName = " + parmName + " value = " + value); |
1175 | 1207 |
|
1176 | 1208 |
} else if (part.isFile()) { |
... | ... | |
1214 | 1246 |
return(result); |
1215 | 1247 |
} |
1216 | 1248 |
|
1249 |
private String nextVersion(String lastDocId) { |
|
1250 |
String result = null, tokens[], scope; |
|
1251 |
int vers, docNum; |
|
1252 |
final int LAST_TOKEN = 2; |
|
1253 |
final String TEMPLATE = "%1$s.%2$d.%3$d"; |
|
1254 |
|
|
1255 |
if(lastDocId != null && lastDocId.contains(".")) { |
|
1256 |
lastDocId = lastDocId.replace('.','~'); //*** This is necessary for the split to work. |
|
1257 |
tokens = lastDocId.split("~"); |
|
1258 |
if(tokens.length > LAST_TOKEN && !tokens[LAST_TOKEN].equals("")) { |
|
1259 |
scope = tokens[LAST_TOKEN - 2]; |
|
1260 |
docNum = Integer.parseInt(tokens[LAST_TOKEN - 1]); |
|
1261 |
try { |
|
1262 |
vers = Integer.parseInt(tokens[LAST_TOKEN]); |
|
1263 |
result = String.format(TEMPLATE, scope, docNum, 1 + vers); |
|
1264 |
} catch (NumberFormatException ex) { |
|
1265 |
//*** In case the lastDocId has something other than a number. |
|
1266 |
result = String.format(TEMPLATE, scope, docNum, 1); |
|
1267 |
} |
|
1268 |
} else { |
|
1269 |
//*** In case the lastDocId ends with a '.' |
|
1270 |
result = lastDocId + "1"; |
|
1271 |
} |
|
1272 |
} else { |
|
1273 |
//*** In case of missing doc Id. |
|
1274 |
result = null; |
|
1275 |
} |
|
1276 |
return(result); |
|
1277 |
} |
|
1278 |
|
|
1217 | 1279 |
private boolean isFGDC() { |
1218 | 1280 |
boolean result = false; |
1219 | 1281 |
DocumentType docType; |
... | ... | |
1346 | 1408 |
return(result); |
1347 | 1409 |
} |
1348 | 1410 |
|
1411 |
private static final String SELECT_TEMPLATE = "<select name='%1$s' style='%2$s' size='%3$s'>\n%4$s</select>\n"; |
|
1412 |
private static final String OPTION_TEMPLATE = "<option value='%1$s'>%2$s</option>\n"; |
|
1413 |
private static final String OPTGRP_TEMPLATE = "<optgroup label='%1$s'>%2$s</optgroup>"; |
|
1414 |
private static final String INPUT_TEMPLATE = "<input name='%1$s' value='%2$s' type='%4$s' class='%3$s' size='%5$d'/>\n"; |
|
1415 |
|
|
1416 |
/** |
|
1417 |
* JSP API: A static helper method which takes a vector (keys/values) and returns |
|
1418 |
* an XHTML SELECT String. |
|
1419 |
* @param vector The vector contianing the values to convert into an HTML SELECT statement. |
|
1420 |
* @param name The name to assign the HTML SELECT, which will become the parameter name. |
|
1421 |
* @param style Any HTML styling text. |
|
1422 |
* @param size HTML field width. |
|
1423 |
* @return String, XHTML for a SELECT statement. |
|
1424 |
*/ |
|
1425 |
public static String vectorToHtmlSelect(Vector vector, String name, String style, int size) { |
|
1426 |
String result = "", item; |
|
1427 |
Iterator<String> iterIt; |
|
1428 |
|
|
1429 |
iterIt = vector.iterator(); |
|
1430 |
while(iterIt.hasNext()) { |
|
1431 |
item = iterIt.next(); |
|
1432 |
item = String.format(OPTION_TEMPLATE, item, item); |
|
1433 |
result += item; |
|
1434 |
} |
|
1435 |
result = String.format(SELECT_TEMPLATE, name, style, size, result); |
|
1436 |
return(result); |
|
1437 |
} |
|
1438 |
|
|
1439 |
/** |
|
1440 |
* JSP API: A static helper method which takes a map (key, value pairs) and returns |
|
1441 |
* an XHTML SELECT String. |
|
1442 |
* @param map The map contianing the key, value pairs to convert into an HTML SELECT |
|
1443 |
* statement. |
|
1444 |
* @param name The name to assign the HTML SELECT, which will become the parameter name. |
|
1445 |
* @param style Any HTML styling text. |
|
1446 |
* @param size HTML field width. |
|
1447 |
* @return String, XHTML for a SELECT statement. |
|
1448 |
*/ |
|
1449 |
public static String mapToHtmlSelect(Map map, String name, String style, int size) { |
|
1450 |
String result = "", item, key, optGrp; |
|
1451 |
Iterator<String> iterIt; |
|
1452 |
Object obj; |
|
1453 |
Vector vector; |
|
1454 |
Iterator completeIterIt; |
|
1455 |
|
|
1456 |
iterIt = map.keySet().iterator(); |
|
1457 |
while(iterIt.hasNext()) { |
|
1458 |
key = iterIt.next(); |
|
1459 |
obj = map.get(key); |
|
1460 |
if (obj instanceof String) { |
|
1461 |
item = (String) obj; |
|
1462 |
item = String.format(OPTION_TEMPLATE, key, item); |
|
1463 |
result += item; |
|
1464 |
} else if (obj instanceof Vector) { |
|
1465 |
vector = (Vector) obj; |
|
1466 |
optGrp = ""; |
|
1467 |
completeIterIt = vector.iterator(); |
|
1468 |
while (completeIterIt.hasNext()) { |
|
1469 |
item = (String) completeIterIt.next(); |
|
1470 |
item = String.format(OPTION_TEMPLATE, item, item); |
|
1471 |
optGrp += item; |
|
1472 |
} |
|
1473 |
item = String.format(OPTGRP_TEMPLATE, key, optGrp); |
|
1474 |
result += item; |
|
1475 |
} |
|
1476 |
} |
|
1477 |
result = String.format(SELECT_TEMPLATE, name, style, size, result); |
|
1478 |
return(result); |
|
1479 |
} |
|
1480 |
|
|
1481 |
|
|
1482 |
/** |
|
1483 |
* JSP API: A static helper method which takes attribute values and returns |
|
1484 |
* an XHTML INPUT Statement. |
|
1485 |
* @param type The 'type attribute' of the input statement. |
|
1486 |
* @param name The 'name attribute' of the input statement. |
|
1487 |
* @param value The 'value attribute' of the input statement. |
|
1488 |
* @param cssClass The CSS 'class attribute'. |
|
1489 |
* @param fldSize HTML field width. |
|
1490 |
* @return String, XHTML for an INPUT statement. |
|
1491 |
*/ |
|
1492 |
public static String htmlInput(String type, String name, String value, String cssClass, int fldSize) { |
|
1493 |
String result; |
|
1494 |
|
|
1495 |
result = String.format(INPUT_TEMPLATE, name, value, cssClass, type, fldSize); |
|
1496 |
return(result); |
|
1497 |
} |
|
1498 |
|
|
1499 |
|
|
1500 |
/** |
|
1501 |
* JSP API: A static helper method which takes a key/value pair and saves |
|
1502 |
* it in the session. |
|
1503 |
* @param key The session attribute key name to use. |
|
1504 |
* @param val The value to assign. |
|
1505 |
* @param request The HttpServletRequest. |
|
1506 |
*/ |
|
1507 |
public static void setSessValue(String key, String val, HttpServletRequest request) { |
|
1508 |
javax.servlet.http.HttpSession session; |
|
1509 |
|
|
1510 |
session = request.getSession(); |
|
1511 |
if (key != null && !key.equals("")) { |
|
1512 |
session.setAttribute(key, val); |
|
1513 |
} |
|
1514 |
} |
|
1515 |
|
|
1516 |
|
|
1517 |
/** |
|
1518 |
* JSP API: A static helper method which takes a key and returns the |
|
1519 |
* value. |
|
1520 |
* @param key The session attribute key name to use. |
|
1521 |
* @param request The HttpServletRequest. |
|
1522 |
* @return String value. |
|
1523 |
*/ |
|
1524 |
public static String getSessValue(String key, HttpServletRequest request) { |
|
1525 |
javax.servlet.http.HttpSession session; |
|
1526 |
String result = ""; |
|
1527 |
|
|
1528 |
if (key != null && !key.equals("") && request != null) { |
|
1529 |
session = request.getSession(); |
|
1530 |
result = (String) session.getAttribute(key); |
|
1531 |
} |
|
1532 |
result = (result == null ? "" : result); |
|
1533 |
return(result); |
|
1534 |
} |
|
1535 |
|
|
1536 |
/** |
|
1537 |
* Query metacat for documents that 'CONTAINS' the value at the specified XPath |
|
1538 |
* expression. Additionally, returns another non-standard field value. |
|
1539 |
* Standard info contains: DocId, DocName, DocType, CreateDate, and UpdateDate. |
|
1540 |
* @param pathExpr String contianing an XPath expression. |
|
1541 |
* @param pathValue String containing a comparison value at the XPath expression. |
|
1542 |
* @param returnFld String containing an XPath expression to a field which will be returned |
|
1543 |
* in addition to the standard info. |
|
1544 |
* @return DOM Document containing the results. |
|
1545 |
*/ |
|
1546 |
public Document query(String pathExpr, String pathValue, String returnFld) { |
|
1547 |
Document result = null; |
|
1548 |
InputStream response; |
|
1549 |
BufferedReader buffy; |
|
1550 |
Properties prop; |
|
1551 |
|
|
1552 |
try { |
|
1553 |
prop = new Properties(); |
|
1554 |
prop.put("action", "query"); |
|
1555 |
prop.put("qformat", "xml"); |
|
1556 |
prop.put(pathExpr, pathValue); |
|
1557 |
if (returnFld != null) { |
|
1558 |
prop.put("returnfield", returnFld); |
|
1559 |
} |
|
1560 |
|
|
1561 |
response = sendData(prop, null, null, 0); |
|
1562 |
if (response != null) { |
|
1563 |
buffy = new BufferedReader(new InputStreamReader(response)); |
|
1564 |
result = XMLUtilities.getXMLReaderAsDOMDocument(buffy); |
|
1565 |
} |
|
1566 |
} catch (IOException ex) { |
|
1567 |
ex.printStackTrace(); |
|
1568 |
} catch (Exception ex) { |
|
1569 |
ex.printStackTrace(); |
|
1570 |
} |
|
1571 |
return(result); |
|
1572 |
} |
|
1573 |
|
|
1574 |
/** |
|
1575 |
* Queries Metacat for document listings, and returns the results in a TreeMap, |
|
1576 |
* where the key is the Doc Id, and the value is the Create Date. If the document |
|
1577 |
* contains the specified 'returnfield', an addtional entry will be created with |
|
1578 |
* the value being a Vector of sub-DocId's. The key of this entry will be the |
|
1579 |
* original DocId with some addtional text added. |
|
1580 |
* Reads request parameters 'pathExpr' (String[]), 'pathValue' (String) |
|
1581 |
* and 'returnfield' (String). |
|
1582 |
* @param request HttpServletRequest. |
|
1583 |
* @return TreeMap |
|
1584 |
*/ |
|
1585 |
public TreeMap getSelectQueryMap(HttpServletRequest request) { |
|
1586 |
TreeMap result; |
|
1587 |
Document doc; |
|
1588 |
NodeList nodeLst, subNodeLst; |
|
1589 |
Node node, subNode; |
|
1590 |
String key, val, paramExpr, paramVal; |
|
1591 |
String value, paths[], returnFld; |
|
1592 |
Vector optGroup; |
|
1593 |
final String DOCID_EXPR = "./docid"; |
|
1594 |
final String DOCNAME_EXPR = "./createdate"; |
|
1595 |
final String PARAM_EXPR = "./param[@name='%1$s']"; |
|
1596 |
|
|
1597 |
paths = (String[]) request.getParameterValues("pathExpr"); |
|
1598 |
returnFld = (String) request.getParameter("returnfield"); |
|
1599 |
value = (String) request.getParameter("pathValue"); |
|
1600 |
|
|
1601 |
result = new TreeMap(); |
|
1602 |
paramExpr = String.format(PARAM_EXPR, returnFld); |
|
1603 |
|
|
1604 |
for(int j = 0; j < paths.length; j++) { |
|
1605 |
//*** Query the database *** |
|
1606 |
doc = query(paths[j], value, returnFld); |
|
1607 |
//*** Build the TreeMap to return *** |
|
1608 |
try { |
|
1609 |
nodeLst = (NodeList) xpath.evaluate("/resultset/document", doc, XPathConstants.NODESET); |
|
1610 |
for (int i = 0; i < nodeLst.getLength(); i++) { |
|
1611 |
node = nodeLst.item(i); |
|
1612 |
key = xpath.evaluate(DOCID_EXPR, node); |
|
1613 |
val = xpath.evaluate(DOCNAME_EXPR, node); |
|
1614 |
result.put(key, key + " (" + val + ")"); |
|
1615 |
|
|
1616 |
//*** returnfield values *** |
|
1617 |
subNodeLst = (NodeList) xpath.evaluate(paramExpr, node, XPathConstants.NODESET); |
|
1618 |
if (subNodeLst.getLength() > 0) { |
|
1619 |
optGroup = new Vector(); |
|
1620 |
for (int k = 0; k < subNodeLst.getLength(); k++) { |
|
1621 |
subNode = subNodeLst.item(k); |
|
1622 |
paramVal = xpath.evaluate("text()", subNode); |
|
1623 |
optGroup.add(paramVal); |
|
1624 |
} |
|
1625 |
result.put(key + " Data Files", optGroup); |
|
1626 |
} |
|
1627 |
|
|
1628 |
} |
|
1629 |
} catch (XPathExpressionException ex) { |
|
1630 |
ex.printStackTrace(); |
|
1631 |
} |
|
1632 |
} |
|
1633 |
return(result); |
|
1634 |
} |
|
1635 |
|
|
1636 |
/** |
|
1637 |
* JSP API: Removes the data Doc Id from the FGDC document in the Metacat database. |
|
1638 |
* It gets the Doc Id to delete from the session (key=docId), and determines what |
|
1639 |
* metadata file is including this file. It then queries metacat for the parent FGDC |
|
1640 |
* document and removes the Doc Id from it, and reloads the new version of the FGDC |
|
1641 |
* document with a new revision number. This is intended to be called after |
|
1642 |
* a call to MetacatClient.delete(docId). |
|
1643 |
* @param request HttpServletRequest which contains the session. |
|
1644 |
* @return String server response, if any. |
|
1645 |
*/ |
|
1646 |
public String removeDataDocIdFromFGDC(HttpServletRequest request) { |
|
1647 |
String docId, parentDocId, result = " ", pathToDigform, revision; |
|
1648 |
Document doc; |
|
1649 |
InputStream response; |
|
1650 |
BufferedReader buffy; |
|
1651 |
Properties prop; |
|
1652 |
Node node; |
|
1653 |
NodeList nodeLst; |
|
1654 |
Reader reader; |
|
1655 |
final String PATH4QUERY = "/metadata/distinfo/stdorder/digform/digtopt/onlinopt/computer/networka/networkr"; |
|
1656 |
final String PATH4ANCESTOR = PATH4QUERY + "[text()='%1$s']/ancestor::node()[name()='%2$s']"; |
|
1657 |
|
|
1658 |
//*** First, determine what metadata file is including this file (if any). |
|
1659 |
docId = getSessValue("docId", request); |
|
1660 |
doc = query(PATH4QUERY, docId, null); |
|
1661 |
try { |
|
1662 |
parentDocId = xpath.evaluate("/resultset/document/docid", doc.getDocumentElement()); |
|
1663 |
if (parentDocId != null && !parentDocId.equals("")) { |
|
1664 |
//*** Next, get the metadata document and update the networkr node. |
|
1665 |
//*** MetaCatServlet Properties: action, qformat and docid. *** |
|
1666 |
prop = new Properties(); |
|
1667 |
prop.put("action", "read"); |
|
1668 |
prop.put("qformat", "xml"); |
|
1669 |
prop.put("docid", parentDocId); |
|
1670 |
response = sendData(prop, null, null, 0); |
|
1671 |
if (response != null) { |
|
1672 |
buffy = new BufferedReader(new InputStreamReader(response)); |
|
1673 |
doc = XMLUtilities.getXMLReaderAsDOMDocument(buffy); |
|
1674 |
//System.out.println("MetacatClinet.removeDataDocIdFromFGDC: BEFORE\n" + XMLUtilities.getDOMTreeAsString(doc.getDocumentElement())); |
|
1675 |
pathToDigform = String.format(PATH4ANCESTOR, docId, "digform"); |
|
1676 |
node = (Node) xpath.evaluate(pathToDigform, doc, XPathConstants.NODE); |
|
1677 |
node.getParentNode().removeChild(node); |
|
1678 |
//System.out.println("MetacatClinet.removeDataDocIdFromFGDC: AFTER\n" + XMLUtilities.getDOMTreeAsString(doc.getDocumentElement())); |
|
1679 |
reader = XMLUtilities.getDOMTreeAsReader(doc.getDocumentElement(), false); |
|
1680 |
revision = nextVersion(parentDocId); |
|
1681 |
result += update(revision, reader, null); |
|
1682 |
} |
|
1683 |
} |
|
1684 |
} catch (Exception ex) { |
|
1685 |
ex.printStackTrace(); |
|
1686 |
} |
|
1687 |
return(result); |
|
1688 |
} |
|
1349 | 1689 |
} |
Also available in: Unified diff
Several newly developed methods providing a JSP API into metacat. Most of the new methods were developed to support FGDC metadata.
Some of the other new methods merely provide convenience to the JSP code. New methods include:
nextVersion, getFGDCdistinfo, addDistInfoToFGDC, vectorToHtmlSelect, mapToHtmlSelect, htmlInput, getSessValue, setSessValue, query, getSelectQueryMap,
and removeDataDocIdFromFGDC.