Project

General

Profile

1
/*
2
 * ClientViewHelper.java
3
 *
4
 * Created on June 25, 2007, 9:57 AM
5
 *
6
 * To change this template, choose Tools | Template Manager
7
 * and open the template in the editor.
8
 */
9

    
10
package edu.ucsb.nceas.metacat.clientview;
11

    
12
import com.oreilly.servlet.multipart.FilePart;
13
import com.oreilly.servlet.multipart.MultipartParser;
14
import com.oreilly.servlet.multipart.ParamPart;
15
import com.oreilly.servlet.multipart.Part;
16
import edu.ucsb.nceas.metacat.client.InsufficientKarmaException;
17
import edu.ucsb.nceas.metacat.client.MetacatClient;
18
import edu.ucsb.nceas.metacat.client.MetacatException;
19
import edu.ucsb.nceas.metacat.client.MetacatFactory;
20
import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException;
21
import edu.ucsb.nceas.metacat.properties.PropertyService;
22
import edu.ucsb.nceas.metacat.service.SessionService;
23
import edu.ucsb.nceas.metacat.util.SessionData;
24
import edu.ucsb.nceas.utilities.XMLUtilities;
25
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
26
import java.io.BufferedReader;
27
import java.io.ByteArrayOutputStream;
28
import java.io.IOException;
29
import java.io.InputStream;
30
import java.io.InputStreamReader;
31
import java.io.Reader;
32
import java.io.StringReader;
33
import java.util.HashMap;
34
import java.util.Iterator;
35
import java.util.Properties;
36
import java.util.Stack;
37
import java.util.TreeMap;
38
import java.util.Vector;
39
import javax.servlet.http.Cookie;
40
import javax.servlet.http.HttpServletRequest;
41
import javax.servlet.http.HttpServletResponse;
42
import javax.servlet.http.HttpSession;
43
import javax.xml.xpath.XPath;
44
import javax.xml.xpath.XPathConstants;
45
import javax.xml.xpath.XPathExpressionException;
46
import javax.xml.xpath.XPathFactory;
47
import org.w3c.dom.DOMException;
48
import org.w3c.dom.Document;
49
import org.w3c.dom.Node;
50
import org.w3c.dom.NodeList;
51
import org.w3c.dom.Text;
52

    
53
/**
54
 *
55
 * @author barteau
56
 */
