Project

General

Profile

« Previous | Next » 

Revision 3316

Added by barteau over 17 years ago

Refactored almost all of the JSP API methods and fields to a new package (edu.ucsb.nceas.metacat.clientview).

View differences:

src/edu/ucsb/nceas/metacat/client/MetacatClient.java
24 24

  
25 25
package edu.ucsb.nceas.metacat.client;
26 26

  
27
import com.oreilly.servlet.multipart.FilePart;
28
import com.oreilly.servlet.multipart.MultipartParser;
29
import com.oreilly.servlet.multipart.ParamPart;
30
import com.oreilly.servlet.multipart.Part;
31
import edu.ucsb.nceas.metacat.MetaCatUtil;
32
import java.io.BufferedInputStream;
33
import java.io.BufferedReader;
34 27
import java.io.InputStream;
35 28
import java.io.InputStreamReader;
36 29
import java.io.PushbackReader;
......
39 32
import java.io.StringWriter;
40 33
import java.io.Reader;
41 34
import java.net.URL;
42
import java.util.HashMap;
43
import java.util.Iterator;
44
import java.util.Map;
45 35
import java.util.Properties;
46
import java.util.TreeMap;
47 36
import java.util.Vector;
48
import javax.servlet.ServletContext;
49 37
import javax.servlet.http.HttpServletRequest;
50
import javax.servlet.http.HttpServletResponse;
51 38
import javax.xml.xpath.XPath;
52 39
import javax.xml.xpath.XPathFactory;
53 40
import org.w3c.dom.Document;
54
import org.w3c.dom.DocumentType;
55
import org.w3c.dom.Element;
56 41

  
57 42
import org.w3c.dom.Node;
58 43
import org.w3c.dom.NodeList;
......
61 46
import edu.ucsb.nceas.utilities.IOUtil;
62 47
import edu.ucsb.nceas.utilities.XMLUtilities;
63 48
import java.io.File;
64
import javax.xml.xpath.XPathConstants;
65
import javax.xml.xpath.XPathExpressionException;
66 49

  
67

  
68 50
/**
69 51
 *  This interface provides methods for initializing and logging in to a
70 52
 *  Metacat server, and then querying, reading, transforming, inserting,
......
78 60
    private String sessionId;
79 61
    
80 62
    /**
81
     * Identifies the FGDC DTD.
82
     */
83
    public static final String              FGDC_SYSTEM_ID = "http://www.fgdc.gov/metadata/fgdc-std-001-1998.dtd";
84
    
85
    /**
86
     * Data Document ID location within an FGDC document.  XPath expression.
87
     */
88
    public static final String              FGDC_DATA_FILE_DOCID_XPATH = "/metadata/distinfo/stdorder/digform/digtopt/onlinopt/computer/networka/networkr";
89
    
90
    /**
91
     * Metadata Document ID location within an FGDC document.  XPath expression.
92
     */
93
    public static final String              FGDC_DOCID_XPATH = "/metadata/distinfo/resdesc";
94
    
95
    private static XPath                    xpath = XPathFactory.newInstance().newXPath();
96
    private Document                        loginResponse = null, metadataDoc = null;
97
    private String                          user = null;
98
    
99
    /**
100 63
     * The Login cookie name.
101 64
     */
102 65
    public final static String                    LOGIN_COOOKIE = "cookie";
......
885 848
     *                  in case of upload, otherwise 0
886 849
     * @return      InputStream as returned by Metacat
887 850
     */