57
public class ClientViewHelper {
58
    private XPath                                       xpath = XPathFactory.newInstance().newXPath();
59
    private HttpSession                                 clientSession;
60
    private ClientView                                  clientViewBean = null;
61
    private MetacatClient                               metacatClient = null;
62
    private boolean                                     loggedIn = false;
63
    private Document                                    metadataDoc = null;
64
    private int                                         sizeLimit;
65
    private String                                      contactName = "";
66
    
67
    private static final String                         LDAP_TEMPLATE = "uid=%1s,o=%2s,dc=ecoinformatics,dc=org";
68
    
69
    public static final String                          DOWNLOAD_ACTION = "Download";
70
    
71
    public static final String                          PERMISSION_TYPE_ALLOW = "allow";
72
    
73
    public static final String                          PERMISSION_TYPE_DISALLOW = "deny";
74
    
75
    /**
76
     * Creates a new instance of ClientViewHelper, using info in an HttpServletRequest
77
     * for initializing.
78
     * @param request HttpServletRequest, sent from the client browser.
79
     * @throws edu.ucsb.nceas.metacat.client.MetacatInaccessibleException Thrown
80
     */
81
    public ClientViewHelper(HttpServletRequest request) throws MetacatInaccessibleException {
82
        String                              host, context;
83
        
84
        clientSession = request.getSession(false);
85
        host = request.getHeader("host");
86
        context = request.getContextPath();
87
        init(host, context);
88
    }
89
    
90
    /**
91
     * Creates a new instance of ClientViewHelper, using parameter values
92
     * for initializing.  This constructor is plain java code so it's the portal of
93
     * choice for JUnit testing.
94
     * @param host The host with port (if needed), such as "localhost:8084".
95
     * @param context The application root context.
96
     * @param bean ClientView instance, with pre-populated values.
97
     * @throws edu.ucsb.nceas.metacat.client.MetacatInaccessibleException thrown
98
     */
99
    public ClientViewHelper(String host, String context, ClientView bean) throws MetacatInaccessibleException {
100
        clientViewBean = bean;
101
        init(host, context);
102
    }
103
    
104
    private void init(String host, String context) throws MetacatInaccessibleException {
105
        String                              metacatPath = "http://%1s%2s/metacat";
106
        String                              tmp;
107
        
108
        tmp = metacatPath.replaceFirst("%1s", host);
109
        metacatPath = tmp.replaceFirst("%2s", context);
110
        metacatClient = (MetacatClient) MetacatFactory.createMetacatConnection(metacatPath);
111
        try {
112
        	sizeLimit = 
113
        		(new Integer(PropertyService.getProperty("replication.datafilesizelimit"))).intValue();
114
        } catch (PropertyNotFoundException pnfe) {
115
        	throw new MetacatInaccessibleException(pnfe.getMessage());
116
        }
117
    }
118
    
119
    /**
120
     * Main web API method for handling various actions.
121
     * @param request HttpServletRequest
122
     * @param response HttpServletResponse
123
     * @return String message
124
     */
125
    public String clientRequest(HttpServletRequest request, HttpServletResponse response)  {
126
        String                              result = null, action, contentType;
127
        MultipartParser                     multipartParser;
128
        HashMap<String, Object>             responseMap;
129
        
130
        getMetacatClient().setSessionId(request.getSession().getId());
131
        
132
        if (clientViewBean == null) {
133
            clientViewBean = (ClientView) clientSession.getAttribute(ClientView.CLIENT_VIEW_BEAN);
134
            
135
            if (clientViewBean == null) {
136
            	//make a new one and shove it in the session
137
            	clientViewBean = new ClientView();
138
            	clientSession.setAttribute(ClientView.CLIENT_VIEW_BEAN, clientViewBean);
139
            }
140
        }
141
        
142
        if (clientViewBean != null) {
143
            action = clientViewBean.getAction();
144
            contentType = request.getContentType();
145
            
146
            //*** BEGIN: manual bind params to bean (if we arrived here via the ClientViewHelper.jspx).
147
            if (action == null || action.equals("")) {
148
                if (contentType != null && contentType.indexOf("multipart/form-data") > -1) {
149
                    action = "Upload";
150
                } else {
151
                    action = request.getParameter("action");
152
                    clientViewBean.setDocId(request.getParameter("docid"));
153
                    clientViewBean.setMetaFileDocId(request.getParameter("metadataDocId"));
154
                    clientViewBean.setQformat(request.getParameter("qformat"));
155
                    clientViewBean.setPublicAccess(request.getParameter("publicAccess") != null);
156
                    clientViewBean.setContentStandard(request.getParameter("contentStandard"));
157
                }
158
                clientViewBean.setAction(action);
159
            }
160
            //*** END: manual bind params to bean.
161
            
162
            if (action != null) {
163
                if (action.equals("Login")) {
164
                    responseMap = handleClientRequest(null);
165
                    //*** Now that the action has been processed, clear it.
166
                    clientViewBean.setAction("");
167
                    if (isLoggedIn()) {
168
//                    	HttpSession session = request.getSession(false);                 	
169
//                    	session.setAttribute("ClientViewHelper", this);
170
                    	Cookie jSessionCookie = new Cookie("JSESSIONID", clientViewBean.getSessionid());
171
                    	response.addCookie(jSessionCookie);
172
                    }
173
                } else if (action.equals("Logout")) {
174
                    responseMap = handleClientRequest(null);
175
                    clientViewBean.setAction("");
176
                } else if (action.equals("Upload")) {
177
                    try {
178
                        //*** Init the MultipartParser.
179
                        multipartParser = new MultipartParser(request, sizeLimit * 1024 * 1024);
180
                        responseMap = handleClientRequest(multipartParser);
181
                    } catch (IOException ex) {
182
                        responseMap = new HashMap<String, Object>();
183
                        responseMap.put("message", ex.getMessage());
184
                    }
185
                    clientViewBean.setAction("");
186
                } else if (action.equals("Download")) {
187
                    responseMap = handleClientRequest(null);
188
                    try {
189
                        handleDownloadResponse(responseMap, response);
190
                    } catch (IOException ex) {
191
                        responseMap = new HashMap<String, Object>();
192
                        responseMap.put("message", ex.getMessage());
193
                    }
194
                    
195
                } else if (action.equals("Set Access")) {
196
                    responseMap = handleClientRequest(null);
197
                    clientViewBean.setAction("");
198
                } else {
199
                    responseMap = handleClientRequest(null);
200
                }
201
                result = (String) responseMap.get("message");
202
            }
203
        } else {
204
            result = "ClientViewHelper.clientRequest: ClientView bean is not instantiated.";
205
        }
206
        return(result);
207
    }
208
    
209
    /**
210
     * Main method for handling various actions.
211
     *
212
     * Note: This is mostly plain java code so it is JUnit friendly
213
     * (pass null as the MulipartParser).
214
     *
215
     * @param multipartParser Only needed if the action is "Upload".
216
     * @return HashMap containing "message", and possibly several other values.  If
217
     * the action is Download, than this will contain all needed values
218
     * to pass to handleDownloadResponse.
219
     */
220
    public HashMap<String, Object> handleClientRequest(MultipartParser multipartParser)  {
221
        String                              result = "", serverResponse;
222
        String                              posted_ldapUserName, tmp, action;
223
        HashMap<String, Object>             responseMap = new HashMap<String, Object>();
224
        
225
        
226
        if (clientViewBean != null) {
227
            action = clientViewBean.getAction();
228
            if (action != null) {
229
                try {
230
                    if (action.equals("Login")) {
231
                        tmp = LDAP_TEMPLATE.replaceFirst("%1s", clientViewBean.getUsername());
232
                        posted_ldapUserName = tmp.replaceFirst("%2s", clientViewBean.getOrganization());
233
                        
234
//                        if (metacatSessionId != null) {
235
//                        	metacatClient.setSessionId(metacatSessionId);
236
//                        }                       
237
                        serverResponse = metacatClient.login(posted_ldapUserName, clientViewBean.getPassword());
238
                        setLoggedIn(serverResponse);
239
                        result = parseXml("message", serverResponse);
240
                        contactName = parseXml("name", serverResponse);
241
                        clientViewBean.setMessage(ClientView.LOGIN_MESSAGE, result);
242
                        clientViewBean.setMessage(ClientView.UPLOAD_MESSAGE, "");
243
                        if (isLoggedIn()) {
244
                            clientViewBean.setSessionid(metacatClient.getSessionId());
245
                            
246
                        }
247
                    } else if (action.equals("Logout")) {
248
                        result = metacatClient.logout();
249
                        setLoggedIn(result);
250
                        result = parseXml("message", result);
251
                        clientViewBean.setMessage(ClientView.LOGIN_MESSAGE, result);
252
                        clientViewBean.setMessage(ClientView.UPLOAD_MESSAGE, "");
253
                        if (!isLoggedIn()) {
254
                            clientViewBean.setUsername("");
255
                            clientViewBean.setPassword("");
256
                            clientViewBean.setOrganization("");
257
                            clientViewBean.setSessionid(null);
258
                        }
259
                    } else if (action.equals("Delete")) {
260
                        ClientFgdcHelper.clientDeleteRequest(clientViewBean, this);
261
                        clientViewBean.setAction("read"); //*** Set for re-query.
262
                        //*** Note: the clientViewBean will already have the updated Meta Doc Id.
263
                        
264
                    } else if (action.equals("Upload")) {
265
                        //*** Only process request if logged in.
266
                        if (isLoggedIn()) {
267
                            if (multipartParser == null)
268
                                result = "ClientViewHelper.handleClientRequest: MultipartParser is not instantiated.";
269
                            else
270
                                result = handlePackageUpload(clientViewBean, multipartParser);
271
                        } else {
272
                            result = "You must be logged in to perform an upload.";
273
                        }
274
                        clientViewBean.setMessage(ClientView.UPLOAD_MESSAGE, result);
275
                    } else if (action.equals("Update")) {
276
                        result = "This is not implemented here.  Call ClientViewHelper.jspx";
277
                    } else if (action.equals("Scope")) {
278
                        result = handleDocIdSelect();
279
                        clientViewBean.setMessage(ClientView.SELECT_MESSAGE, result);
280
                    } else if (action.equals("Download")) {
281
                        responseMap = download(clientViewBean);
282
                    } else if (action.equals("Set Access")) {
283
                        result = handleChangeAccess(clientViewBean.getMetaFileDocId(),
284
                                (clientViewBean.isPublicAccess()? PERMISSION_TYPE_ALLOW: PERMISSION_TYPE_DISALLOW));
285
                        clientViewBean.setMessage(ClientView.UPDATE_MESSAGE, result);
286
                    } else {
287
                        result = action + " action not recognized.";
288
                    }
289
                } catch (Exception ex) {
290
                    result = ex.getMessage();
291
                    clientViewBean.setMessage(ClientView.ERROR_MESSAGE, result);
292
                    ex.printStackTrace();
293
                }
294
            }
295
        } else {
296
            result = "ClientViewHelper.clientRequest: ClientView bean is not instantiated.";
297
        }
298
        responseMap.put("message", result);
299
        return(responseMap);
300
    }
301
    
302
    /**
303
     * This is a convenience method to reduce the amount of code in a Metacat Client.
304
     * It handles creating/reusing (per session) an instance of a ClientViewHelper.
305
     * @param request Since this is intended to be used by an Http client, it is passed the
306
     * available "request" variable (the HttpServletRequest).
307
     * @throws edu.ucsb.nceas.metacat.client.MetacatInaccessibleException Received by MetacatFactory.
308
     * @return ClientViewHelper instance.
309
     */
310
    public static ClientViewHelper clientViewHelperInstance(HttpServletRequest request) {
311
        ClientViewHelper result;
312
        
313
        String sessionId = request.getSession(false).getId();
314
        
315
        result = (ClientViewHelper) request.getSession().getAttribute("ClientViewHelper");
316
        if (result == null) {
317
            try {
318
                result = new ClientViewHelper(request);
319
                request.getSession().setAttribute("ClientViewHelper", result);
320
            } catch (MetacatInaccessibleException ex) {
321
                ex.printStackTrace();
322
            }
323
        }
324
        
325
        if (result.clientViewBean == null) {
326
        	result.clientViewBean = (ClientView) request.getSession().getAttribute(ClientView.CLIENT_VIEW_BEAN);
327
            
328
            if (result.clientViewBean == null) {
329
            	//make a new one and shove it in the session
330
            	result.clientViewBean = new ClientView();
331
            	request.getSession().setAttribute(ClientView.CLIENT_VIEW_BEAN, result.clientViewBean);
332
            }
333
        }
334
        
335
        boolean oldLoginValue = result.loggedIn;
336
        result.setLoggedIn(SessionService.getInstance().validateSession(sessionId));
337
        if (result.isLoggedIn()) {
338
        	SessionData sessionData = SessionService.getInstance().getRegisteredSession(sessionId);
339
        	result.setUserName(sessionData.getName());
340
        }
341
        
342
        if (!oldLoginValue || result.loggedIn) {
343
        	result.clientViewBean.setMessage(ClientView.UPLOAD_MESSAGE, "");
344
        }
345
        
346
        return(result);
347
    }
348
    
349
    /**
350
     * A convenience method to be used by client code that requires
351
     * the user to be logged in.  NOTE: setUser() must have been called first,
352
     * otherwise it will always return false.
353
     * @return boolean  true if user has logged in for this session, false otherwise.
354
     */
355
    public boolean isLoggedIn() {
356
        return(loggedIn);
357
    }
358
    
359
    /**
360
     * After calling "login(ldapUserName, pwd)", call this with the username
361
     * and servers response message.  You can than use isLoggedIn() to determine if
362
     * the user is logged in, getLoginResponseElement(), etc.  The user name will also
363
     * used by calls to doMetadataUpload() for Document Id creation (scope).
364
     * @param userName User name
365
     * @param serverResponse XML login response sent from Metacat.
366
     */
367
    public void setLoggedIn(String serverResponse) {
368
        loggedIn = (serverResponse != null && serverResponse.indexOf("login") > -1);
369
    }
370
    
371
    public void setLoggedIn(boolean isLoggedIn) {
372
        this.loggedIn = isLoggedIn;
373
    }
374
    
375
    public void setUserName(String userName) {
376
        clientViewBean.setUsername(userName);
377
    }
378
    
379
    public String parseXml(String elementName, String xml) {
380
        String                      result = null;
381
        Document                    doc;
382
        
383
        try {
384
            doc = XMLUtilities.getXMLReaderAsDOMDocument(new StringReader(xml));
385
            result = (String) xpath.evaluate(elementName, doc.getDocumentElement(), XPathConstants.STRING);
386
            if (result != null)
387
                result = result.trim();
388
        } catch (IOException ex) {
389
            ex.printStackTrace();
390
        } catch (XPathExpressionException ex) {
391
            ex.printStackTrace();
392
        }
393
        return(result);
394
    }
395
    
396
    public String handleDocIdSelect() {
397
        String                              result = "";
398
        TreeMap                             allDocIds;
399
        
400
        if (!clientViewBean.getPathValue().equals("")) {
401
            allDocIds = getSelectQueryMap();
402
            result = ClientHtmlHelper.mapToHtmlSelect(allDocIds, "docId", "width: 240", 10);
403
        }
404
        return(result);
405
    }
406
    
407
    /**
408
     * Handles metadata file and data file uploads for inserting new
409
     * Metacat data packages.  Note: if content type is not "multipart/form-data",
410
     * nothing will happen.
411
     * @param request HTTP request.
412
     * @return A 1-line status message for the user.
413
     */
414
    public String handlePackageUpload(ClientView clientViewBean, MultipartParser multipartParser) throws Exception {
415
        String                      result = "", contentType, formatType;
416
        String                      lastDocId, nextDocId, metaDocId, metaFileName;
417
        String                      fileInfo[];
418
        Reader                      reader;
419
        int                         sizeLimit, idx;
420
        InputStream                 inputStream;
421
        HashMap                     paramsMap, dataDocIDs;
422
        StringBuffer                fileName;
423
        boolean                     sendIt;
424
        Iterator                    iterIt;
425
        Stack                       docIdStack;
426
        
427
        //*** Get the First file, which should be the metadata file.
428
        paramsMap = new HashMap();
429
        fileName = new StringBuffer();
430
        inputStream = getNextInputStream(multipartParser, fileName, paramsMap);
431
        metaFileName = fileName.toString();
432
        if (metaFileName.toLowerCase().endsWith(".xml")) {
433
            //*** Keep it here for updating.
434
            setMetadataDoc(inputStream);
435
            //*** Get the Metadata File's DOC ID.
436
            String scope = clientViewBean.getUsername();
437
            scope = scope.replaceAll(" ", "_");
438
            scope = scope.toLowerCase();
439
            lastDocId = getMetacatClient().getLastDocid(scope);
440
            metaDocId = lastDocId = nextDocId(lastDocId, scope);
441
            
442
            //*** Loop thru all of the data files, get fileName and inputStream.
443
            dataDocIDs = new HashMap();
444
            fileName = new StringBuffer();
445
            while ((inputStream = getNextInputStream(multipartParser, fileName, paramsMap)) != null) {
446
                //*** Get the data file's DOC ID.
447
                nextDocId = nextDocId(lastDocId, scope);
448
                
449
                fileInfo = parseFileInfo(fileName.toString());
450
                dataDocIDs.put(nextDocId, fileInfo);
451
                
452
                //*** Upload the data file to metacat.
453
                getMetacatClient().upload(nextDocId, fileName.toString(), inputStream, Integer.MAX_VALUE);
454
                
455
                lastDocId = nextDocId;
456
                fileName = new StringBuffer();
457
            }
458
            
459
            if (ClientFgdcHelper.isFGDC(getMetadataDoc())) {
460
                sendIt = ClientFgdcHelper.handlePackageUpload(metaDocId, dataDocIDs, contactName, metaFileName, getMetadataDoc());
461
            } else {
462
                //TODO add other types of metadata grammars here...
463
                System.out.println("ClientViewHelper.handlePackageUpload: not an FGDC file = " + fileName);
464
                result = fileName + " is not an FGDC file.  Files not uploaded.";
465
                sendIt = false;
466
            }
467
            
468
            if (sendIt) {
469
                //*** Upload the metadata file to metacat.
470
                reader = XMLUtilities.getDOMTreeAsReader(metadataDoc.getDocumentElement(), false);
471
                getMetacatClient().insert(metaDocId, reader, null);
472
                
473
                result = "MetaCat Package Inserted:  the Document Identifier is " + metaDocId;
474
                reader.close();
475
                //*** Grant the public read access to the meta file.
476
                if (paramsMap.containsKey("publicAccess")) {
477
                    docIdStack = new Stack();
478
                    docIdStack.addAll(dataDocIDs.keySet());
479
                    setPublicAccess(this.PERMISSION_TYPE_ALLOW, metaDocId, docIdStack);
480
                }
481
            }
482
        } else {
483
            result = "The first file must be an XML Metadata file.  Files not uploaded.";
484
        }
485
        if (inputStream != null)
486
            inputStream.close();
487
        return(result);
488
    }
489
    
490
    private String setPublicAccess(String permissionType, String metaDocId, Stack docIdStack)
491
    throws InsufficientKarmaException, MetacatException, MetacatInaccessibleException {
492
        String                      result = " for Documents ";
493
        String                      docId, lst = metaDocId, permOrder;
494
        
495
        if (permissionType.equals("allow"))
496
            permOrder = "denyFirst";
497
        else
498
            permOrder = "allowFirst";
499
        
500
        getMetacatClient().setAccess(metaDocId, "public", "read", permissionType, permOrder);
501
        //*** Grant the public read access to the data files.
502
        while(!docIdStack.isEmpty()) {
503
            docId = (String) docIdStack.pop();
504
            getMetacatClient().setAccess(docId, "public", "read", permissionType, permOrder);
505
            lst += ", " + docId;
506
        }
507
        result = "Changed public read access to '" + permissionType + "' for " + result + lst;
508
        return(result);
509
    }
510
    
511
    private String handleChangeAccess(String metaDocId, String permissionType) throws Exception {
512
        Stack                       dataDocIDs;
513
        String                      result = "", xpathExpr = null;
514
        
515
        setMetadataDoc(metaDocId);
516
        //*** Build list of sub-documents.
517
        if (clientViewBean.getContentStandard().equals(ClientView.FEDERAL_GEOGRAPHIC_DATA_COMMITTEE)) {
518
            xpathExpr = ClientFgdcHelper.SUB_DOCS_PATH;
519
        } else if (clientViewBean.getContentStandard().equals(ClientView.ECOLOGICAL_METADATA_LANGUAGE)) {
520
            xpathExpr = null; //TODO  - EML
521
        }
522
        if (xpathExpr != null) {
523
            dataDocIDs = getNodeTextStack(xpath, xpathExpr, getMetadataDoc().getDocumentElement());
524
            result = setPublicAccess(permissionType, metaDocId, dataDocIDs);
525
        }
526
        return(result);
527
    }
528
    
529
    public String handleFileUpdate(MultipartParser multipartParser) throws Exception {
530
        String                      result = "", fNm, action, lastDocId, newDocId, xPathQuery, qFrmt;
531
        InputStream                 inputStream;
532
        HashMap                     paramsMap;
533
        StringBuffer                fileName;
534
        Iterator                    iterIt;
535
        boolean                     sendIt;
536
        String                      metadataDocId, fileInfo[];
537
        
538
        paramsMap = new HashMap();
539
        fileName = new StringBuffer();
540
        if ((inputStream = getNextInputStream(multipartParser, fileName, paramsMap)) != null) {
541
            action = (String) paramsMap.get("action");
542
            //*** Get the Doc Id.
543
            lastDocId = (String) paramsMap.get("docid");
544
            
545
            //*** Get the metadata Doc Id.
546
            metadataDocId = (String) paramsMap.get("metadataDocId");
547
            clientViewBean.setMetaFileDocId(metadataDocId);
548
            
549
            //*** Get the qformat.
550
            qFrmt = (String) paramsMap.get("qformat");
551
            clientViewBean.setQformat(qFrmt);
552
            
553
            fNm = fileName.toString();
554
            
555
            try {
556
                if (lastDocId.equals(metadataDocId)) { //*** This is the metadata file.
557
                    //*** Keep it here for updating.
558
                    setMetadataDoc(inputStream);
559
                    if (ClientFgdcHelper.isFGDC(getMetadataDoc())) {
560
                        clientViewBean.setContentStandard(ClientView.FEDERAL_GEOGRAPHIC_DATA_COMMITTEE);
561
                        if (!ClientFgdcHelper.hasMetacatInfo(lastDocId, getMetadataDoc())) {
562
                            
563
                            //*** Save the Doc Id for re-query.
564
                            clientViewBean.setMetaFileDocId(lastDocId);
565
                            clientViewBean.setAction("read"); //*** Set for re-query.
566
                            result = "Update not performed: the Metadata file has no prior Metacat info in it.";
567
                        } else {
568
                            xPathQuery = ClientFgdcHelper.XPATH_QUERY_TEMPLATE.replaceFirst("%1s", lastDocId);
569
                            newDocId = updateMetadataDoc(lastDocId, xPathQuery, fNm);
570
                            
571
                            //*** Save the Doc Id for re-query.
572
                            clientViewBean.setMetaFileDocId(newDocId);
573
                            clientViewBean.setAction("read"); //*** Set for re-query.
574
                            result = "Updated to new document (from " + lastDocId + " to " + newDocId + ")";
575
                        }
576
                    } else {
577
                        //***TODO This is EML.
578
                        clientViewBean.setContentStandard(ClientView.ECOLOGICAL_METADATA_LANGUAGE);
579
                        
580
                        //*** Save the Doc Id for re-query.
581
                        clientViewBean.setMetaFileDocId(lastDocId);
582
                        clientViewBean.setAction("read"); //*** Set for re-query.
583
                        result = "Currently this functionality only supports FGDC metadata.";
584
                    }
585
                } else {
586
                    //*** This is a data file.
587
                    //*** Query for the metadata, we need to update it with the new data file doc id.
588
                    setMetadataDoc(metadataDocId);
589
                    
590
                    if (ClientFgdcHelper.isFGDC(getMetadataDoc())) {
591
                        clientViewBean.setContentStandard(ClientView.FEDERAL_GEOGRAPHIC_DATA_COMMITTEE);
592
                        fileInfo = parseFileInfo(fNm);
593
                        
594
                        xPathQuery = ClientFgdcHelper.FGDC_DATA_FILE_QUERY_XPATH.replaceFirst("%1s", lastDocId);
595
                        newDocId = nextVersion(lastDocId, xPathQuery);
596
                        ClientFgdcHelper.updateFileNameAndType(getMetadataDoc().getDocumentElement(), newDocId, fileInfo);
597
                        //*** Upload the data file to metacat.
598
                        getMetacatClient().upload(newDocId, fNm, inputStream, Integer.MAX_VALUE);
599
                        result = "Updated to new document (from " + lastDocId + " to " + newDocId + ")";
600
                        
601
                        //*** Upload the metadata file to metacat.
602
                        xPathQuery = ClientFgdcHelper.XPATH_QUERY_TEMPLATE.replaceFirst("%1s", metadataDocId);
603
                        newDocId = updateMetadataDoc(metadataDocId, xPathQuery, null);
604
                        
605
                        //*** Save the new meta Doc Id for re-query.
606
                        clientViewBean.setMetaFileDocId(newDocId);
607
                        clientViewBean.setAction("read"); //*** Set for re-query.
608
                        
609
                    } else {
610
                        //***TODO This is EML.
611
                        clientViewBean.setContentStandard(ClientView.ECOLOGICAL_METADATA_LANGUAGE);
612
                        
613
                        //*** Save the old meta Doc Id for re-query.
614
                        clientViewBean.setMetaFileDocId(metadataDocId);
615
                        clientViewBean.setAction("read"); //*** Set for re-query.
616
                        result = "Currently this functionality only supports FGDC metadata.";
617
                    }
618
                }
619
            } catch (java.io.IOException ex) {
620
                ex.printStackTrace();
621
            }
622
        } else {
623
            result = "Please enter the updated file path/name.";
624
        }
625
        clientViewBean.setMessage(ClientView.UPDATE_MESSAGE, result);
626
        return(result);
627
    }
628
    
629
    private String updateMetadataDoc(String lastDocId, String docIdPath, String origFileName) {
630
        String                      newDocId = null;
631
        Reader                      reader;
632
        
633
        //*** Update the metadata with the new Doc Id version.
634
        try {
635
            newDocId = nextVersion(lastDocId, docIdPath);
636
            if (origFileName != null) {
637
                if (clientViewBean.getContentStandard().equals(ClientView.FEDERAL_GEOGRAPHIC_DATA_COMMITTEE))
638
                    ClientFgdcHelper.updateMetadataFileName(getMetadataDoc().getDocumentElement(), newDocId, origFileName);
639
                else
640
                    ; //TODO EML, etc.
641
            }
642
            //*** Upload the metadata file to metacat.
643
            reader = XMLUtilities.getDOMTreeAsReader(getMetadataDoc().getDocumentElement(), false);
644
            getMetacatClient().update(newDocId, reader, null);
645
            reader.close();
646
        } catch (Exception ex) {
647
            ex.printStackTrace();
648
        }
649
        return(newDocId);
650
    }
651
    
652
    private InputStream getNextInputStream(MultipartParser multipartParser, StringBuffer fileName, HashMap paramsMap)
653
    throws IOException {
654
        InputStream                     result = null;
655
        Part                            part;
656
        String                          parmName = null, value = null, fnam;
657
        
658
        while ((part = multipartParser.readNextPart()) != null) {
659
            if (part.isParam()) {
660
                parmName = part.getName();
661
                value = ((ParamPart) part).getStringValue();
662
                paramsMap.put(parmName, value);
663
                
664
            } else if (part.isFile()) {
665
                fnam = ((FilePart) part).getFileName();
666
                if (fnam != null && !fnam.equals("")) {
667
                    //*** File name is passed back via StringBuffer fileName param.
668
                    fileName.append(fnam);
669
                    result = ((FilePart) part).getInputStream();
670
                    break;
671
                }
672
            }
673
        }
674
        return(result);
675
    }
676
    
677
    private void getRemainingParameters(MultipartParser multipartParser, HashMap paramsMap)
678
    throws IOException {
679
        InputStream                     result = null;
680
        Part                            part;
681
        String                          parmName = null, value = null, fnam;
682
        
683
        while ((part = multipartParser.readNextPart()) != null) {
684
            if (part.isParam()) {
685
                parmName = part.getName();
686
                value = ((ParamPart) part).getStringValue();
687
                paramsMap.put(parmName, value);
688
            }
689
        }
690
    }
691
    
692
    /**
693
     * Queries Metacat for document listings, and returns the results in a TreeMap,
694
     * where the key is the Doc Id, and the value is the Create Date.  If the document
695
     * contains the specified 'returnfield', an addtional entry will be created with
696
     * the value being a Vector of sub-DocId's.  The key of this entry will be the
697
     * original DocId with some addtional text added.
698
     * Reads bean properties 'pathExpr' (String[]), 'pathValue' (String)
699
     * and 'returnfield' (String).
700
     * @return TreeMap
701
     */
702
    public TreeMap getSelectQueryMap() {
703
        TreeMap                         result;
704
        Document                        doc;
705
        NodeList                        nodeLst, subNodeLst;
706
        Node                            node, subNode;
707
        String                          key, val, paramExpr, paramVal;
708
        String                          value, returnFld;
709
        String                          path;
710
        Vector                          optGroup;
711
        final String                    DOCID_EXPR = "./docid";
712
        final String                    DOCNAME_EXPR = "./createdate";
713
        final String                    PARAM_EXPR = "./param[@name='%1s']";
714
        
715
        path = clientViewBean.getPathExpr();
716
        returnFld = clientViewBean.getReturnfield();
717
        value = clientViewBean.getPathValue();
718
        
719
        result = new TreeMap();
720
        //paramExpr = String.format(PARAM_EXPR, returnFld);
721
        paramExpr = PARAM_EXPR.replaceFirst("%1s", returnFld);
722
        //*** Query the database ***
723
        doc = query(path, value, returnFld);
724
        //*** Build the TreeMap to return ***
725
        try {
726
            nodeLst = (NodeList) xpath.evaluate("/resultset/document", doc, XPathConstants.NODESET);
727
            for (int i = 0; i < nodeLst.getLength(); i++) {
728
                node = nodeLst.item(i);
729
                key = xpath.evaluate(DOCID_EXPR, node);
730
                val = xpath.evaluate(DOCNAME_EXPR, node);
731
                result.put(key, key + " (" + val + ")");
732
                
733
                //*** returnfield values ***
734
                subNodeLst = (NodeList) xpath.evaluate(paramExpr, node, XPathConstants.NODESET);
735
                if (subNodeLst.getLength() > 0) {
736
                    optGroup = new Vector();
737
                    for (int k = 0; k < subNodeLst.getLength(); k++) {
738
                        subNode =  subNodeLst.item(k);
739
                        paramVal = xpath.evaluate("text()", subNode);
740
                        optGroup.add(paramVal);
741
                    }
742
                    result.put(key + " Data Files", optGroup);
743
                }
744
                
745
            }
746
        } catch (XPathExpressionException ex) {
747
            ex.printStackTrace();
748
        }
749
        return(result);
750
    }
751
    
752
    /**
753
     * Query metacat for documents that 'CONTAINS' the value at the specified XPath
754
     * expression.  Additionally, returns another non-standard field value.
755
     * Standard info contains: DocId, DocName, DocType, CreateDate, and UpdateDate.
756
     * @param pathExpr String contianing an XPath expression.
757
     * @param pathValue String containing a comparison value at the XPath expression.
758
     * @param returnFld String containing an XPath expression to a field which will be returned
759
     * in addition to the standard info.
760
     * @return DOM Document containing the results.
761
     */
762
    public Document query(String pathExpr, String pathValue, String returnFld) {
763
        Document                        result = null;
764
        InputStream                     response;
765
        BufferedReader                  buffy;
766
        Properties                      prop;
767
        
768
        try {
769
            prop = new Properties();
770
            prop.put("action", "query");
771
            prop.put("qformat", "xml");
772
            prop.put(pathExpr, pathValue);
773
            if (returnFld != null) {
774
                prop.put("returnfield", returnFld);
775
            }
776
            
777
            response = metacatClient.sendParameters(prop);
778
            if (response != null) {
779
                buffy = new BufferedReader(new InputStreamReader(response));
780
                result = XMLUtilities.getXMLReaderAsDOMDocument(buffy);
781
            }
782
        } catch (IOException ex) {
783
            ex.printStackTrace();
784
        } catch (Exception ex) {
785
            ex.printStackTrace();
786
        }
787
        return(result);
788
    }
789
    
790
    public void setMetadataDoc(Document doc) {
791
        metadataDoc = doc;
792
    }
793
    
794
    public void setMetadataDoc(String docId) throws Exception {
795
        Document                        doc = null;
796
        BufferedReader                  buffy;
797
        InputStream                     response;
798

    
799
        response = metacatClient.read(docId);
800
        if (response != null) {
801
            buffy = new BufferedReader(new InputStreamReader(response));
802
            doc = XMLUtilities.getXMLReaderAsDOMDocument(buffy);
803
            response.close();
804
        }
805
        setMetadataDoc(doc);
806
    }
807
    
808
    public void setMetadataDoc(InputStream ioStream) throws IOException {
809
        BufferedReader                          buffy;
810
        
811
        if (ioStream != null) {
812
            buffy = new BufferedReader(new InputStreamReader(ioStream));
813
            metadataDoc = XMLUtilities.getXMLReaderAsDOMDocument(buffy);
814
        }
815
    }
816
    
817
    public Document getMetadataDoc() {
818
        return(metadataDoc);
819
    }
820
    
821
    public String nextVersion(String lastDocId, String xPathQuery) throws XPathExpressionException {
822
        String                      result = null, tokens[], scope, ready2Split, tmp;
823
        int                         vers, docNum;
824
        final int                   LAST_TOKEN = 2;
825
        final String                TEMPLATE = "%1s.%2d.%3d";
826
        Node                        node;
827
        
828
        //*** Parse the last Doc Id, and increment the version number.
829
        if(lastDocId != null && lastDocId.indexOf(".") > -1) {
830
            ready2Split = lastDocId.replace('.','~'); //*** This is necessary for the split to work.
831
            tokens = ready2Split.split("~");
832
            if(tokens.length > LAST_TOKEN && !tokens[LAST_TOKEN].equals("")) {
833
                scope = tokens[LAST_TOKEN - 2];
834
                docNum = Integer.parseInt(tokens[LAST_TOKEN - 1]);
835
                try {
836
                    vers = Integer.parseInt(tokens[LAST_TOKEN]);
837
                    //result = String.format(TEMPLATE, scope, docNum, 1 + vers);
838
                    tmp = TEMPLATE.replaceFirst("%1s", scope);
839
                    tmp = tmp.replaceFirst("%2d", String.valueOf(docNum));
840
                    result = tmp.replaceFirst("%3d", String.valueOf(vers + 1));
841
                    
842
                } catch (NumberFormatException ex) {
843
                    //*** In case the lastDocId has something other than a number.
844
                    //result = String.format(TEMPLATE, scope, docNum, 1);
845
                    tmp = TEMPLATE.replaceFirst("%1s", scope);
846
                    tmp = tmp.replaceFirst("%2d", String.valueOf(docNum));
847
                    result = tmp.replaceFirst("%3d", "1");
848
                }
849
            } else {
850
                //*** In case the lastDocId ends with a '.'
851
                result = lastDocId + "1";
852
            }
853
        } else {
854
            //*** In case of missing doc Id.
855
            result = null;
856
        }
857
        //*** Update the Doc Id in the metadata file.
858
        if (getMetadataDoc() != null) {
859
            node = (Node) xpath.evaluate(xPathQuery, getMetadataDoc().getDocumentElement(), XPathConstants.NODE);
860
            setTextContent(xpath, node, result);
861
        }
862
        return(result);
863
    }
864
    
865
    private String nextDocId(String lastDocId, String scope) {
866
        String                      result = null, tokens[], tmp;
867
        int                         vers;
868
        String                      template = scope.toLowerCase() + ".%1d.%2d";
869
        
870
        if(lastDocId != null && lastDocId.indexOf(".") > -1) {
871
            lastDocId = lastDocId.replace('.','~'); //*** This is necessary for the split to work.
872
            tokens = lastDocId.split("~");
873
            if(tokens.length > 1 && !tokens[1].equals("")) {
874
                try {
875
                    vers = Integer.parseInt(tokens[1]);
876
                    //result = String.format(template, 1 + vers, 1);
877
                    tmp = template.replaceFirst("%1d", String.valueOf(1 + vers));
878
                    result = tmp.replaceFirst("%2d", "1");
879
                } catch (NumberFormatException ex) {
880
                    //*** In case the lastDocId has something other than a number.
881
                    //result = String.format(template, 1, 1);
882
                    tmp = template.replaceFirst("%1d", "1");
883
                    result = tmp.replaceFirst("%2d", "1");
884
                }
885
            } else {
886
                //*** In case the lastDocId ends with a '.'
887
                //result = String.format(template, 1, 1);
888
                tmp = template.replaceFirst("%1d", "1");
889
                result = tmp.replaceFirst("%2d", "1");
890
            }
891
        } else {
892
            //*** In case there isn't any doc Id's with the user name.
893
            //result = String.format(template, 1, 1);
894
            tmp = template.replaceFirst("%1d", "1");
895
            result = tmp.replaceFirst("%2d", "1");
896
        }
897
        return(result);
898
    }
899
    
900
    public MetacatClient getMetacatClient() {
901
        return(metacatClient);
902
    }
903
    
904
    //*** BEGIN: Static utility methods ***
905
    
906
    public static String[] parseFileInfo(String fileName) {
907
        String[]                        result = new String[2];
908
        int                             idx;
909
        String                          formatType;
910
        
911
        //*** Set the file format (just using file extension for now).
912
        idx = fileName.lastIndexOf(".");
913
        if (idx > 1)
914
            formatType = fileName.substring(idx+1).toUpperCase();
915
        else
916
            formatType = "";
917
        
918
        result[ClientView.FORMAT_TYPE] = formatType;
919
        result[ClientView.FILE_NAME] = fileName.toString();
920
        return(result);
921
    }
922
    
923
    public static void updateNodeText(Node root, XPath xPath, String expression, String text) {
924
        Node                    targetNode;
925
        
926
        if (text != null && !text.equals("")) {
927
            try {
928
                targetNode = (Node) xPath.evaluate(expression, root, XPathConstants.NODE);
929
                setTextContent(xPath, targetNode, text);
930
                //targetNode.setTextContent(text);
931
            } catch (XPathExpressionException ex) {
932
                ex.printStackTrace();
933
            }
934
        }
935
    }
936
    
937
    
938
    public static Node getNode(XPath xPath, String expression, Node root) {
939
        Node                        result = null;
940
        
941
        try {
942
            result = (Node) xPath.evaluate(expression, root, XPathConstants.NODE);
943
        } catch (XPathExpressionException ex) {
944
            ex.printStackTrace();
945
        }
946
        return(result);
947
        
948
    }
949
    
950
    public static String getNodeText(XPath xPath, String expression, Node root) {
951
        Node                        node;
952
        String                      result = null;
953
        
954
        node = getNode(xPath, expression, root);
955
        if (node != null && !node.equals(""))
956
            result = getTextContent(xPath, node);
957
        //result = node.getTextContent(); Not in java 1.4
958
        return(result);
959
    }
960
    
961
    public static String[] getNodeTextList(XPath xPath, String expression, Node root) {
962
        NodeList                    nodes;
963
        String                      result[] = new String[0];
964
        int                         size;
965
        
966
        try {
967
            nodes = (NodeList) xPath.evaluate(expression, root, XPathConstants.NODESET);
968
            if (nodes != null && (size = nodes.getLength()) > 0) {
969
                result = new String[size];
970
                for(int i = 0; i < size; i++)
971
                    result[i] = getTextContent(xPath, nodes.item(i));
972
                //result[i] = nodes.item(i).getTextContent(); Not in java 1.4
973
            }
974
        } catch (XPathExpressionException ex) {
975
            ex.printStackTrace();
976
        }
977
        return(result);
978
    }
979
    
980
    public static Stack getNodeTextStack(XPath xpathInstance, String xpathExpr, Node parentNode) {
981
        String                      nodeLst[];
982
        Stack                       result = new Stack();
983
        
984
        nodeLst = getNodeTextList(xpathInstance, xpathExpr, parentNode);
985
        for(int i = 0; i < nodeLst.length; i++)
986
            result.push(nodeLst[i]);
987
        return(result);
988
    }
989
    
990
    public static String getStringFromInputStream(InputStream input) {
991
        StringBuffer result = new StringBuffer();
992
        BufferedReader in = new BufferedReader(new InputStreamReader(input));
993
        String line;
994
        try {
995
            while ((line = in.readLine()) != null) {
996
                result.append(line);
997
            }
998
        } catch (IOException e) {
999
            System.out.println("ClientViewHelper.getStringFromInputStream: " + e);
1000
        }
1001
        return result.toString();
1002
    }
1003
    
1004
    //*** END: Static utility methods ***
1005
    
1006
    public String makeRedirectUrl() {
1007
        String                      result, docId, message;
1008
        
1009
        docId = clientViewBean.getMetaFileDocId();
1010
        if (clientViewBean.getAction().equals(DOWNLOAD_ACTION)) {
1011
            result = null;
1012
        } else if (docId != null && !docId.equals("")) {
1013
            message = clientViewBean.getMessage(ClientView.UPDATE_MESSAGE);
1014
            result = "metacat?action=read&qformat=" +clientViewBean.getQformat()
1015
            + "&docid=" + docId + "&sessionid=" + clientViewBean.getSessionid() + "&message=" + message;
1016
        } else {
1017
            result = "style/skins/" + clientViewBean.getQformat() + "/confirm.jsp";
1018
        }
1019
        //*** Reset bean action property.
1020
        clientViewBean.setAction("");
1021
        return(result);
1022
    }
1023
    
1024
    private HashMap<String, Object> download(ClientView bean) {
1025
        Properties                      args;
1026
        InputStream                     inStream;
1027
        String                          docId, metaId, fNm = null, pth, txtLst[];
1028
        String                          msg = "File '~' (~) downloaded";
1029
        Node                            branchRoot, metaRoot;
1030
        ByteArrayOutputStream           outStream;
1031
        int                             intMe;
1032
        HashMap<String, Object>         responseMap = new HashMap<String, Object>();
1033
        
1034
        docId = bean.getDocId();
1035
        metaId = bean.getMetaFileDocId();
1036
        if (docId != null && metaId != null && !docId.equals("") && !metaId.equals("")) {
1037
            //*** Properties args: key=param_value, value=param_name.
1038
            args = new Properties();
1039
            args.put("read", "action");
1040
            try {
1041
                //*** First, retrieve the metadata and get the original filename.
1042
                //*** Also, if this is the metadata, get a list of docId's for the package.
1043
                setMetadataDoc(metaId);
1044
                metaRoot = getMetadataDoc().getDocumentElement();
1045
                if (ClientFgdcHelper.isFGDC(getMetadataDoc())) {
1046
                    //*** FGDC
1047
                    if (docId.equals(metaId)) { //*** This is the metadata file.
1048
                        pth = ClientFgdcHelper.FGDC_DOCID_ROOT_XPATH.replaceFirst("%1s", docId);
1049
                        branchRoot = getNode(xpath, pth, getMetadataDoc());
1050
                        fNm = getNodeText(xpath, ClientFgdcHelper.FGDC_FILE_NAME_XPATH, branchRoot);
1051
                        //include the filename for the docid
1052
                        args.put(fNm, docId);
1053
                        fNm = toZipFileName(fNm);
1054
                        responseMap.put("contentType", "application/zip");
1055
                        //*** Get the list of docId's for the entire package.
1056
                        args.put(metaId, "docid");
1057
                        txtLst = getNodeTextList(xpath, ClientFgdcHelper.FGDC_DATA_FILE_NODES_XPATH, branchRoot);
1058
                        for (int i = 0; i < txtLst.length; i++) {
1059
                        	String additionalDocId = txtLst[i];
1060
                        	if (additionalDocId != null && additionalDocId.length() > 1) {
1061
                        		//look up the filename from the metadata
1062
                        		String tempPath = ClientFgdcHelper.PATH4ANCESTOR.replaceFirst("%1s", additionalDocId);
1063
                        		tempPath = tempPath.replaceFirst("%2s", "digform");
1064
                                Node tempBranchRoot = getNode(xpath, tempPath, getMetadataDoc());
1065
                                String tempFileName = getNodeText(xpath, ClientFgdcHelper.FGDC_DATA_FILE_NAME_XPATH, tempBranchRoot);
1066
                                //include the docid
1067
                        		args.put(additionalDocId, "docid");
1068
                        		//include the filename for the docid
1069
                        		args.put(tempFileName, additionalDocId);
1070
                        	}
1071
                        }
1072
                        args.put("zip", "qformat");
1073
                    } else { //*** This is a data file.
1074
                        pth = ClientFgdcHelper.PATH4ANCESTOR.replaceFirst("%1s", docId);
1075
                        pth = pth.replaceFirst("%2s", "digform");
1076
                        branchRoot = getNode(xpath, pth, getMetadataDoc());
1077
                        fNm = getNodeText(xpath, ClientFgdcHelper.FGDC_DATA_FILE_NAME_XPATH, branchRoot);
1078
                        responseMap.put("contentType", "application/octet-stream");
1079
                        args.put(docId, "docid");
1080
                        args.put("xml", "qformat");
1081
                    }
1082
                } else {
1083
                    //*** TODO: EML -  this is just some basic code to start with.
1084
                    if (docId.equals(metaId)) {
1085
                        fNm = "emlMetadata.xml";
1086
                        txtLst = new String[] {docId};
1087
                        args.put(txtLst[0], "docid");
1088
                        args.put("zip", "qformat");
1089
                        responseMap.put("contentType", "application/zip");
1090
                    } else {
1091
                        fNm = "emlData.dat";
1092
                        args.put("xml", "qformat");
1093
                        args.put(docId, "docid");
1094
                        responseMap.put("contentType", "application/octet-stream");
1095
                    }
1096
                }
1097
                
1098
                //*** Set the filename in the response.
1099
                responseMap.put("Content-Disposition", "attachment; filename=" + fNm);
1100
                
1101
                //*** Next, read the file from metacat.
1102
                inStream = metacatClient.sendParameters(args);
1103
                
1104
                //*** Then, convert the input stream into an output stream.
1105
                outStream = new ByteArrayOutputStream();
1106
                while ((intMe = inStream.read()) != -1) {
1107
                    outStream.write(intMe);
1108
                }
1109
                
1110
                //*** Now, write the output stream to the response.
1111
                responseMap.put("outputStream", outStream);
1112
                
1113
                //*** Finally, set the message for the user interface to display.
1114
                msg = msg.replaceFirst("~", fNm);
1115
                msg = msg.replaceFirst("~", docId);
1116
                bean.setMessage(ClientView.SELECT_MESSAGE, msg);
1117
            } catch (Exception ex) {
1118
                ex.printStackTrace();
1119
                bean.setMessage(ClientView.SELECT_MESSAGE, ex.getMessage());
1120
            }
1121
        }
1122
        responseMap.put("message", bean.getMessage(ClientView.SELECT_MESSAGE));
1123
        return(responseMap);
1124
    }
1125
    
1126
    private void handleDownloadResponse(HashMap responseMap, HttpServletResponse response) throws IOException {
1127
        ByteArrayOutputStream                       outStream;
1128
        String                                      contentDisposition, contentType;
1129
        
1130
        contentType = (String) responseMap.get("contentType");
1131
        contentDisposition = (String) responseMap.get("Content-Disposition");
1132
        outStream = (ByteArrayOutputStream) responseMap.get("outputStream");
1133
        
1134
        response.setContentType(contentType);
1135
        response.setHeader("Content-Disposition", contentDisposition);
1136
        response.setContentLength(outStream.size());
1137
        outStream.writeTo(response.getOutputStream());
1138
        response.flushBuffer();
1139
    }
1140
    
1141
    public static String toZipFileName(String fileName) {
1142
        String                      result = "metacat";
1143
        int                         idx;
1144
        
1145
        if (fileName != null && !fileName.equals("") && !fileName.equals(".")) {
1146
            idx = fileName.indexOf('.');
1147
            if (idx > -1)
1148
                result = fileName.substring(0, idx);
1149
            else
1150
                result = fileName;
1151
        }
1152
        result += ".zip";
1153
        return(result);
1154
    }
1155
    
1156
    public static void setTextContent(XPath xPath, Node elementNode, String content) throws DOMException {
1157
        Text                        textNode, newTxtNode;
1158
        Document                    document;
1159
        
1160
        textNode = (Text) getNode(xPath, "text()", elementNode);
1161
        if (textNode != null) {
1162
            if (isElementContentWhitespace(textNode)) {
1163
                //*** If there is an existing text node, and it's whitespace,
1164
                //*** create a new text node and insert it before whitespace.
1165
                document = elementNode.getOwnerDocument();
1166
                newTxtNode = document.createTextNode(content);
1167
                elementNode.insertBefore(newTxtNode, textNode);
1168
            } else {
1169
                //*** If there is an existing text node, and it has content,
1170
                //*** overwrite the existing text.
1171
                textNode.setNodeValue(content);
1172
            }
1173
        } else {
1174
            //*** If there isn't an existing text node,
1175
            //*** create a new text node and append it to the elementNode.
1176
            document = elementNode.getOwnerDocument();
1177
            newTxtNode = document.createTextNode(content);
1178
            elementNode.appendChild(newTxtNode);
1179
        }
1180
    }
1181
    
1182
    public static String getTextContent(XPath xPath, Node elementNode) throws DOMException {
1183
        String                      result = "";
1184
        Text                        textNode;
1185
        
1186
        if (elementNode.getNodeType() != Node.TEXT_NODE)
1187
            textNode = (Text) getNode(xPath, "text()", elementNode);
1188
        else
1189
            textNode = (Text) elementNode;
1190
        if (textNode != null)
1191
            result = textNode.getNodeValue();
1192
        return(result);
1193
    }
1194
    
1195
    public static boolean isElementContentWhitespace(Text textNode) {
1196
        boolean                     result = false;
1197
        String                      val;
1198
        
1199
        if ((val = textNode.getNodeValue()) != null) {
1200
            if (val != null) {
1201
                val = val.trim();
1202
                result = (val.length() == 0);
1203
            }
1204
        }
1205
        return(result);
1206
    }
1207
    
1208
}
(5-5/5)