888
    synchronized private InputStream sendData(Properties args,
851
    synchronized public InputStream sendData(Properties args,
889 852
            Properties filename,
890 853
            InputStream fileData,
891 854
            int size)
......
986 949
     * @throws edu.ucsb.nceas.metacat.client.MetacatInaccessibleException Received by MetacatFactory.
987 950
     * @return MetacatClient instance.
988 951
     */
989
    public static MetacatClient getMetacatClient(javax.servlet.http.HttpServletRequest request) throws MetacatInaccessibleException {
952
    public static MetacatClient getMetacatClient(HttpServletRequest request) throws MetacatInaccessibleException {
990 953
        MetacatClient                       result;
991 954
        String                              metacatPath = "http://%1$s%2$s/metacat";
992 955
        String                              host, context;
......
1004 967
        return(result);
1005 968
    }
1006 969
    
1007
    /**
1008
     * JSP API: When the user logs in, the server will send back a string containing XML.  Calling
1009
     * this method with the string will allow other methods to work, such as isLoggIn()
1010
     * and getLoginResponseElement().
1011
     * @param xmlString XML in String format.
1012
     * @throws java.io.IOException Input/Output exception.
1013
     */
1014
    public void setLoginResponse(String xmlString) throws IOException {
1015
        if (xmlString != null) {
1016
            loginResponse = XMLUtilities.getXMLReaderAsDOMDocument(new StringReader(xmlString));
1017
        }
1018
    }
1019
    
1020
    private void setMetadataDoc(InputStream ioStream) throws IOException {
1021
        BufferedReader                          buffy;
1022
        
1023
        if (ioStream != null) {
1024
            buffy = new BufferedReader(new InputStreamReader(ioStream));
1025
            metadataDoc = XMLUtilities.getXMLReaderAsDOMDocument(buffy);
1026
        }
1027
    }
1028
    
1029
    public void setMetadataDoc(Document doc) {
1030
        metadataDoc = doc;
1031
    }
1032
    
1033
    public void setMetadataDoc(String docId) throws Exception {
1034
        Document                        doc = null;
1035
        BufferedReader                  buffy;
1036
        Properties                      prop;
1037
        InputStream                     response;
1038
        
1039
        //*** MetaCatServlet Properties: action, qformat and docid. ***
1040
        prop = new Properties();
1041
        prop.put("action", "read");
1042
        prop.put("qformat", "xml");
1043
        prop.put("docid", docId);
1044
        response = sendData(prop, null, null, 0);
1045
        if (response != null) {
1046
            buffy = new BufferedReader(new InputStreamReader(response));
1047
            doc = XMLUtilities.getXMLReaderAsDOMDocument(buffy);
1048
        }
1049
        setMetadataDoc(doc);
1050
    }
1051
    
1052
    public Document getMetadataDoc() {
1053
        return(metadataDoc);
1054
    }
1055
    
1056
    /**
1057
     * JSP API: A convenient and efficient method to retrieve info from the "login response".
1058
     * @param elementName String of the elementName.
1059
     * NOTE: setLoginResponse() must have been called first,
1060
     * otherwise it will always return null.
1061
     * @throws javax.xml.xpath.XPathExpressionException XPath error.
1062
     * @return String containing the text content of the element, or null.
1063
     */
1064
    public String getLoginResponseElement(String elementName) throws XPathExpressionException {
1065
        String                      result = null;
1066
        
1067
        if (loginResponse != null) {
1068
            result = (String) xpath.evaluate(elementName, loginResponse.getDocumentElement(), XPathConstants.STRING);
1069
            if (result != null)
1070
                result = result.trim();
1071
        }
1072
        return(result);
1073
    }
1074
    
1075
    
1076
    /**
1077
     * JSP API: Easy way to get info from an uploaded metadata XML file.
1078
     * Note:  doMetadataUpload() must have been called first.
1079
     * @param elementName String containing the elemement name
1080
     * @throws javax.xml.xpath.XPathExpressionException Thrown by XPath
1081
     * @return String text content of the named element
1082
     */
1083
    public String getMetadataDocElement(String elementName) throws XPathExpressionException {
1084
        String                      result = null;
1085
        
1086
        if (metadataDoc != null) {
1087
            result = (String) xpath.evaluate(elementName, metadataDoc.getDocumentElement(), XPathConstants.STRING);
1088
            result = result.trim();
1089
        }
1090
        return(result);
1091
    }
1092
    
1093
    /**
1094
     * JSP API: A convenience method to be used by JSP or any other client code that requires
1095
     * the user to be logged in.  NOTE: setUser() must have been called first,
1096
     * otherwise it will always return false.
1097
     * @return boolean  true if user has logged in for this session, false otherwise.
1098
     */
1099
    public boolean isLoggedIn() {
1100
        return(user != null);
1101
    }
1102
    
1103
    /**
1104
     * JSP API: Get the user's name.  This will be what was entered for the user name,
1105
     * and is not the LDAP user name.
1106
     * @return String of the users name.
1107
     */
1108
    public String getUser() {
1109
        return(user);
1110
    }
1111
    
1112
    /**
1113
     * JSP API: After calling "login(ldapUserName, pwd)", call this with the username
1114
     * and servers response message.  You can than use isLoggedIn() to determine if
1115
     * the user is logged in, getLoginResponseElement(), etc.  The user name will also
1116
     * used by calls to doMetadataUpload() for Document Id creation (scope).
1117
     * @param userName User name
1118
     * @param serverResponse XML login response sent from Metacat.
1119
     */
1120
    public void setUser(String userName, String serverResponse) {
1121
        
1122
        if (serverResponse != null && serverResponse.contains("login")) {
1123
            user = userName;
1124
            System.out.println("MetacatClient.setUser: getSessionId() = " + getSessionId());
1125
        } else {
1126
            user = null;
1127
        }
1128
    }
1129
    
1130
    /**
1131
     * JSP API:  Handles metadata file and data file uploads for inserting new
1132
     * Metacat data packages.  Note: if content type is not "multipart/form-data",
1133
     * nothing will happen; thus, it's safe to be (unintentionally) called by other
1134
     * types of form submissions.
1135
     * @param request HTTP request.
1136
     * @return A 1-line status message for the user.
1137
     */
1138
    public String doMetadataUpload(javax.servlet.http.HttpServletRequest request) {
1139
        String                      result = "", contentType, formatType;
1140
        String                      lastDocId, nextDocId, metaDocId;
1141
        StringBuilder               fileName = new StringBuilder();
1142
        Reader                      reader;
1143
        int                         sizeLimit, idx;
1144
        MultipartParser             multipartParser;
1145
        InputStream                 inputStream;
1146
        Node                        newBranch, metaRootNode;
1147
        HashMap                     dataDocIDs, paramsMap;
1148
        
1149
        
1150
        ServletContext cntxt = request.getSession().getServletContext().getContext("/knb/metacat");
1151
        String servletName = cntxt.getServletContextName();
1152
        
1153
        //*** Only process request if a file upload.
1154
        contentType = request.getContentType();
1155
        if (isLoggedIn() && contentType != null && contentType.contains("multipart/form-data")) {
1156
            try {
1157
                //*** Init the MultipartParser.
1158
                sizeLimit = (new Integer(MetaCatUtil.getOption("datafilesizelimit"))).intValue();
1159
                multipartParser = new MultipartParser(request, sizeLimit * 1024 * 1024);
1160
                
1161
                //*** Get the First file, which should be the metadata file.
1162
                paramsMap = new HashMap();
1163
                inputStream = getNextInputStream(multipartParser, fileName, paramsMap);
1164
                if (fileName.toString().toLowerCase().endsWith(".xml")) {
1165
                    setMetadataDoc(inputStream);
1166
                    
1167
                    //*** Get the Metadata File's DOC ID.
1168
                    lastDocId = getLastDocid(user);
1169
                    metaDocId = lastDocId = nextDocId(lastDocId);
1170
                    
1171
                    if (isFGDC()) {
1172
                        //*** Loop thru all of the data files, get fileName and inputStream.
1173
                        dataDocIDs = new HashMap();
1174
                        fileName = new StringBuilder();
1175
                        while ((inputStream = getNextInputStream(multipartParser, fileName, paramsMap)) != null) {
1176
                            //*** Get the data file's DOC ID.
1177
                            nextDocId = nextDocId(lastDocId);
1178
                            //*** Set the file format (just using file extension for now).
1179
                            idx = fileName.lastIndexOf(".");
1180
                            if (idx > 1)
1181
                                formatType = fileName.substring(idx+1).toUpperCase();
1182
                            else
1183
                                formatType = "";
1184
                            dataDocIDs.put(nextDocId, formatType);
1185
                            //*** Upload the data file to metacat.
1186
                            upload(nextDocId, fileName.toString(), inputStream, Integer.MAX_VALUE);
1187
                            
1188
                            lastDocId = nextDocId;
1189
                            fileName = new StringBuilder();
1190
                        }
1191
                        
1192
                        //*** Store the User Name and Doc Id in the FGDC document.
1193
                        newBranch = getFGDCdisinfo(getLoginResponseElement("name"), metaDocId, dataDocIDs);
1194
                        System.out.println("MetacatClient.doMetadataUpload: " + XMLUtilities.getDOMTreeAsString(newBranch));
1195
                        metaRootNode = addDistInfoToFGDC(newBranch);
1196
                        
1197
                        //*** Upload the metadata file to metacat.
1198
                        reader = XMLUtilities.getDOMTreeAsReader(metadataDoc.getDocumentElement(), false);
1199
                        insert(metaDocId, reader, null);
1200
                        
1201
                        result = "MetaCat Package Inserted:  the Document Identifier is " + metaDocId;
1202
                        reader.close();
1203
                        
1204
                        //*** One last detail...grant the public read access.
1205
                        if (paramsMap.containsKey("publicAccess"))
1206
                            setAccess(metaDocId, "public", "read", "allow", "allowFirst");
1207
                        
1208
                    } else {
1209
                        System.out.println("MetacatClient.doUpload: not an FGDC file = " + fileName);
1210
                        result = fileName + " is not an FGDC file.  Files not uploaded.";
1211
                        //TODO add other types of metadata grammars here...
1212
                    }
1213
                } else {
1214
                    result = "The first file must be an XML Metadata file.  Files not uploaded.";
1215
                }
1216
                if (inputStream != null)
1217
                    inputStream.close();
1218
            } catch (MetacatException ex)  {
1219
                result = ex.getMessage();
1220
                System.out.println("MetacatClient.doUpload: MetacatException = " + result);
1221
            } catch (IOException ex)  {
1222
                System.out.println("MetacatClient.doUpload: " + ex);
1223
            } catch (Exception ex) {
1224
                System.out.println("MetacatClient.doUpload: " + ex);
1225
            } catch (Error err) {
1226
                System.out.println("MetacatClient.doUpload: ERR - " + err.getCause());
1227
                result = "ERR: " + err.getMessage();
1228
            }
1229
        }
1230
        return(result);
1231
    }
1232
    
1233
    private InputStream getNextInputStream(MultipartParser multipartParser, StringBuilder fileName, HashMap paramsMap)
1234
    throws IOException {
1235
        InputStream                     result = null;
1236
        Part                            part;
1237
        String                          parmName = null, value = null, fnam;
1238
        
1239
        while ((part = multipartParser.readNextPart()) != null) {
1240
            if (part.isParam()) {
1241
                parmName = part.getName();
1242
                value = ((ParamPart) part).getStringValue();
1243
                paramsMap.put(parmName, value);
1244
                System.out.println("MetacatClient.doUpload: parmName = " + parmName + "  value = " + value);
1245
                
1246
            } else if (part.isFile()) {
1247
                fnam = ((FilePart) part).getFileName();
1248
                if (fnam != null && !fnam.equals("")) {
1249
                    //*** File name is passed back via StringBuilder fileName param.
1250
                    fileName.append(fnam);
1251
                    result = ((FilePart) part).getInputStream();
1252
                    System.out.println("MetacatClient.doUpload: fileName = " + fileName + "  inputStream = " + result.toString());
1253
                    break;
1254
                }
1255
            }
1256
        }
1257
        return(result);
1258
    }
1259
    
1260
    private String nextDocId(String lastDocId) {
1261
        String                      result = null, tokens[];
1262
        int                         vers;
1263
        String                      template = user.toLowerCase() + ".%1$d.%2$d";
1264
        
1265
        if(lastDocId != null && lastDocId.contains(".")) {
1266
            lastDocId = lastDocId.replace('.','~'); //*** This is necessary for the split to work.
1267
            tokens = lastDocId.split("~");
1268
            if(tokens.length > 1 && !tokens[1].equals("")) {
1269
                try {
1270
                    vers = Integer.parseInt(tokens[1]);
1271
                    result = String.format(template, 1 + vers, 1);
1272
                } catch (NumberFormatException ex) {
1273
                    //*** In case the lastDocId has something other than a number.
1274
                    result = String.format(template, 1, 1);
1275
                }
1276
            } else {
1277
                //*** In case the lastDocId ends with a '.'
1278
                result = String.format(template, 1, 1);
1279
            }
1280
        } else {
1281
            //*** In case there isn't any doc Id's with the user name.
1282
            result = String.format(template, 1, 1);
1283
        }
1284
        return(result);
1285
    }
1286
    
1287
    private String nextVersion(String lastDocId) throws XPathExpressionException {
1288
        String                      result = null, tokens[], scope, xPathQuery, ready2Split;
1289
        int                         vers, docNum;
1290
        final int                   LAST_TOKEN = 2;
1291
        final String                TEMPLATE = "%1$s.%2$d.%3$d";
1292
        final String                XPATH_QUERY_TEMPLATE = FGDC_DOCID_XPATH + "[text()='%1$s']";
1293
        Node                        node;
1294
        
1295
        //*** Parse the last Doc Id, and increment the version number.
1296
        if(lastDocId != null && lastDocId.contains(".")) {
1297
            ready2Split = lastDocId.replace('.','~'); //*** This is necessary for the split to work.
1298
            tokens = ready2Split.split("~");
1299
            if(tokens.length > LAST_TOKEN && !tokens[LAST_TOKEN].equals("")) {
1300
                scope = tokens[LAST_TOKEN - 2];
1301
                docNum = Integer.parseInt(tokens[LAST_TOKEN - 1]);
1302
                try {
1303
                    vers = Integer.parseInt(tokens[LAST_TOKEN]);
1304
                    result = String.format(TEMPLATE, scope, docNum, 1 + vers);
1305
                } catch (NumberFormatException ex) {
1306
                    //*** In case the lastDocId has something other than a number.
1307
                    result = String.format(TEMPLATE, scope, docNum, 1);
1308
                }
1309
            } else {
1310
                //*** In case the lastDocId ends with a '.'
1311
                result = lastDocId + "1";
1312
            }
1313
        } else {
1314
            //*** In case of missing doc Id.
1315
            result = null;
1316
        }
1317
        
1318
        //*** Update the Doc Id in the metadata file.
1319
        if (getMetadataDoc() != null) {
1320
            xPathQuery = String.format(XPATH_QUERY_TEMPLATE, lastDocId);
1321
            node = (Node) xpath.evaluate(xPathQuery, getMetadataDoc().getDocumentElement(), XPathConstants.NODE);
1322
            node.setTextContent(result);
1323
        }
1324
        return(result);
1325
    }
1326
    
1327
    private boolean isFGDC() {
1328
        boolean                     result = false;
1329
        DocumentType                docType;
1330
        String                      sysId;
1331
        final String                FGDC_TEST_EXPRESSION = "/metadata/idinfo/citation/citeinfo/title";
1332
        Node                        node = null;
1333
        
1334
        //*** First, try the rigid proper way of determining it.
1335
        if (getMetadataDoc() != null) {
1336
            docType = getMetadataDoc().getDoctype();
1337
            if (docType != null) {
1338
                sysId = docType.getSystemId();
1339
                if (sysId != null)
1340
                    result = sysId.contains(FGDC_SYSTEM_ID);
1341
            }
1342
        }
1343
        //*** It might not have a doc type line, so try another method.
1344
        if (getMetadataDoc() != null && !result) {
1345
            try {
1346
                node = (Node) xpath.evaluate(FGDC_TEST_EXPRESSION, getMetadataDoc().getDocumentElement(), XPathConstants.NODE);
1347
            } catch (XPathExpressionException ex) {
1348
                ex.printStackTrace();
1349
            }
1350
            result = (node != null);
1351
        }
1352
        return(result);
1353
    }
1354
    
1355
    private Node getFGDCdisinfo(String contactName, String resourceDescription, HashMap dataDocIDs) throws IOException {
1356
        Node                        result = null, node, digformBranch, formname, stdorder;
1357
        Document                    doc;
1358
        Iterator                    iterIt;
1359
        String                      key, value;
1360
        
1361
        //*** This is a valid/minimal FGDC "distinfo" branch.
1362
        final String XML = "<distinfo>"
1363
                + "    <distrib>"
1364
                + "        <cntinfo>"
1365
                + "            <cntperp>"
1366
                + "                <cntper></cntper>"
1367
                + "            </cntperp>"
1368
                + "            <cntaddr>"
1369
                + "                <addrtype></addrtype>"
1370
                + "                <address></address>"
1371
                + "                <city></city>"
1372
                + "                <state></state>"
1373
                + "                <postal></postal>"
1374
                + "                <country></country>"
1375
                + "            </cntaddr>"
1376
                + "            <cntvoice></cntvoice>"
1377
                + "        </cntinfo>"
1378
                + "    </distrib>"
1379
                + "    <resdesc></resdesc>"
1380
                + "    <distliab></distliab>"
1381
                + "    <stdorder>"
1382
                + "        <digform>"
1383
                + "            <digtinfo>"
1384
                + "                <formname></formname>"
1385
                + "            </digtinfo>"
1386
                + "            <digtopt>"
1387
                + "                <onlinopt>"
1388
                + "                    <computer>"
1389
                + "                        <networka>"
1390
                + "                            <networkr></networkr>"
1391
                + "                        </networka>"
1392
                + "                    </computer>"
1393
                + "                </onlinopt>"
1394
                + "            </digtopt>"
1395
                + "        </digform>"
1396
                + "        <fees></fees>"
1397
                + "    </stdorder>"
1398
                + "</distinfo>";
1399
        
1400
        doc = XMLUtilities.getXMLReaderAsDOMDocument(new StringReader(XML));
1401
        result = doc.getDocumentElement();
1402
        try {
1403
            //*** Set the Contact Person.
1404
            node = (Node) xpath.evaluate("/distinfo/distrib/cntinfo/cntperp/cntper", result, XPathConstants.NODE);
1405
            node.setTextContent(contactName);
1406
            //*** Set the metadata Doc Id.
1407
            node = (Node) xpath.evaluate("/distinfo/resdesc", result, XPathConstants.NODE);
1408
            node.setTextContent(resourceDescription);
1409
            
1410
            //*** Loop thru the files, setting their format and Doc Id.
1411
            stdorder = (Node) xpath.evaluate("/distinfo/stdorder", result, XPathConstants.NODE);
1412
            digformBranch = (Node) xpath.evaluate("/distinfo/stdorder/digform", result, XPathConstants.NODE);
1413
            iterIt = dataDocIDs.keySet().iterator();
1414
            while(iterIt.hasNext()) {
1415
                //*** Save the data file Doc ID (required).
1416
                key = (String) iterIt.next();
1417
                node = (Node) xpath.evaluate("digtopt/onlinopt/computer/networka/networkr", digformBranch, XPathConstants.NODE);
1418
                node.setTextContent(key);
1419
                //*** Save the data file format (optional).
1420
                formname = (Node) xpath.evaluate("digtinfo/formname", digformBranch, XPathConstants.NODE);
1421
                if ((value = (String) dataDocIDs.get(key)) != null && !value.equals("")) {
1422
                    formname.setTextContent(value);
1423
                } else {
1424
                    //*** We did a deep clone of the branch, so clear prior contents.
1425
                    formname.setTextContent("");
1426
                }
1427
                
1428
                //*** Clone branch for next file.
1429
                if (iterIt.hasNext()) {
1430
                    digformBranch = digformBranch.cloneNode(true);
1431
                    stdorder.appendChild(digformBranch);
1432
                }
1433
            }
1434
        } catch (XPathExpressionException ex) {
1435
            ex.printStackTrace();
1436
        }
1437
        return(result);
1438
    }
1439
    
1440
    private Node addDistInfoToFGDC(Node newBranch) {
1441
        Node                        result = null, node;
1442
        
1443
        if (newBranch != null) {
1444
            result = metadataDoc.getDocumentElement();
1445
            try {
1446
                //*** Get a reference to the FGDC required "metainfo" node (only 1 allowed).
1447
                node = (Node) xpath.evaluate("/metadata/metainfo", result, XPathConstants.NODE);
1448
                if (node != null) {
1449
                    newBranch = metadataDoc.importNode(newBranch, true);
1450
                    //*** Add the new "distinfo" before it.
1451
                    result.insertBefore(newBranch, node);
1452
                }
1453
            } catch (XPathExpressionException ex) {
1454
                ex.printStackTrace();
1455
            }
1456
        }
1457
        return(result);
1458
    }
1459
    
1460
    private static final String                SELECT_TEMPLATE = "<select name='%1$s' style='%2$s' size='%3$s'>\n%4$s</select>\n";
1461
    private static final String                OPTION_TEMPLATE = "<option value='%1$s'>%2$s</option>\n";
1462
    private static final String                OPTGRP_TEMPLATE = "<optgroup label='%1$s'>%2$s</optgroup>";
1463
    private static final String                INPUT_TEMPLATE = "<input name='%1$s' value='%2$s' type='%4$s' class='%3$s' size='%5$d'/>\n";
1464
    
1465
    /**
1466
     * JSP API: A static helper method which takes a vector (keys/values) and returns
1467
     * an XHTML SELECT String.
1468
     * @param vector The vector contianing the values to convert into an HTML SELECT statement.
1469
     * @param name The name to assign the HTML SELECT, which will become the parameter name.
1470
     * @param style Any HTML styling text.
1471
     * @param size HTML field width.
1472
     * @return String, XHTML for a SELECT statement.
1473
     */
1474
    public static String vectorToHtmlSelect(Vector vector, String name, String style, int size) {
1475
        String                      result = "", item;
1476
        Iterator<String>            iterIt;
1477
        
1478
        iterIt = vector.iterator();
1479
        while(iterIt.hasNext()) {
1480
            item = iterIt.next();
1481
            item = String.format(OPTION_TEMPLATE, item, item);
1482
            result += item;
1483
        }
1484
        result = String.format(SELECT_TEMPLATE, name, style, size, result);
1485
        return(result);
1486
    }
1487
    
1488
    /**
1489
     * JSP API: A static helper method which takes a map (key, value pairs) and returns
1490
     * an XHTML SELECT String.
1491
     * @param map The map contianing the key, value pairs to convert into an HTML SELECT
1492
     * statement.
1493
     * @param name The name to assign the HTML SELECT, which will become the parameter name.
1494
     * @param style Any HTML styling text.
1495
     * @param size HTML field width.
1496
     * @return String, XHTML for a SELECT statement.
1497
     */
1498
    public static String mapToHtmlSelect(Map map, String name, String style, int size) {
1499
        String                      result = "", item, key, optGrp;
1500
        Iterator<String>            iterIt;
1501
        Object                      obj;
1502
        Vector                      vector;
1503
        Iterator                    completeIterIt;
1504
        
1505
        iterIt = map.keySet().iterator();
1506
        while(iterIt.hasNext()) {
1507
            key = iterIt.next();
1508
            obj = map.get(key);
1509
            if (obj instanceof String) {
1510
                item = (String) obj;
1511
                item = String.format(OPTION_TEMPLATE, key, item);
1512
                result += item;
1513
            } else if (obj instanceof Vector) {
1514
                vector = (Vector) obj;
1515
                optGrp = "";
1516
                completeIterIt = vector.iterator();
1517
                while (completeIterIt.hasNext()) {
1518
                    item = (String) completeIterIt.next();
1519
                    item = String.format(OPTION_TEMPLATE, item, item);
1520
                    optGrp += item;
1521
                }
1522
                item = String.format(OPTGRP_TEMPLATE, key, optGrp);
1523
                result += item;
1524
            }
1525
        }
1526
        result = String.format(SELECT_TEMPLATE, name, style, size, result);
1527
        return(result);
1528
    }
1529
    
1530
    
1531
    /**
1532
     * JSP API: A static helper method which takes attribute values and returns
1533
     * an XHTML INPUT Statement.
1534
     * @param type The 'type attribute' of the input statement.
1535
     * @param name The 'name attribute' of the input statement.
1536
     * @param value The 'value attribute' of the input statement.
1537
     * @param cssClass The CSS 'class attribute'.
1538
     * @param fldSize HTML field width.
1539
     * @return String, XHTML for an INPUT statement.
1540
     */
1541
    public static String htmlInput(String type, String name, String value, String cssClass, int fldSize) {
1542
        String                          result;
1543
        
1544
        result = String.format(INPUT_TEMPLATE, name, value, cssClass, type, fldSize);
1545
        return(result);
1546
    }
1547
    
1548
    
1549
    /**
1550
     * JSP API: A static helper method which takes a key/value pair and saves
1551
     * it in the session.
1552
     * @param key The session attribute key name to use.
1553
     * @param val The value to assign.
1554
     * @param request The HttpServletRequest.
1555
     */
1556
    public static void setSessValue(String key, String val, HttpServletRequest request) {
1557
        javax.servlet.http.HttpSession      session;
1558
        
1559
        session = request.getSession();
1560
        if (key != null && !key.equals("")) {
1561
            session.setAttribute(key, val);
1562
        }
1563
    }
1564
    
1565
    
1566
    /**
1567
     * JSP API: A static helper method which takes a key and returns the
1568
     * value.
1569
     * @param key The session attribute key name to use.
1570
     * @param request The HttpServletRequest.
1571
     * @return String value.
1572
     */
1573
    public static String getSessValue(String key, HttpServletRequest request) {
1574
        javax.servlet.http.HttpSession      session;
1575
        String                              result = "";
1576
        
1577
        if (key != null && !key.equals("") && request != null) {
1578
            session = request.getSession();
1579
            result = (String) session.getAttribute(key);
1580
        }
1581
        result = (result == null ? "" : result);
1582
        return(result);
1583
    }
1584
    
1585
    /**
1586
     * Query metacat for documents that 'CONTAINS' the value at the specified XPath
1587
     * expression.  Additionally, returns another non-standard field value.
1588
     * Standard info contains: DocId, DocName, DocType, CreateDate, and UpdateDate.
1589
     * @param pathExpr String contianing an XPath expression.
1590
     * @param pathValue String containing a comparison value at the XPath expression.
1591
     * @param returnFld String containing an XPath expression to a field which will be returned
1592
     * in addition to the standard info.
1593
     * @return DOM Document containing the results.
1594
     */
1595
    public Document query(String pathExpr, String pathValue, String returnFld) {
1596
        Document                        result = null;
1597
        InputStream                     response;
1598
        BufferedReader                  buffy;
1599
        Properties                      prop;
1600
        
1601
        try {
1602
            prop = new Properties();
1603
            prop.put("action", "query");
1604
            prop.put("qformat", "xml");
1605
            prop.put(pathExpr, pathValue);
1606
            if (returnFld != null) {
1607
                prop.put("returnfield", returnFld);
1608
            }
1609
            
1610
            response = sendData(prop, null, null, 0);
1611
            if (response != null) {
1612
                buffy = new BufferedReader(new InputStreamReader(response));
1613
                result = XMLUtilities.getXMLReaderAsDOMDocument(buffy);
1614
            }
1615
        } catch (IOException ex) {
1616
            ex.printStackTrace();
1617
        } catch (Exception ex) {
1618
            ex.printStackTrace();
1619
        }
1620
        return(result);
1621
    }
1622
    
1623
    /**
1624
     * Queries Metacat for document listings, and returns the results in a TreeMap,
1625
     * where the key is the Doc Id, and the value is the Create Date.  If the document
1626
     * contains the specified 'returnfield', an addtional entry will be created with
1627
     * the value being a Vector of sub-DocId's.  The key of this entry will be the
1628
     * original DocId with some addtional text added.
1629
     * Reads request parameters 'pathExpr' (String[]), 'pathValue' (String)
1630
     * and 'returnfield' (String).
1631
     * @param request HttpServletRequest.
1632
     * @return TreeMap
1633
     */
1634
    public TreeMap getSelectQueryMap(HttpServletRequest request) {
1635
        TreeMap                         result;
1636
        Document                        doc;
1637
        NodeList                        nodeLst, subNodeLst;
1638
        Node                            node, subNode;
1639
        String                          key, val, paramExpr, paramVal;
1640
        String                          value, paths[], returnFld;
1641
        Vector                          optGroup;
1642
        final String                    DOCID_EXPR = "./docid";
1643
        final String                    DOCNAME_EXPR = "./createdate";
1644
        final String                    PARAM_EXPR = "./param[@name='%1$s']";
1645
        
1646
        paths = (String[]) request.getParameterValues("pathExpr");
1647
        returnFld = (String) request.getParameter("returnfield");
1648
        value = (String) request.getParameter("pathValue");
1649
        
1650
        result = new TreeMap();
1651
        paramExpr = String.format(PARAM_EXPR, returnFld);
1652
        
1653
        for(int j = 0; j < paths.length; j++) {
1654
            //*** Query the database ***
1655
            doc = query(paths[j], value, returnFld);
1656
            //*** Build the TreeMap to return ***
1657
            try {
1658
                nodeLst = (NodeList) xpath.evaluate("/resultset/document", doc, XPathConstants.NODESET);
1659
                for (int i = 0; i < nodeLst.getLength(); i++) {
1660
                    node = nodeLst.item(i);
1661
                    key = xpath.evaluate(DOCID_EXPR, node);
1662
                    val = xpath.evaluate(DOCNAME_EXPR, node);
1663
                    result.put(key, key + " (" + val + ")");
1664
                    
1665
                    //*** returnfield values ***
1666
                    subNodeLst = (NodeList) xpath.evaluate(paramExpr, node, XPathConstants.NODESET);
1667
                    if (subNodeLst.getLength() > 0) {
1668
                        optGroup = new Vector();
1669
                        for (int k = 0; k < subNodeLst.getLength(); k++) {
1670
                            subNode =  subNodeLst.item(k);
1671
                            paramVal = xpath.evaluate("text()", subNode);
1672
                            optGroup.add(paramVal);
1673
                        }
1674
                        result.put(key + " Data Files", optGroup);
1675
                    }
1676
                    
1677
                }
1678
            } catch (XPathExpressionException ex) {
1679
                ex.printStackTrace();
1680
            }
1681
        }
1682
        return(result);
1683
    }
1684
    
1685
    private String removeDataDocIdFromFGDC(String docId, String parentDocId) throws Exception {
1686
        String                          pathToDigform, revision = "";
1687
        Document                        doc;
1688
        InputStream                     response;
1689
        BufferedReader                  buffy;
1690
        Properties                      prop;
1691
        Node                            node;
1692
        NodeList                        nodeLst;
1693
        Reader                          reader;
1694
        final String                    PATH4ANCESTOR = FGDC_DATA_FILE_DOCID_XPATH + "[text()='%1$s']/ancestor::node()[name()='%2$s']";
1695
        
1696
        //*** Get the metadata document and remove the digform branch.
1697
        doc = getMetadataDoc();
1698
        if (doc != null) {
1699
            //System.out.println("MetacatClinet.removeDataDocIdFromFGDC: BEFORE\n" + XMLUtilities.getDOMTreeAsString(doc.getDocumentElement()));
1700
            pathToDigform = String.format(PATH4ANCESTOR, docId, "digform");
1701
            node = (Node) xpath.evaluate(pathToDigform, doc.getDocumentElement(), XPathConstants.NODE);
1702
            node.getParentNode().removeChild(node);
1703
            //System.out.println("MetacatClinet.removeDataDocIdFromFGDC: AFTER\n" + XMLUtilities.getDOMTreeAsString(doc.getDocumentElement()));
1704
            
1705
            revision = nextVersion(parentDocId);
1706
            reader = XMLUtilities.getDOMTreeAsReader(doc.getDocumentElement(), false);
1707
            update(revision, reader, null);
1708
        }
1709
        return(revision);
1710
    }
1711
    
1712
    /**
1713
     * Removes the data Doc Id from the FGDC document in the Metacat database.
1714
     * Determines what
1715
     * metadata file is including this file.  It then queries metacat for the parent FGDC
1716
     * document and removes the Doc Id from it, and reloads the new version of the FGDC
1717
     * document with a new revision number.  This is intended to be called after
1718
     * a call to MetacatClient.delete(docId).
1719
     * @param docId String which contains the document Id.
1720
     * @return String server response, if any.
1721
     */
1722
    public void clientDeleteRequest(HttpServletRequest request) {
1723
        String                      result = null, docId, subDocId, parentDocId, revisedDocId;
1724
        NodeList                    nodeLst;
1725
        final String                SUB_DOCS_PATH = FGDC_DATA_FILE_DOCID_XPATH + "/text()";
1726
        Node                        node;
1727
        Document                    resultSetDoc;
1728
        
1729
        docId = getSessValue("docId", request);
1730
        try {
1731
            //*** First, determine what metadata file is including this file (if any).
1732
            resultSetDoc = query(FGDC_DATA_FILE_DOCID_XPATH, docId, null);
1733
            parentDocId = xpath.evaluate("/resultset/document/docid", resultSetDoc.getDocumentElement());
1734
            if (parentDocId != null && !parentDocId.equals("")) {
1735
                setMetadataDoc(parentDocId);
1736
                //*** Remove Doc Id from any parent metadata document.
1737
                revisedDocId = removeDataDocIdFromFGDC(docId, parentDocId);
1738
                setSessValue("docId", revisedDocId, request);
1739
            } else {
1740
                setMetadataDoc(docId);
1741
                //*** This is a metadata document, so remove all of the sub-docId's.
1742
                nodeLst = (NodeList) xpath.evaluate(SUB_DOCS_PATH, getMetadataDoc().getDocumentElement(), XPathConstants.NODESET);
1743
                for(int i = 0; i < nodeLst.getLength(); i++) {
1744
                    node = nodeLst.item(i);
1745
                    subDocId = node.getNodeValue();
1746
                    //*** Remove the sub-document.
1747
                    try {
1748
                        delete(subDocId);
1749
                    } catch (MetacatException ex) {
1750
                        ex.printStackTrace();
1751
                    }
1752
                }
1753
            }
1754
            //*** Remove the document.
1755
            result = delete(docId);
1756
            //*** Save the server feedback in the session, to be used by the view.
1757
            setSessValue("updateFeedback", result, request);
1758
        } catch (Exception ex) {
1759
            ex.printStackTrace();
1760
        }
1761
    }
1762 970
}

Also available in: Unified diff