Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements a metadata catalog as a java Servlet
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Matt Jones, Dan Higgins, Jivka Bojilova, Chad Berkley
7
 *    Release: @release@
8
 *
9
 *   '$Author: jones $'
10
 *     '$Date: 2004-09-21 03:13:53 -0700 (Tue, 21 Sep 2004) $'
11
 * '$Revision: 2312 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27

    
28
package edu.ucsb.nceas.metacat;
29

    
30
import java.io.BufferedInputStream;
31
import java.io.File;
32
import java.io.FileInputStream;
33
import java.io.IOException;
34
import java.io.PrintWriter;
35
import java.io.StringReader;
36
import java.net.MalformedURLException;
37
import java.net.URL;
38
import java.sql.PreparedStatement;
39
import java.sql.ResultSet;
40
import java.sql.SQLException;
41
import java.sql.Timestamp;
42
import java.text.ParseException;
43
import java.text.SimpleDateFormat;
44
import java.util.Enumeration;
45
import java.util.Hashtable;
46
import java.util.Iterator;
47
import java.util.PropertyResourceBundle;
48
import java.util.Vector;
49
import java.util.regex.PatternSyntaxException;
50
import java.util.zip.ZipEntry;
51
import java.util.zip.ZipOutputStream;
52

    
53
import javax.servlet.ServletConfig;
54
import javax.servlet.ServletContext;
55
import javax.servlet.ServletException;
56
import javax.servlet.ServletOutputStream;
57
import javax.servlet.http.HttpServlet;
58
import javax.servlet.http.HttpServletRequest;
59
import javax.servlet.http.HttpServletResponse;
60
import javax.servlet.http.HttpSession;
61

    
62
import edu.ucsb.nceas.utilities.Options;
63

    
64
import org.ecoinformatics.eml.EMLParser;
65

    
66
import com.oreilly.servlet.multipart.FilePart;
67
import com.oreilly.servlet.multipart.MultipartParser;
68
import com.oreilly.servlet.multipart.ParamPart;
69
import com.oreilly.servlet.multipart.Part;
70

    
71
/**
72
 * A metadata catalog server implemented as a Java Servlet
73
 *
74
 * <p>
75
 * Valid parameters are: <br>
76
 * action=query -- query the values of all elements and attributes and return a
77
 * result set of nodes <br>
78
 * action=squery -- structured query (see pathquery.dtd) <br>
79
 * action= -- export a zip format for data packadge <br>
80
 * action=read -- read any metadata/data file from Metacat and from Internet
81
 * <br>
82
 * action=insert -- insert an XML document into the database store <br>
83
 * action=update -- update an XML document that is in the database store <br>
84
 * action=delete -- delete an XML document from the database store <br>
85
 * action=validate -- vallidate the xml contained in valtext <br>
86
 * doctype -- document type list returned by the query (publicID) <br>
87
 * qformat=xml -- display resultset from query in XML <br>
88
 * qformat=html -- display resultset from query in HTML <br>
89
 * qformat=zip -- zip resultset from query <br>
90
 * docid=34 -- display the document with the document ID number 34 <br>
91
 * doctext -- XML text of the document to load into the database <br>
92
 * acltext -- XML access text for a document to load into the database <br>
93
 * dtdtext -- XML DTD text for a new DTD to load into Metacat XML Catalog <br>
94
 * query -- actual query text (to go with 'action=query' or 'action=squery')
95
 * <br>
96
 * valtext -- XML text to be validated <br>
97
 * action=getaccesscontrol -- retrieve acl info for Metacat document <br>
98
 * action=getdoctypes -- retrieve all doctypes (publicID) <br>
99
 * action=getdtdschema -- retrieve a DTD or Schema file <br>
100
 * action=getdataguide -- retrieve a Data Guide <br>
101
 * action=getprincipals -- retrieve a list of principals in XML <br>
102
 * datadoc -- data document name (id) <br>
103
 * action=getlog -- get a report of events that have occurred in the system<br>
104
 * ipAddress --  filter on one or more IP addresses<br>
105
 * principal -- filter on one or more principals (LDAP DN syntax)<br>
106
 * docid -- filter on one or more document identifiers (with revision)<br>
107
 * event -- filter on event type (e.g., read, insert, update, delete)<br>
108
 * start -- filter out events before the start date-time<br>
109
 * end -- filter out events before the end date-time<br>
110
 * <p>
111
 * The particular combination of parameters that are valid for each particular
112
 * action value is quite specific. This documentation will be reorganized to
113
 * reflect this information.
114
 */
115
public class MetaCatServlet extends HttpServlet
116
{
117

    
118
    private ServletConfig config = null;
119

    
120
    private ServletContext context = null;
121

    
122
    private String resultStyleURL = null;
123

    
124
    private String xmlcatalogfile = null;
125

    
126
    private String saxparser = null;
127

    
128
    private String datafilepath = null;
129

    
130
    private File dataDirectory = null;
131

    
132
    private String servletpath = null;
133

    
134
    private String htmlpath = null;
135

    
136
    private String[] administrators = null;
137

    
138
    private PropertyResourceBundle options = null;
139

    
140
    private MetaCatUtil util = null;
141

    
142
    private DBConnectionPool connPool = null;
143

    
144
    private Hashtable sessionHash = new Hashtable();
145

    
146
    private static final String PROLOG = "<?xml version=\"1.0\"?>";
147

    
148
    private static final String SUCCESS = "<success>";
149

    
150
    private static final String SUCCESSCLOSE = "</success>";
151

    
152
    private static final String ERROR = "<error>";
153

    
154
    private static final String ERRORCLOSE = "</error>";
155

    
156
    public static final String SCHEMALOCATIONKEYWORD = ":schemaLocation";
157

    
158
    public static final String NONAMESPACELOCATION = ":noNamespaceSchemaLocation";
159

    
160
    public static final String EML2KEYWORD = ":eml";
161

    
162
    public static final String XMLFORMAT = "xml";
163

    
164
    private static final String CONFIG_DIR = "WEB-INF";
165

    
166
    private static final String CONFIG_NAME = "metacat.properties";
167

    
168
    /**
169
     * Initialize the servlet by creating appropriate database connections
170
     */
171
    public void init(ServletConfig config) throws ServletException
172
    {
173
        try {
174
            super.init(config);
175
            this.config = config;
176
            this.context = config.getServletContext();
177

    
178
            // Initialize the properties file for our options
179
            String dirPath = context.getRealPath(CONFIG_DIR);
180
            File propertyFile = new File(dirPath, CONFIG_NAME);
181
            Options options = null;
182
            try {
183
                options = Options.initialize(propertyFile);
184
                MetaCatUtil.debugMessage("Options configured: "
185
                        + options.getOption("configured"), 20);
186
            } catch (IOException ioe) {
187
                MetaCatUtil.debugMessage("Error in loading options: "
188
                        + ioe.getMessage(), 20);
189
            }
190

    
191
            util = new MetaCatUtil();
192

    
193
            //initial DBConnection pool
194
            connPool = DBConnectionPool.getInstance();
195

    
196
            // Get the configuration file information
197
            resultStyleURL = MetaCatUtil.getOption("resultStyleURL");
198
            xmlcatalogfile = MetaCatUtil.getOption("xmlcatalogfile");
199
            saxparser = MetaCatUtil.getOption("saxparser");
200
            datafilepath = MetaCatUtil.getOption("datafilepath");
201
            dataDirectory = new File(datafilepath);
202
            servletpath = MetaCatUtil.getOption("servletpath");
203
            htmlpath = MetaCatUtil.getOption("htmlpath");
204
            String adminList = MetaCatUtil.getOption("administrators");
205
            try {
206
                administrators = adminList.split(":");
207
            } catch (PatternSyntaxException pse) {
208
                administrators = null;
209
                MetaCatUtil.debugMessage("Error in MetacatServlet.init: "
210
                    + pse.getMessage(), 20);
211
            }
212

    
213
            System.out.println("Metacat (" + Version.getVersion()
214
                    + ") initialized.");
215
        } catch (ServletException ex) {
216
            throw ex;
217
        } catch (SQLException e) {
218
            MetaCatUtil.debugMessage("Error in MetacatServlet.init: "
219
                    + e.getMessage(), 20);
220
        }
221
    }
222

    
223
    /**
224
     * Close all db connections from the pool
225
     */
226
    public void destroy()
227
    {
228
        // Close all db connection
229
        System.out.println("Destroying MetacatServlet");
230
        DBConnectionPool.release();
231
    }
232

    
233
    /** Handle "GET" method requests from HTTP clients */
234
    public void doGet(HttpServletRequest request, HttpServletResponse response)
235
            throws ServletException, IOException
236
    {
237

    
238
        // Process the data and send back the response
239
        handleGetOrPost(request, response);
240
    }
241

    
242
    /** Handle "POST" method requests from HTTP clients */
243
    public void doPost(HttpServletRequest request, HttpServletResponse response)
244
            throws ServletException, IOException
245
    {
246

    
247
        // Process the data and send back the response
248
        handleGetOrPost(request, response);
249
    }
250

    
251
    /**
252
     * Control servlet response depending on the action parameter specified
253
     */
254
    private void handleGetOrPost(HttpServletRequest request,
255
            HttpServletResponse response) throws ServletException, IOException
256
    {
257

    
258
        if (util == null) {
259
            util = new MetaCatUtil();
260
        }
261
        /*
262
         * MetaCatUtil.debugMessage("Connection pool size: "
263
         * +connPool.getSizeOfDBConnectionPool(),10);
264
         * MetaCatUtil.debugMessage("Free DBConnection number: "
265
         */
266
        //If all DBConnection in the pool are free and DBConnection pool
267
        //size is greater than initial value, shrink the connection pool
268
        //size to initial value
269
        DBConnectionPool.shrinkDBConnectionPoolSize();
270

    
271
        //Debug message to print out the method which have a busy DBConnection
272
        connPool.printMethodNameHavingBusyDBConnection();
273

    
274
        String ctype = request.getContentType();
275
        if (ctype != null && ctype.startsWith("multipart/form-data")) {
276
            handleMultipartForm(request, response);
277
        } else {
278

    
279
            String name = null;
280
            String[] value = null;
281
            String[] docid = new String[3];
282
            Hashtable params = new Hashtable();
283
            Enumeration paramlist = request.getParameterNames();
284

    
285
            while (paramlist.hasMoreElements()) {
286

    
287
                name = (String) paramlist.nextElement();
288
                value = request.getParameterValues(name);
289

    
290
                // Decode the docid and mouse click information
291
                if (name.endsWith(".y")) {
292
                    docid[0] = name.substring(0, name.length() - 2);
293
                    params.put("docid", docid);
294
                    name = "ypos";
295
                }
296
                if (name.endsWith(".x")) {
297
                    name = "xpos";
298
                }
299

    
300
                params.put(name, value);
301
            }
302

    
303
            //handle param is emptpy
304
            if (params.isEmpty() || params == null) { return; }
305

    
306
            //if the user clicked on the input images, decode which image
307
            //was clicked then set the action.
308
            if(params.get("action") == null){
309
                PrintWriter out = response.getWriter();
310
                response.setContentType("text/xml");
311
                out.println("<?xml version=\"1.0\"?>");
312
                out.println("<error>");
313
                out.println("Action not specified");
314
                out.println("</error>");
315
                out.close();
316
                return;
317
            }
318

    
319
            String action = ((String[]) params.get("action"))[0];
320
            MetaCatUtil.debugMessage("Line 230: Action is: " + action, 1);
321

    
322
            // This block handles session management for the servlet
323
            // by looking up the current session information for all actions
324
            // other than "login" and "logout"
325
            String username = null;
326
            String password = null;
327
            String[] groupnames = null;
328
            String sess_id = null;
329

    
330
            // handle login action
331
            if (action.equals("login")) {
332
                PrintWriter out = response.getWriter();
333
                handleLoginAction(out, params, request, response);
334
                out.close();
335

    
336
                // handle logout action
337
            } else if (action.equals("logout")) {
338
                PrintWriter out = response.getWriter();
339
                handleLogoutAction(out, params, request, response);
340
                out.close();
341

    
342
                // handle shrink DBConnection request
343
            } else if (action.equals("shrink")) {
344
                PrintWriter out = response.getWriter();
345
                boolean success = false;
346
                //If all DBConnection in the pool are free and DBConnection
347
                // pool
348
                //size is greater than initial value, shrink the connection
349
                // pool
350
                //size to initial value
351
                success = DBConnectionPool.shrinkConnectionPoolSize();
352
                if (success) {
353
                    //if successfully shrink the pool size to initial value
354
                    out.println("DBConnection Pool shrunk successfully.");
355
                }//if
356
                else {
357
                    out.println("DBConnection pool not shrunk successfully.");
358
                }
359
                //close out put
360
                out.close();
361

    
362
                // aware of session expiration on every request
363
            } else {
364
                HttpSession sess = request.getSession(true);
365
                if (sess.isNew() && !params.containsKey("sessionid")) {
366
                    // session expired or has not been stored b/w user requests
367
                    MetaCatUtil.debugMessage(
368
                            "in session is new or no sessionid", 40);
369
                    username = "public";
370
                    sess.setAttribute("username", username);
371
                } else {
372
                    MetaCatUtil.debugMessage("in session is not new or "
373
                            + " has sessionid parameter", 40);
374
                    try {
375
                        if (params.containsKey("sessionid")) {
376
                            sess_id = ((String[]) params.get("sessionid"))[0];
377
                            MetaCatUtil.debugMessage("in has sessionid "
378
                                    + sess_id, 40);
379
                            if (sessionHash.containsKey(sess_id)) {
380
                                MetaCatUtil.debugMessage("find the id "
381
                                        + sess_id + " in hash table", 40);
382
                                sess = (HttpSession) sessionHash.get(sess_id);
383
                            }
384
                        } else {
385
                            // we already store the session in login, so we
386
                            // don't need here
387
                            /*
388
                             * MetaCatUtil.debugMessage("in no sessionid
389
                             * parameter ", 40); sess_id =
390
                             * (String)sess.getId();
391
                             * MetaCatUtil.debugMessage("storing the session id "
392
                             * + sess_id + " which has username " +
393
                             * sess.getAttribute("username") + " into session
394
                             * hash in handleGetOrPost method", 35);
395
                             */
396
                        }
397
                    } catch (IllegalStateException ise) {
398
                        System.out.println(
399
                                "error in handleGetOrPost: this shouldn't "
400
                                + "happen: the session should be valid: "
401
                                + ise.getMessage());
402
                    }
403

    
404
                    username = (String) sess.getAttribute("username");
405
                    MetaCatUtil.debugMessage("The user name from session is: "
406
                            + username, 20);
407
                    password = (String) sess.getAttribute("password");
408
                    groupnames = (String[]) sess.getAttribute("groupnames");
409
                }
410

    
411
                //make user user username should be public
412
                if (username == null || (username.trim().equals(""))) {
413
                    username = "public";
414
                }
415
                MetaCatUtil.debugMessage("The user is : " + username, 5);
416
            }
417
            // Now that we know the session is valid, we can delegate the
418
            // request
419
            // to a particular action handler
420
            if (action.equals("query")) {
421
                PrintWriter out = response.getWriter();
422
                handleQuery(out, params, response, username, groupnames,
423
                        sess_id);
424
                out.close();
425
            } else if (action.equals("squery")) {
426
                PrintWriter out = response.getWriter();
427
                if (params.containsKey("query")) {
428
                    handleSQuery(out, params, response, username, groupnames,
429
                            sess_id);
430
                    out.close();
431
                } else {
432
                    out.println(
433
                            "Illegal action squery without \"query\" parameter");
434
                    out.close();
435
                }
436
            } else if (action.equals("export")) {
437

    
438
                handleExportAction(params, response, username,
439
                        groupnames, password);
440
            } else if (action.equals("read")) {
441
                handleReadAction(params, request, response, username, password,
442
                        groupnames);
443
            } else if (action.equals("readinlinedata")) {
444
                handleReadInlineDataAction(params, request, response, username,
445
                        password, groupnames);
446
            } else if (action.equals("insert") || action.equals("update")) {
447
                PrintWriter out = response.getWriter();
448
                if ((username != null) && !username.equals("public")) {
449
                    handleInsertOrUpdateAction(request, response,
450
                            out, params, username, groupnames);
451
                } else {
452
                    response.setContentType("text/xml");
453
                    out.println("<?xml version=\"1.0\"?>");
454
                    out.println("<error>");
455
                    out.println("Permission denied for user " + username + " "
456
                            + action);
457
                    out.println("</error>");
458
                }
459
                out.close();
460
            } else if (action.equals("delete")) {
461
                PrintWriter out = response.getWriter();
462
                if ((username != null) && !username.equals("public")) {
463
                    handleDeleteAction(out, params, request, response, username,
464
                            groupnames);
465
                } else {
466
                    response.setContentType("text/xml");
467
                    out.println("<?xml version=\"1.0\"?>");
468
                    out.println("<error>");
469
                    out.println("Permission denied for " + action);
470
                    out.println("</error>");
471
                }
472
                out.close();
473
            } else if (action.equals("validate")) {
474
                PrintWriter out = response.getWriter();
475
                handleValidateAction(out, params);
476
                out.close();
477
            } else if (action.equals("setaccess")) {
478
                PrintWriter out = response.getWriter();
479
                handleSetAccessAction(out, params, username);
480
                out.close();
481
            } else if (action.equals("getaccesscontrol")) {
482
                PrintWriter out = response.getWriter();
483
                handleGetAccessControlAction(out, params, response, username,
484
                        groupnames);
485
                out.close();
486
            } else if (action.equals("getprincipals")) {
487
                PrintWriter out = response.getWriter();
488
                handleGetPrincipalsAction(out, username, password);
489
                out.close();
490
            } else if (action.equals("getdoctypes")) {
491
                PrintWriter out = response.getWriter();
492
                handleGetDoctypesAction(out, params, response);
493
                out.close();
494
            } else if (action.equals("getdtdschema")) {
495
                PrintWriter out = response.getWriter();
496
                handleGetDTDSchemaAction(out, params, response);
497
                out.close();
498
            } else if (action.equals("getlastdocid")) {
499
                PrintWriter out = response.getWriter();
500
                handleGetMaxDocidAction(out, params, response);
501
                out.close();
502
            } else if (action.equals("getrevisionanddoctype")) {
503
                PrintWriter out = response.getWriter();
504
                handleGetRevisionAndDocTypeAction(out, params);
505
                out.close();
506
            } else if (action.equals("getversion")) {
507
                response.setContentType("text/xml");
508
                PrintWriter out = response.getWriter();
509
                out.println(Version.getVersionAsXml());
510
                out.close();
511
            } else if (action.equals("getlog")) {
512
                handleGetLogAction(params, request, response, username);
513
            } else if (action.equals("buildindex")) {
514
                handleBuildIndexAction(params, request, response, username);
515
            } else if (action.equals("login") || action.equals("logout")) {
516
                /*
517
            } else if (action.equals("protocoltest")) {
518
                String testURL = "metacat://dev.nceas.ucsb.edu/NCEAS.897766.9";
519
                try {
520
                    testURL = ((String[]) params.get("url"))[0];
521
                } catch (Throwable t) {
522
                }
523
                String phandler = System
524
                        .getProperty("java.protocol.handler.pkgs");
525
                response.setContentType("text/html");
526
                PrintWriter out = response.getWriter();
527
                out.println("<body bgcolor=\"white\">");
528
                out.println("<p>Handler property: <code>" + phandler
529
                        + "</code></p>");
530
                out.println("<p>Starting test for:<br>");
531
                out.println("    " + testURL + "</p>");
532
                try {
533
                    URL u = new URL(testURL);
534
                    out.println("<pre>");
535
                    out.println("Protocol: " + u.getProtocol());
536
                    out.println("    Host: " + u.getHost());
537
                    out.println("    Port: " + u.getPort());
538
                    out.println("    Path: " + u.getPath());
539
                    out.println("     Ref: " + u.getRef());
540
                    String pquery = u.getQuery();
541
                    out.println("   Query: " + pquery);
542
                    out.println("  Params: ");
543
                    if (pquery != null) {
544
                        Hashtable qparams = MetaCatUtil.parseQuery(u.getQuery());
545
                        for (Enumeration en = qparams.keys(); en
546
                                .hasMoreElements();) {
547
                            String pname = (String) en.nextElement();
548
                            String pvalue = (String) qparams.get(pname);
549
                            out.println("    " + pname + ": " + pvalue);
550
                        }
551
                    }
552
                    out.println("</pre>");
553
                    out.println("</body>");
554
                    out.close();
555
                } catch (MalformedURLException mue) {
556
                    System.out.println(
557
                            "bad url from MetacatServlet.handleGetOrPost");
558
                    out.println(mue.getMessage());
559
                    mue.printStackTrace(out);
560
                    out.close();
561
                }
562
                */
563
            } else {
564
                PrintWriter out = response.getWriter();
565
                out.println("<?xml version=\"1.0\"?>");
566
                out.println("<error>");
567
                out.println(
568
                     "Error: action not registered.  Please report this error.");
569
                out.println("</error>");
570
                out.close();
571
            }
572

    
573
            //util.closeConnections();
574
            // Close the stream to the client
575
            //out.close();
576
        }
577
    }
578

    
579
    // LOGIN & LOGOUT SECTION
580
    /**
581
     * Handle the login request. Create a new session object. Do user
582
     * authentication through the session.
583
     */
584
    private void handleLoginAction(PrintWriter out, Hashtable params,
585
            HttpServletRequest request, HttpServletResponse response)
586
    {
587

    
588
        AuthSession sess = null;
589

    
590
        if(params.get("username") == null){
591
            response.setContentType("text/xml");
592
            out.println("<?xml version=\"1.0\"?>");
593
            out.println("<error>");
594
            out.println("Username not specified");
595
            out.println("</error>");
596
            return;
597
        }
598

    
599
        if(params.get("password") == null){
600
            response.setContentType("text/xml");
601
            out.println("<?xml version=\"1.0\"?>");
602
            out.println("<error>");
603
            out.println("Password not specified");
604
            out.println("</error>");
605
            return;
606
        }
607

    
608
        String un = ((String[]) params.get("username"))[0];
609
        MetaCatUtil.debugMessage("user " + un + " try to login", 20);
610
        String pw = ((String[]) params.get("password"))[0];
611

    
612
        String qformat = "xml";
613
        if(params.get("qformat") != null){
614
            qformat = ((String[]) params.get("qformat"))[0];
615
        }
616

    
617
        try {
618
            sess = new AuthSession();
619
        } catch (Exception e) {
620
            System.out.println("error in MetacatServlet.handleLoginAction: "
621
                    + e.getMessage());
622
            out.println(e.getMessage());
623
            return;
624
        }
625
        boolean isValid = sess.authenticate(request, un, pw);
626

    
627
        //if it is authernticate is true, store the session
628
        if (isValid) {
629
            HttpSession session = sess.getSessions();
630
            String id = session.getId();
631
            MetaCatUtil.debugMessage("Store session id " + id
632
                    + "which has username" + session.getAttribute("username")
633
                    + " into hash in login method", 35);
634
            sessionHash.put(id, session);
635
        }
636

    
637
        // format and transform the output
638
        if (qformat.equals("xml")) {
639
            response.setContentType("text/xml");
640
            out.println(sess.getMessage());
641
        } else {
642
            try {
643
                DBTransform trans = new DBTransform();
644
                response.setContentType("text/html");
645
                trans.transformXMLDocument(sess.getMessage(),
646
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
647
                        out, null);
648
            } catch (Exception e) {
649

    
650
                MetaCatUtil.debugMessage(
651
                        "Error in MetaCatServlet.handleLoginAction: "
652
                                + e.getMessage(), 30);
653
            }
654
        }
655
    }
656

    
657
    /**
658
     * Handle the logout request. Close the connection.
659
     */
660
    private void handleLogoutAction(PrintWriter out, Hashtable params,
661
            HttpServletRequest request, HttpServletResponse response)
662
    {
663

    
664
        String qformat = "xml";
665
        if(params.get("qformat") != null){
666
            qformat = ((String[]) params.get("qformat"))[0];
667
        }
668

    
669
        // close the connection
670
        HttpSession sess = request.getSession(false);
671
        MetaCatUtil.debugMessage("After get session in logout request", 40);
672
        if (sess != null) {
673
            MetaCatUtil.debugMessage("The session id " + sess.getId()
674
                    + " will be invalidate in logout action", 30);
675
            MetaCatUtil.debugMessage("The session contains user "
676
                    + sess.getAttribute("username")
677
                    + " will be invalidate in logout action", 30);
678
            sess.invalidate();
679
        }
680

    
681
        // produce output
682
        StringBuffer output = new StringBuffer();
683
        output.append("<?xml version=\"1.0\"?>");
684
        output.append("<logout>");
685
        output.append("User logged out");
686
        output.append("</logout>");
687

    
688
        //format and transform the output
689
        if (qformat.equals("xml")) {
690
            response.setContentType("text/xml");
691
            out.println(output.toString());
692
        } else {
693
            try {
694
                DBTransform trans = new DBTransform();
695
                response.setContentType("text/html");
696
                trans.transformXMLDocument(output.toString(),
697
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
698
                        out, null);
699
            } catch (Exception e) {
700
                MetaCatUtil.debugMessage(
701
                        "Error in MetaCatServlet.handleLogoutAction"
702
                                + e.getMessage(), 30);
703
            }
704
        }
705
    }
706

    
707
    // END OF LOGIN & LOGOUT SECTION
708

    
709
    // SQUERY & QUERY SECTION
710
    /**
711
     * Retreive the squery xml, execute it and display it
712
     *
713
     * @param out the output stream to the client
714
     * @param params the Hashtable of parameters that should be included in the
715
     *            squery.
716
     * @param response the response object linked to the client
717
     * @param conn the database connection
718
     */
719
    protected void handleSQuery(PrintWriter out, Hashtable params,
720
            HttpServletResponse response, String user, String[] groups,
721
            String sessionid)
722
    {
723
        double startTime = System.currentTimeMillis() / 1000;
724
        DBQuery queryobj = new DBQuery(saxparser);
725
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
726
        double outPutTime = System.currentTimeMillis() / 1000;
727
        MetaCatUtil.debugMessage("total search time: "
728
                + (outPutTime - startTime), 30);
729

    
730
    }
731

    
732
    /**
733
     * Create the xml query, execute it and display the results.
734
     *
735
     * @param out the output stream to the client
736
     * @param params the Hashtable of parameters that should be included in the
737
     *            squery.
738
     * @param response the response object linked to the client
739
     */
740
    protected void handleQuery(PrintWriter out, Hashtable params,
741
            HttpServletResponse response, String user, String[] groups,
742
            String sessionid)
743
    {
744
        //create the query and run it
745
        String xmlquery = DBQuery.createSQuery(params);
746
        String[] queryArray = new String[1];
747
        queryArray[0] = xmlquery;
748
        params.put("query", queryArray);
749
        double startTime = System.currentTimeMillis() / 1000;
750
        DBQuery queryobj = new DBQuery(saxparser);
751
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
752
        double outPutTime = System.currentTimeMillis() / 1000;
753
        MetaCatUtil.debugMessage("total search time: "
754
                + (outPutTime - startTime), 30);
755

    
756
        //handleSQuery(out, params, response,user, groups, sessionid);
757
    }
758

    
759
    // END OF SQUERY & QUERY SECTION
760

    
761
    //Exoport section
762
    /**
763
     * Handle the "export" request of data package from Metacat in zip format
764
     *
765
     * @param params the Hashtable of HTTP request parameters
766
     * @param response the HTTP response object linked to the client
767
     * @param user the username sent the request
768
     * @param groups the user's groupnames
769
     */
770
    private void handleExportAction(Hashtable params,
771
            HttpServletResponse response,
772
            String user, String[] groups, String passWord)
773
    {
774
        // Output stream
775
        ServletOutputStream out = null;
776
        // Zip output stream
777
        ZipOutputStream zOut = null;
778
        DocumentImpl docImpls = null;
779
        DBQuery queryObj = null;
780

    
781
        String[] docs = new String[10];
782
        String docId = "";
783

    
784
        try {
785
            // read the params
786
            if (params.containsKey("docid")) {
787
                docs = (String[]) params.get("docid");
788
            }
789
            // Create a DBuery to handle export
790
            queryObj = new DBQuery(saxparser);
791
            // Get the docid
792
            docId = docs[0];
793
            // Make sure the client specify docid
794
            if (docId == null || docId.equals("")) {
795
                response.setContentType("text/xml"); //MIME type
796
                // Get a printwriter
797
                PrintWriter pw = response.getWriter();
798
                // Send back message
799
                pw.println("<?xml version=\"1.0\"?>");
800
                pw.println("<error>");
801
                pw.println("You didn't specify requested docid");
802
                pw.println("</error>");
803
                // Close printwriter
804
                pw.close();
805
                return;
806
            }
807
            // Get output stream
808
            out = response.getOutputStream();
809
            response.setContentType("application/zip"); //MIME type
810
            zOut = new ZipOutputStream(out);
811
            zOut = queryObj
812
                    .getZippedPackage(docId, out, user, groups, passWord);
813
            zOut.finish(); //terminate the zip file
814
            zOut.close(); //close the zip stream
815

    
816
        } catch (Exception e) {
817
            try {
818
                response.setContentType("text/xml"); //MIME type
819
                // Send error message back
820
                if (out != null) {
821
                    PrintWriter pw = new PrintWriter(out);
822
                    pw.println("<?xml version=\"1.0\"?>");
823
                    pw.println("<error>");
824
                    pw.println(e.getMessage());
825
                    pw.println("</error>");
826
                    // Close printwriter
827
                    pw.close();
828
                    // Close output stream
829
                    out.close();
830
                }
831
                // Close zip output stream
832
                if (zOut != null) {
833
                    zOut.close();
834
                }
835
            } catch (IOException ioe) {
836
                MetaCatUtil.debugMessage("Problem with the servlet output "
837
                        + "in MetacatServlet.handleExportAction: "
838
                        + ioe.getMessage(), 30);
839
            }
840

    
841
            MetaCatUtil.debugMessage(
842
                    "Error in MetacatServlet.handleExportAction: "
843
                            + e.getMessage(), 30);
844
            e.printStackTrace(System.out);
845

    
846
        }
847

    
848
    }
849

    
850
    /**
851
     * In eml2 document, the xml can have inline data and data was stripped off
852
     * and store in file system. This action can be used to read inline data
853
     * only
854
     *
855
     * @param params the Hashtable of HTTP request parameters
856
     * @param response the HTTP response object linked to the client
857
     * @param user the username sent the request
858
     * @param groups the user's groupnames
859
     */
860
    private void handleReadInlineDataAction(Hashtable params,
861
            HttpServletRequest request, HttpServletResponse response,
862
            String user, String passWord, String[] groups)
863
    {
864
        String[] docs = new String[10];
865
        String inlineDataId = null;
866
        String docId = "";
867
        ServletOutputStream out = null;
868

    
869
        try {
870
            // read the params
871
            if (params.containsKey("inlinedataid")) {
872
                docs = (String[]) params.get("inlinedataid");
873
            }
874
            // Get the docid
875
            inlineDataId = docs[0];
876
            // Make sure the client specify docid
877
            if (inlineDataId == null || inlineDataId.equals("")) {
878
                throw new Exception("You didn't specify requested inlinedataid"); }
879

    
880
            // check for permission
881
            docId = MetaCatUtil
882
                    .getDocIdWithoutRevFromInlineDataID(inlineDataId);
883
            PermissionController controller = new PermissionController(docId);
884
            // check top level read permission
885
            if (!controller.hasPermission(user, groups,
886
                    AccessControlInterface.READSTRING))
887
            {
888
                throw new Exception("User " + user
889
                        + " doesn't have permission " + " to read document "
890
                        + docId);
891
            }
892
            else
893
            {
894
              //check data access level
895
              try
896
              {
897
                Hashtable unReadableInlineDataList =
898
                    PermissionController.getUnReadableInlineDataIdList(docId,
899
                    user, groups, false);
900
                if (unReadableInlineDataList.containsValue(
901
                          MetaCatUtil.getInlineDataIdWithoutRev(inlineDataId)))
902
                {
903
                  throw new Exception("User " + user
904
                       + " doesn't have permission " + " to read inlinedata "
905
                       + inlineDataId);
906

    
907
                }//if
908
              }//try
909
              catch (Exception e)
910
              {
911
                throw e;
912
              }//catch
913
            }//else
914

    
915
            // Get output stream
916
            out = response.getOutputStream();
917
            // read the inline data from the file
918
            String inlinePath = MetaCatUtil.getOption("inlinedatafilepath");
919
            File lineData = new File(inlinePath, inlineDataId);
920
            FileInputStream input = new FileInputStream(lineData);
921
            byte[] buffer = new byte[4 * 1024];
922
            int bytes = input.read(buffer);
923
            while (bytes != -1) {
924
                out.write(buffer, 0, bytes);
925
                bytes = input.read(buffer);
926
            }
927
            out.close();
928

    
929
            EventLog.getInstance().log(request.getRemoteAddr(), user,
930
                    inlineDataId, "readinlinedata");
931
        } catch (Exception e) {
932
            try {
933
                PrintWriter pw = null;
934
                // Send error message back
935
                if (out != null) {
936
                    pw = new PrintWriter(out);
937
                } else {
938
                    pw = response.getWriter();
939
                }
940
                pw.println("<?xml version=\"1.0\"?>");
941
                pw.println("<error>");
942
                pw.println(e.getMessage());
943
                pw.println("</error>");
944
                // Close printwriter
945
                pw.close();
946
                // Close output stream if out is not null
947
                if (out != null) {
948
                    out.close();
949
                }
950
            } catch (IOException ioe) {
951
                MetaCatUtil.debugMessage("Problem with the servlet output "
952
                        + "in MetacatServlet.handleExportAction: "
953
                        + ioe.getMessage(), 30);
954
            }
955
            MetaCatUtil.debugMessage(
956
                    "Error in MetacatServlet.handleReadInlineDataAction: "
957
                            + e.getMessage(), 30);
958
        }
959
    }
960

    
961
    /*
962
     * Get the nodeid from xml_nodes for the inlinedataid
963
     */
964
    private long getInlineDataNodeId(String inLineDataId, String docId)
965
            throws SQLException
966
    {
967
        long nodeId = 0;
968
        String INLINE = "inline";
969
        boolean hasRow;
970
        PreparedStatement pStmt = null;
971
        DBConnection conn = null;
972
        int serialNumber = -1;
973
        String sql = "SELECT nodeid FROM xml_nodes WHERE docid=? AND nodedata=? "
974
                + "AND nodetype='TEXT' AND parentnodeid IN "
975
                + "(SELECT nodeid FROM xml_nodes WHERE docid=? AND "
976
                + "nodetype='ELEMENT' AND nodename='" + INLINE + "')";
977

    
978
        try {
979
            //check out DBConnection
980
            conn = DBConnectionPool
981
                    .getDBConnection("AccessControlList.isAllowFirst");
982
            serialNumber = conn.getCheckOutSerialNumber();
983

    
984
            pStmt = conn.prepareStatement(sql);
985
            //bind value
986
            pStmt.setString(1, docId);//docid
987
            pStmt.setString(2, inLineDataId);//inlinedataid
988
            pStmt.setString(3, docId);
989
            // excute query
990
            pStmt.execute();
991
            ResultSet rs = pStmt.getResultSet();
992
            hasRow = rs.next();
993
            // get result
994
            if (hasRow) {
995
                nodeId = rs.getLong(1);
996
            }//if
997

    
998
        } catch (SQLException e) {
999
            throw e;
1000
        } finally {
1001
            try {
1002
                pStmt.close();
1003
            } finally {
1004
                DBConnectionPool.returnDBConnection(conn, serialNumber);
1005
            }
1006
        }
1007
        MetaCatUtil.debugMessage("The nodeid for inlinedataid " + inLineDataId
1008
                + " is: " + nodeId, 35);
1009
        return nodeId;
1010
    }
1011

    
1012
    /**
1013
     * Handle the "read" request of metadata/data files from Metacat or any
1014
     * files from Internet; transformed metadata XML document into HTML
1015
     * presentation if requested; zip files when more than one were requested.
1016
     *
1017
     * @param params the Hashtable of HTTP request parameters
1018
     * @param request the HTTP request object linked to the client
1019
     * @param response the HTTP response object linked to the client
1020
     * @param user the username sent the request
1021
     * @param groups the user's groupnames
1022
     */
1023
    private void handleReadAction(Hashtable params, HttpServletRequest request,
1024
            HttpServletResponse response, String user, String passWord,
1025
            String[] groups)
1026
    {
1027
        ServletOutputStream out = null;
1028
        ZipOutputStream zout = null;
1029
        PrintWriter pw = null;
1030
        boolean zip = false;
1031
        boolean withInlineData = true;
1032

    
1033
        try {
1034
            String[] docs = new String[0];
1035
            String docid = "";
1036
            String qformat = "";
1037
            String abstrpath = null;
1038

    
1039
            // read the params
1040
            if (params.containsKey("docid")) {
1041
                docs = (String[]) params.get("docid");
1042
            }
1043
            if (params.containsKey("qformat")) {
1044
                qformat = ((String[]) params.get("qformat"))[0];
1045
            }
1046
            // the param for only metadata (eml)
1047
            // we don't support read a eml document without inline data now.
1048
            /*if (params.containsKey("inlinedata")) {
1049

    
1050
                String inlineData = ((String[]) params.get("inlinedata"))[0];
1051
                if (inlineData.equalsIgnoreCase("false")) {
1052
                    withInlineData = false;
1053
                }
1054
            }*/
1055
            if ((docs.length > 1) || qformat.equals("zip")) {
1056
                zip = true;
1057
                out = response.getOutputStream();
1058
                response.setContentType("application/zip"); //MIME type
1059
                zout = new ZipOutputStream(out);
1060
            }
1061
            // go through the list of docs to read
1062
            for (int i = 0; i < docs.length; i++) {
1063
                try {
1064

    
1065
                    URL murl = new URL(docs[i]);
1066
                    Hashtable murlQueryStr = MetaCatUtil.parseQuery(
1067
                            murl.getQuery());
1068
                    // case docid="http://.../?docid=aaa"
1069
                    // or docid="metacat://.../?docid=bbb"
1070
                    if (murlQueryStr.containsKey("docid")) {
1071
                        // get only docid, eliminate the rest
1072
                        docid = (String) murlQueryStr.get("docid");
1073
                        if (zip) {
1074
                            addDocToZip(request, docid, zout, user, groups);
1075
                        } else {
1076
                            readFromMetacat(request, response, docid, qformat,
1077
                                    abstrpath, user, groups, zip, zout,
1078
                                    withInlineData, params);
1079
                        }
1080

    
1081
                        // case docid="http://.../filename"
1082
                    } else {
1083
                        docid = docs[i];
1084
                        if (zip) {
1085
                            addDocToZip(request, docid, zout, user, groups);
1086
                        } else {
1087
                            readFromURLConnection(response, docid);
1088
                        }
1089
                    }
1090

    
1091
                } catch (MalformedURLException mue) {
1092
                    docid = docs[i];
1093
                    if (zip) {
1094
                        addDocToZip(request, docid, zout, user, groups);
1095
                    } else {
1096
                        readFromMetacat(request, response, docid, qformat,
1097
                                abstrpath, user, groups, zip, zout,
1098
                                withInlineData, params);
1099
                    }
1100
                }
1101
            }
1102

    
1103
            if (zip) {
1104
                zout.finish(); //terminate the zip file
1105
                zout.close(); //close the zip stream
1106
            }
1107

    
1108
        } catch (McdbDocNotFoundException notFoundE) {
1109
            // To handle doc not found exception
1110
            // the docid which didn't be found
1111
            String notFoundDocId = notFoundE.getUnfoundDocId();
1112
            String notFoundRevision = notFoundE.getUnfoundRevision();
1113
            MetaCatUtil.debugMessage("Missed id: " + notFoundDocId, 30);
1114
            MetaCatUtil.debugMessage("Missed rev: " + notFoundRevision, 30);
1115
            try {
1116
                // read docid from remote server
1117
                readFromRemoteMetaCat(response, notFoundDocId,
1118
                        notFoundRevision, user, passWord, out, zip, zout);
1119
                // Close zout outputstream
1120
                if (zout != null) {
1121
                    zout.close();
1122
                }
1123
                // close output stream
1124
                if (out != null) {
1125
                    out.close();
1126
                }
1127

    
1128
            } catch (Exception exc) {
1129
                MetaCatUtil.debugMessage(
1130
                        "Erorr in MetacatServlet.hanldReadAction: "
1131
                                + exc.getMessage(), 30);
1132
                try {
1133
                    if (out != null) {
1134
                        response.setContentType("text/xml");
1135
                        // Send back error message by printWriter
1136
                        pw = new PrintWriter(out);
1137
                        pw.println("<?xml version=\"1.0\"?>");
1138
                        pw.println("<error>");
1139
                        pw.println(notFoundE.getMessage());
1140
                        pw.println("</error>");
1141
                        pw.close();
1142
                        out.close();
1143

    
1144
                    } else {
1145
                        response.setContentType("text/xml"); //MIME type
1146
                        // Send back error message if out = null
1147
                        if (pw == null) {
1148
                            // If pw is null, open the respnose
1149
                            pw = response.getWriter();
1150
                        }
1151
                        pw.println("<?xml version=\"1.0\"?>");
1152
                        pw.println("<error>");
1153
                        pw.println(notFoundE.getMessage());
1154
                        pw.println("</error>");
1155
                        pw.close();
1156
                    }
1157
                    // close zout
1158
                    if (zout != null) {
1159
                        zout.close();
1160
                    }
1161
                } catch (IOException ie) {
1162
                    MetaCatUtil.debugMessage("Problem with the servlet output "
1163
                            + "in MetacatServlet.handleReadAction: "
1164
                            + ie.getMessage(), 30);
1165
                }
1166
            }
1167
        } catch (Exception e) {
1168
            try {
1169

    
1170
                if (out != null) {
1171
                    response.setContentType("text/xml"); //MIME type
1172
                    pw = new PrintWriter(out);
1173
                    pw.println("<?xml version=\"1.0\"?>");
1174
                    pw.println("<error>");
1175
                    pw.println(e.getMessage());
1176
                    pw.println("</error>");
1177
                    pw.close();
1178
                    out.close();
1179
                } else {
1180
                    response.setContentType("text/xml"); //MIME type
1181
                    // Send back error message if out = null
1182
                    if (pw == null) {
1183
                        pw = response.getWriter();
1184
                    }
1185
                    pw.println("<?xml version=\"1.0\"?>");
1186
                    pw.println("<error>");
1187
                    pw.println(e.getMessage());
1188
                    pw.println("</error>");
1189
                    pw.close();
1190

    
1191
                }
1192
                // Close zip output stream
1193
                if (zout != null) {
1194
                    zout.close();
1195
                }
1196

    
1197
            } catch (IOException ioe) {
1198
                MetaCatUtil.debugMessage("Problem with the servlet output "
1199
                        + "in MetacatServlet.handleReadAction: "
1200
                        + ioe.getMessage(), 30);
1201
                ioe.printStackTrace(System.out);
1202

    
1203
            }
1204

    
1205
            MetaCatUtil.debugMessage(
1206
                    "Error in MetacatServlet.handleReadAction: "
1207
                            + e.getMessage(), 30);
1208
            //e.printStackTrace(System.out);
1209
        }
1210
    }
1211

    
1212
    /** read metadata or data from Metacat
1213
     */
1214
    private void readFromMetacat(HttpServletRequest request,
1215
            HttpServletResponse response, String docid, String qformat,
1216
            String abstrpath, String user, String[] groups, boolean zip,
1217
            ZipOutputStream zout, boolean withInlineData, Hashtable params)
1218
            throws ClassNotFoundException, IOException, SQLException,
1219
            McdbException, Exception
1220
    {
1221

    
1222
        try {
1223

    
1224
            DocumentImpl doc = new DocumentImpl(docid);
1225

    
1226
            //check the permission for read
1227
            if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1228
                Exception e = new Exception("User " + user
1229
                        + " does not have permission"
1230
                        + " to read the document with the docid " + docid);
1231

    
1232
                throw e;
1233
            }
1234

    
1235
            if (doc.getRootNodeID() == 0) {
1236
                // this is data file
1237
                String filepath = MetaCatUtil.getOption("datafilepath");
1238
                if (!filepath.endsWith("/")) {
1239
                    filepath += "/";
1240
                }
1241
                String filename = filepath + docid;
1242
                FileInputStream fin = null;
1243
                fin = new FileInputStream(filename);
1244

    
1245
                //MIME type
1246
                String contentType = getServletContext().getMimeType(filename);
1247
                if (contentType == null) {
1248
                    ContentTypeProvider provider = new ContentTypeProvider(
1249
                            docid);
1250
                    contentType = provider.getContentType();
1251
                    MetaCatUtil.debugMessage("Final contenttype is: "
1252
                            + contentType, 30);
1253
                }
1254

    
1255
                response.setContentType(contentType);
1256
                // if we decide to use "application/octet-stream" for all data
1257
                // returns
1258
                // response.setContentType("application/octet-stream");
1259

    
1260
                try {
1261

    
1262
                    ServletOutputStream out = response.getOutputStream();
1263
                    byte[] buf = new byte[4 * 1024]; // 4K buffer
1264
                    int b = fin.read(buf);
1265
                    while (b != -1) {
1266
                        out.write(buf, 0, b);
1267
                        b = fin.read(buf);
1268
                    }
1269
                } finally {
1270
                    if (fin != null) fin.close();
1271
                }
1272

    
1273
            } else {
1274
                // this is metadata doc
1275
                if (qformat.equals("xml") || qformat.equals("")) {
1276
                    // if equals "", that means no qformat is specified. hence
1277
                    // by default the document should be returned in xml format
1278
                    // set content type first
1279
                    response.setContentType("text/xml"); //MIME type
1280
                    PrintWriter out = response.getWriter();
1281
                    doc.toXml(out, user, groups, withInlineData);
1282
                } else {
1283
                    response.setContentType("text/html"); //MIME type
1284
                    PrintWriter out = response.getWriter();
1285

    
1286
                    // Look up the document type
1287
                    String doctype = doc.getDoctype();
1288
                    // Transform the document to the new doctype
1289
                    DBTransform dbt = new DBTransform();
1290
                    dbt.transformXMLDocument(doc.toString(user, groups,
1291
                            withInlineData), doctype, "-//W3C//HTML//EN",
1292
                            qformat, out, params);
1293
                }
1294

    
1295
            }
1296
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1297
                    docid, "read");
1298
        } catch (Exception except) {
1299
            throw except;
1300
        }
1301
    }
1302

    
1303
    /**
1304
     * read data from URLConnection
1305
     */
1306
    private void readFromURLConnection(HttpServletResponse response,
1307
            String docid) throws IOException, MalformedURLException
1308
    {
1309
        ServletOutputStream out = response.getOutputStream();
1310
        String contentType = getServletContext().getMimeType(docid); //MIME
1311
                                                                     // type
1312
        if (contentType == null) {
1313
            if (docid.endsWith(".xml")) {
1314
                contentType = "text/xml";
1315
            } else if (docid.endsWith(".css")) {
1316
                contentType = "text/css";
1317
            } else if (docid.endsWith(".dtd")) {
1318
                contentType = "text/plain";
1319
            } else if (docid.endsWith(".xsd")) {
1320
                contentType = "text/xml";
1321
            } else if (docid.endsWith("/")) {
1322
                contentType = "text/html";
1323
            } else {
1324
                File f = new File(docid);
1325
                if (f.isDirectory()) {
1326
                    contentType = "text/html";
1327
                } else {
1328
                    contentType = "application/octet-stream";
1329
                }
1330
            }
1331
        }
1332
        response.setContentType(contentType);
1333
        // if we decide to use "application/octet-stream" for all data returns
1334
        // response.setContentType("application/octet-stream");
1335

    
1336
        // this is http url
1337
        URL url = new URL(docid);
1338
        BufferedInputStream bis = null;
1339
        try {
1340
            bis = new BufferedInputStream(url.openStream());
1341
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1342
            int b = bis.read(buf);
1343
            while (b != -1) {
1344
                out.write(buf, 0, b);
1345
                b = bis.read(buf);
1346
            }
1347
        } finally {
1348
            if (bis != null) bis.close();
1349
        }
1350

    
1351
    }
1352

    
1353
    /**
1354
     * read file/doc and write to ZipOutputStream
1355
     *
1356
     * @param docid
1357
     * @param zout
1358
     * @param user
1359
     * @param groups
1360
     * @throws ClassNotFoundException
1361
     * @throws IOException
1362
     * @throws SQLException
1363
     * @throws McdbException
1364
     * @throws Exception
1365
     */
1366
    private void addDocToZip(HttpServletRequest request, String docid,
1367
            ZipOutputStream zout, String user, String[] groups) throws
1368
            ClassNotFoundException, IOException, SQLException, McdbException,
1369
            Exception
1370
    {
1371
        byte[] bytestring = null;
1372
        ZipEntry zentry = null;
1373

    
1374
        try {
1375
            URL url = new URL(docid);
1376

    
1377
            // this http url; read from URLConnection; add to zip
1378
            zentry = new ZipEntry(docid);
1379
            zout.putNextEntry(zentry);
1380
            BufferedInputStream bis = null;
1381
            try {
1382
                bis = new BufferedInputStream(url.openStream());
1383
                byte[] buf = new byte[4 * 1024]; // 4K buffer
1384
                int b = bis.read(buf);
1385
                while (b != -1) {
1386
                    zout.write(buf, 0, b);
1387
                    b = bis.read(buf);
1388
                }
1389
            } finally {
1390
                if (bis != null) bis.close();
1391
            }
1392
            zout.closeEntry();
1393

    
1394
        } catch (MalformedURLException mue) {
1395

    
1396
            // this is metacat doc (data file or metadata doc)
1397
            try {
1398
                DocumentImpl doc = new DocumentImpl(docid);
1399

    
1400
                //check the permission for read
1401
                if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1402
                    Exception e = new Exception("User " + user
1403
                            + " does not have "
1404
                            + "permission to read the document with the docid "
1405
                            + docid);
1406
                    throw e;
1407
                }
1408

    
1409
                if (doc.getRootNodeID() == 0) {
1410
                    // this is data file; add file to zip
1411
                    String filepath = MetaCatUtil.getOption("datafilepath");
1412
                    if (!filepath.endsWith("/")) {
1413
                        filepath += "/";
1414
                    }
1415
                    String filename = filepath + docid;
1416
                    FileInputStream fin = null;
1417
                    fin = new FileInputStream(filename);
1418
                    try {
1419

    
1420
                        zentry = new ZipEntry(docid);
1421
                        zout.putNextEntry(zentry);
1422
                        byte[] buf = new byte[4 * 1024]; // 4K buffer
1423
                        int b = fin.read(buf);
1424
                        while (b != -1) {
1425
                            zout.write(buf, 0, b);
1426
                            b = fin.read(buf);
1427
                        }
1428
                    } finally {
1429
                        if (fin != null) fin.close();
1430
                    }
1431
                    zout.closeEntry();
1432

    
1433
                } else {
1434
                    // this is metadata doc; add doc to zip
1435
                    bytestring = doc.toString().getBytes();
1436
                    zentry = new ZipEntry(docid + ".xml");
1437
                    zentry.setSize(bytestring.length);
1438
                    zout.putNextEntry(zentry);
1439
                    zout.write(bytestring, 0, bytestring.length);
1440
                    zout.closeEntry();
1441
                }
1442
                EventLog.getInstance().log(request.getRemoteAddr(), user,
1443
                        docid, "read");
1444
            } catch (Exception except) {
1445
                throw except;
1446
            }
1447
        }
1448
    }
1449

    
1450
    /**
1451
     * If metacat couldn't find a data file or document locally, it will read
1452
     * this docid from its home server. This is for the replication feature
1453
     */
1454
    private void readFromRemoteMetaCat(HttpServletResponse response,
1455
            String docid, String rev, String user, String password,
1456
            ServletOutputStream out, boolean zip, ZipOutputStream zout)
1457
            throws Exception
1458
    {
1459
        // Create a object of RemoteDocument, "" is for zipEntryPath
1460
        RemoteDocument remoteDoc = new RemoteDocument(docid, rev, user,
1461
                password, "");
1462
        String docType = remoteDoc.getDocType();
1463
        // Only read data file
1464
        if (docType.equals("BIN")) {
1465
            // If it is zip format
1466
            if (zip) {
1467
                remoteDoc.readDocumentFromRemoteServerByZip(zout);
1468
            } else {
1469
                if (out == null) {
1470
                    out = response.getOutputStream();
1471
                }
1472
                response.setContentType("application/octet-stream");
1473
                remoteDoc.readDocumentFromRemoteServer(out);
1474
            }
1475
        } else {
1476
            throw new Exception("Docid: " + docid + "." + rev
1477
                    + " couldn't find");
1478
        }
1479
    }
1480

    
1481
    /**
1482
     * Handle the database putdocument request and write an XML document to the
1483
     * database connection
1484
     */
1485
    private void handleInsertOrUpdateAction(HttpServletRequest request,
1486
            HttpServletResponse response, PrintWriter out, Hashtable params,
1487
            String user, String[] groups)
1488
    {
1489
        DBConnection dbConn = null;
1490
        int serialNumber = -1;
1491

    
1492
        if(params.get("docid") == null){
1493
            out.println("<?xml version=\"1.0\"?>");
1494
            out.println("<error>");
1495
            out.println("Docid not specified");
1496
            out.println("</error>");
1497
            return;
1498
        }
1499

    
1500
        try {
1501
            // Get the document indicated
1502
            String[] doctext = (String[]) params.get("doctext");
1503

    
1504
            String pub = null;
1505
            if (params.containsKey("public")) {
1506
                pub = ((String[]) params.get("public"))[0];
1507
            }
1508

    
1509
            StringReader dtd = null;
1510
            if (params.containsKey("dtdtext")) {
1511
                String[] dtdtext = (String[]) params.get("dtdtext");
1512
                try {
1513
                    if (!dtdtext[0].equals("")) {
1514
                        dtd = new StringReader(dtdtext[0]);
1515
                    }
1516
                } catch (NullPointerException npe) {
1517
                }
1518
            }
1519
            StringReader xml = new StringReader(doctext[0]);
1520
            boolean validate = false;
1521
            DocumentImplWrapper documentWrapper = null;
1522
            try {
1523
                // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ...
1524
                // >
1525
                // in order to decide whether to use validation parser
1526
                validate = needDTDValidation(xml);
1527
                if (validate) {
1528
                    // set a dtd base validation parser
1529
                    String rule = DocumentImpl.DTD;
1530
                    documentWrapper = new DocumentImplWrapper(rule, validate);
1531
                } else if (needSchemaValidation(xml)) {
1532
                    // for eml2
1533
                    String namespace = findNamespace(xml);
1534
                    if (namespace.compareTo(DocumentImpl.EML2_0_0NAMESPACE) == 0
1535
                                || namespace.compareTo(
1536
                                DocumentImpl.EML2_0_1NAMESPACE) == 0) {
1537
                        // set eml2 base validation parser
1538
                        String rule = DocumentImpl.EML200;
1539
                        // using emlparser to check id validation
1540
                        EMLParser parser = new EMLParser(doctext[0]);
1541
                        documentWrapper = new DocumentImplWrapper(rule, true);
1542
                    } else if (namespace.compareTo(
1543
                                DocumentImpl.EML2_1_0NAMESPACE) == 0) {
1544
                        // set eml2 base validation parser
1545
                        String rule = DocumentImpl.EML210;
1546
                        // using emlparser to check id validation
1547
                        EMLParser parser = new EMLParser(doctext[0]);
1548
                        documentWrapper = new DocumentImplWrapper(rule, true);
1549
                    } else {
1550
                        // set schema base validation parser
1551
                        String rule = DocumentImpl.SCHEMA;
1552
                        documentWrapper = new DocumentImplWrapper(rule, true);
1553
                    }
1554
                } else {
1555
                    documentWrapper = new DocumentImplWrapper("", false);
1556
                }
1557

    
1558
                String[] action = (String[]) params.get("action");
1559
                String[] docid = (String[]) params.get("docid");
1560
                String newdocid = null;
1561

    
1562
                String doAction = null;
1563
                if (action[0].equals("insert")) {
1564
                    doAction = "INSERT";
1565
                } else if (action[0].equals("update")) {
1566
                    doAction = "UPDATE";
1567
                }
1568

    
1569
                try {
1570
                    // get a connection from the pool
1571
                    dbConn = DBConnectionPool
1572
                            .getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1573
                    serialNumber = dbConn.getCheckOutSerialNumber();
1574

    
1575
                    // write the document to the database
1576
                    try {
1577
                        String accNumber = docid[0];
1578
                        MetaCatUtil.debugMessage("" + doAction + " "
1579
                                + accNumber + "...", 10);
1580
                        if (accNumber.equals("")) {
1581
                            accNumber = null;
1582
                        }
1583
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1584
                                doAction, accNumber, user, groups);
1585
                        EventLog.getInstance().log(request.getRemoteAddr(),
1586
                                user, accNumber, action[0]);
1587
                    } catch (NullPointerException npe) {
1588
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1589
                                doAction, null, user, groups);
1590
                        EventLog.getInstance().log(request.getRemoteAddr(),
1591
                                user, "", action[0]);
1592
                    }
1593
                }
1594
                finally {
1595
                    // Return db connection
1596
                    DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1597
                }
1598

    
1599
                // set content type and other response header fields first
1600
                //response.setContentType("text/xml");
1601
                out.println("<?xml version=\"1.0\"?>");
1602
                out.println("<success>");
1603
                out.println("<docid>" + newdocid + "</docid>");
1604
                out.println("</success>");
1605

    
1606
            } catch (NullPointerException npe) {
1607
                //response.setContentType("text/xml");
1608
                out.println("<?xml version=\"1.0\"?>");
1609
                out.println("<error>");
1610
                out.println(npe.getMessage());
1611
                out.println("</error>");
1612
            }
1613
        } catch (Exception e) {
1614
            //response.setContentType("text/xml");
1615
            out.println("<?xml version=\"1.0\"?>");
1616
            out.println("<error>");
1617
            out.println(e.getMessage());
1618
            out.println("</error>");
1619
        }
1620
    }
1621

    
1622
    /**
1623
     * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... > in
1624
     * order to decide whether to use validation parser
1625
     */
1626
    private static boolean needDTDValidation(StringReader xmlreader)
1627
            throws IOException
1628
    {
1629

    
1630
        StringBuffer cbuff = new StringBuffer();
1631
        java.util.Stack st = new java.util.Stack();
1632
        boolean validate = false;
1633
        int c;
1634
        int inx;
1635

    
1636
        // read from the stream until find the keywords
1637
        while ((st.empty() || st.size() < 4) && ((c = xmlreader.read()) != -1)) {
1638
            cbuff.append((char) c);
1639

    
1640
            // "<!DOCTYPE" keyword is found; put it in the stack
1641
            if ((inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1) {
1642
                cbuff = new StringBuffer();
1643
                st.push("<!DOCTYPE");
1644
            }
1645
            // "PUBLIC" keyword is found; put it in the stack
1646
            if ((inx = cbuff.toString().indexOf("PUBLIC")) != -1) {
1647
                cbuff = new StringBuffer();
1648
                st.push("PUBLIC");
1649
            }
1650
            // "SYSTEM" keyword is found; put it in the stack
1651
            if ((inx = cbuff.toString().indexOf("SYSTEM")) != -1) {
1652
                cbuff = new StringBuffer();
1653
                st.push("SYSTEM");
1654
            }
1655
            // ">" character is found; put it in the stack
1656
            // ">" is found twice: fisrt from <?xml ...?>
1657
            // and second from <!DOCTYPE ... >
1658
            if ((inx = cbuff.toString().indexOf(">")) != -1) {
1659
                cbuff = new StringBuffer();
1660
                st.push(">");
1661
            }
1662
        }
1663

    
1664
        // close the stream
1665
        xmlreader.reset();
1666

    
1667
        // check the stack whether it contains the keywords:
1668
        // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1669
        if (st.size() == 4) {
1670
            if (((String) st.pop()).equals(">")
1671
                    && (((String) st.peek()).equals("PUBLIC") | ((String) st
1672
                            .pop()).equals("SYSTEM"))
1673
                    && ((String) st.pop()).equals("<!DOCTYPE")) {
1674
                validate = true;
1675
            }
1676
        }
1677

    
1678
        MetaCatUtil.debugMessage("Validation for dtd is " + validate, 10);
1679
        return validate;
1680
    }
1681

    
1682
    // END OF INSERT/UPDATE SECTION
1683

    
1684
    /* check if the xml string contains key words to specify schema loocation */
1685
    private boolean needSchemaValidation(StringReader xml) throws IOException
1686
    {
1687
        boolean needSchemaValidate = false;
1688
        if (xml == null) {
1689
            MetaCatUtil.debugMessage("Validation for schema is "
1690
                    + needSchemaValidate, 10);
1691
            return needSchemaValidate;
1692
        }
1693
        System.out.println("before get target line");
1694
        String targetLine = getSchemaLine(xml);
1695
        System.out.println("after get target line");
1696
        // to see if the second line contain some keywords
1697
        if (targetLine != null
1698
                && (targetLine.indexOf(SCHEMALOCATIONKEYWORD) != -1 || targetLine
1699
                        .indexOf(NONAMESPACELOCATION) != -1)) {
1700
            // if contains schema location key word, should be validate
1701
            needSchemaValidate = true;
1702
        }
1703

    
1704
        MetaCatUtil.debugMessage("Validation for schema is "
1705
                + needSchemaValidate, 10);
1706
        return needSchemaValidate;
1707

    
1708
    }
1709

    
1710
    /* check if the xml string contains key words to specify schema loocation */
1711
    private String findNamespace(StringReader xml) throws IOException
1712
    {
1713
        String namespace = null;
1714

    
1715
        String eml2_0_0NameSpace = DocumentImpl.EML2_0_0NAMESPACE;
1716
        String eml2_0_1NameSpace = DocumentImpl.EML2_0_1NAMESPACE;
1717
        String eml2_1_0NameSpace = DocumentImpl.EML2_1_0NAMESPACE;
1718

    
1719
        if (xml == null) {
1720
            MetaCatUtil.debugMessage("Validation for schema is "
1721
                    + namespace, 10);
1722
            return namespace;
1723
        }
1724
        String targetLine = getSchemaLine(xml);
1725

    
1726
        if (targetLine != null) {
1727

    
1728
            int startIndex = targetLine.indexOf(SCHEMALOCATIONKEYWORD);
1729
            int start = 1;
1730
            int end = 1;
1731
            String schemaLocation = null;
1732
            int count = 0;
1733
            if (startIndex != -1) {
1734
                for (int i = startIndex; i < targetLine.length(); i++) {
1735
                    if (targetLine.charAt(i) == '"') {
1736
                        count++;
1737
                    }
1738
                    if (targetLine.charAt(i) == '"' && count == 1) {
1739
                        start = i;
1740
                    }
1741
                    if (targetLine.charAt(i) == '"' && count == 2) {
1742
                        end = i;
1743
                        break;
1744
                    }
1745
                }
1746
            }
1747
            schemaLocation = targetLine.substring(start + 1, end);
1748
            MetaCatUtil.debugMessage("schemaLocation in xml is: "
1749
                    + schemaLocation, 30);
1750
            if (schemaLocation.indexOf(eml2_0_0NameSpace) != -1) {
1751
                namespace = eml2_0_0NameSpace;
1752
            } else if (schemaLocation.indexOf(eml2_0_1NameSpace) != -1) {
1753
                namespace = eml2_0_1NameSpace;
1754
            } else if (schemaLocation.indexOf(eml2_1_0NameSpace) != -1) {
1755
                namespace = eml2_1_0NameSpace;
1756
            }
1757
        }
1758

    
1759
        MetaCatUtil.debugMessage("Validation for eml is " + namespace,
1760
                10);
1761

    
1762
        return namespace;
1763

    
1764
    }
1765

    
1766
    private String getSchemaLine(StringReader xml) throws IOException
1767
    {
1768
        // find the line
1769
        String secondLine = null;
1770
        int count = 0;
1771
        int endIndex = 0;
1772
        int startIndex = 0;
1773
        final int TARGETNUM = 2;
1774
        StringBuffer buffer = new StringBuffer();
1775
        boolean comment = false;
1776
        char thirdPreviousCharacter = '?';
1777
        char secondPreviousCharacter = '?';
1778
        char previousCharacter = '?';
1779
        char currentCharacter = '?';
1780
        int tmp = xml.read();
1781
        while (tmp != -1) {
1782
            currentCharacter = (char)tmp;
1783
            //in a comment
1784
            if (currentCharacter == '-' && previousCharacter == '-'
1785
                    && secondPreviousCharacter == '!'
1786
                    && thirdPreviousCharacter == '<') {
1787
                comment = true;
1788
            }
1789
            //out of comment
1790
            if (comment && currentCharacter == '>' && previousCharacter == '-'
1791
                    && secondPreviousCharacter == '-') {
1792
                comment = false;
1793
            }
1794

    
1795
            //this is not comment
1796
            if (currentCharacter != '!' && previousCharacter == '<' && !comment) {
1797
                count++;
1798
            }
1799
            // get target line
1800
            if (count == TARGETNUM && currentCharacter != '>') {
1801
                buffer.append(currentCharacter);
1802
            }
1803
            if (count == TARGETNUM && currentCharacter == '>') {
1804
                break;
1805
            }
1806
            thirdPreviousCharacter = secondPreviousCharacter;
1807
            secondPreviousCharacter = previousCharacter;
1808
            previousCharacter = currentCharacter;
1809
            tmp = xml.read();
1810
        }
1811
        secondLine = buffer.toString();
1812
        MetaCatUtil
1813
                .debugMessage("the second line string is: " + secondLine, 25);
1814
        xml.reset();
1815
        return secondLine;
1816
    }
1817

    
1818
    /**
1819
     * Handle the database delete request and delete an XML document from the
1820
     * database connection
1821
     */
1822
    private void handleDeleteAction(PrintWriter out, Hashtable params,
1823
            HttpServletRequest request, HttpServletResponse response,
1824
            String user, String[] groups)
1825
    {
1826

    
1827
        String[] docid = (String[]) params.get("docid");
1828

    
1829
        if(docid == null){
1830
          response.setContentType("text/xml");
1831
          out.println("<?xml version=\"1.0\"?>");
1832
          out.println("<error>");
1833
          out.println("Docid not specified.");
1834
          out.println("</error>");
1835
        } else {
1836

    
1837
            // delete the document from the database
1838
            try {
1839

    
1840
                try {
1841
                    // null means notify server is null
1842
                    DocumentImpl.delete(docid[0], user, groups, null);
1843
                    EventLog.getInstance().log(request.getRemoteAddr(),
1844
                                               user, docid[0], "delete");
1845
                    response.setContentType("text/xml");
1846
                    out.println("<?xml version=\"1.0\"?>");
1847
                    out.println("<success>");
1848
                    out.println("Document deleted.");
1849
                    out.println("</success>");
1850
                }
1851
                catch (AccessionNumberException ane) {
1852
                    response.setContentType("text/xml");
1853
                    out.println("<?xml version=\"1.0\"?>");
1854
                    out.println("<error>");
1855
                    //out.println("Error deleting document!!!");
1856
                    out.println(ane.getMessage());
1857
                    out.println("</error>");
1858
                }
1859
            }
1860
            catch (Exception e) {
1861
                response.setContentType("text/xml");
1862
                out.println("<?xml version=\"1.0\"?>");
1863
                out.println("<error>");
1864
                out.println(e.getMessage());
1865
                out.println("</error>");
1866
            }
1867
        }
1868
    }
1869

    
1870
    /**
1871
     * Handle the validation request and return the results to the requestor
1872
     */
1873
    private void handleValidateAction(PrintWriter out, Hashtable params)
1874
    {
1875

    
1876
        // Get the document indicated
1877
        String valtext = null;
1878
        DBConnection dbConn = null;
1879
        int serialNumber = -1;
1880

    
1881
        try {
1882
            valtext = ((String[]) params.get("valtext"))[0];
1883
        } catch (Exception nullpe) {
1884

    
1885
            String docid = null;
1886
            try {
1887
                // Find the document id number
1888
                docid = ((String[]) params.get("docid"))[0];
1889

    
1890
                // Get the document indicated from the db
1891
                DocumentImpl xmldoc = new DocumentImpl(docid);
1892
                valtext = xmldoc.toString();
1893

    
1894
            } catch (NullPointerException npe) {
1895

    
1896
                out.println("<error>Error getting document ID: " + docid
1897
                        + "</error>");
1898
                //if ( conn != null ) { util.returnConnection(conn); }
1899
                return;
1900
            } catch (Exception e) {
1901

    
1902
                out.println(e.getMessage());
1903
            }
1904
        }
1905

    
1906
        try {
1907
            // get a connection from the pool
1908
            dbConn = DBConnectionPool
1909
                    .getDBConnection("MetaCatServlet.handleValidateAction");
1910
            serialNumber = dbConn.getCheckOutSerialNumber();
1911
            DBValidate valobj = new DBValidate(saxparser, dbConn);
1912
            boolean valid = valobj.validateString(valtext);
1913

    
1914
            // set content type and other response header fields first
1915

    
1916
            out.println(valobj.returnErrors());
1917

    
1918
        } catch (NullPointerException npe2) {
1919
            // set content type and other response header fields first
1920

    
1921
            out.println("<error>Error validating document.</error>");
1922
        } catch (Exception e) {
1923

    
1924
            out.println(e.getMessage());
1925
        } finally {
1926
            // Return db connection
1927
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1928
        }
1929
    }
1930

    
1931
    /**
1932
     * Handle "getrevsionanddoctype" action Given a docid, return it's current
1933
     * revision and doctype from data base The output is String look like
1934
     * "rev;doctype"
1935
     */
1936
    private void handleGetRevisionAndDocTypeAction(PrintWriter out,
1937
            Hashtable params)
1938
    {
1939
        // To store doc parameter
1940
        String[] docs = new String[10];
1941
        // Store a single doc id
1942
        String givenDocId = null;
1943
        // Get docid from parameters
1944
        if (params.containsKey("docid")) {
1945
            docs = (String[]) params.get("docid");
1946
        }
1947
        // Get first docid form string array
1948
        givenDocId = docs[0];
1949

    
1950
        try {
1951
            // Make sure there is a docid
1952
            if (givenDocId == null || givenDocId.equals("")) { throw new Exception(
1953
                    "User didn't specify docid!"); }//if
1954

    
1955
            // Create a DBUtil object
1956
            DBUtil dbutil = new DBUtil();
1957
            // Get a rev and doctype
1958
            String revAndDocType = dbutil
1959
                    .getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
1960
            out.println(revAndDocType);
1961

    
1962
        } catch (Exception e) {
1963
            // Handle exception
1964
            out.println("<?xml version=\"1.0\"?>");
1965
            out.println("<error>");
1966
            out.println(e.getMessage());
1967
            out.println("</error>");
1968
        }
1969

    
1970
    }
1971

    
1972
    /**
1973
     * Handle "getaccesscontrol" action. Read Access Control List from db
1974
     * connection in XML format
1975
     */
1976
    private void handleGetAccessControlAction(PrintWriter out,
1977
            Hashtable params, HttpServletResponse response, String username,
1978
            String[] groupnames)
1979
    {
1980
        DBConnection dbConn = null;
1981
        int serialNumber = -1;
1982
        String docid = ((String[]) params.get("docid"))[0];
1983

    
1984
        try {
1985

    
1986
            // get connection from the pool
1987
            dbConn = DBConnectionPool
1988
                    .getDBConnection("MetaCatServlet.handleGetAccessControlAction");
1989
            serialNumber = dbConn.getCheckOutSerialNumber();
1990
            AccessControlList aclobj = new AccessControlList(dbConn);
1991
            String acltext = aclobj.getACL(docid, username, groupnames);
1992
            out.println(acltext);
1993

    
1994
        } catch (Exception e) {
1995
            out.println("<?xml version=\"1.0\"?>");
1996
            out.println("<error>");
1997
            out.println(e.getMessage());
1998
            out.println("</error>");
1999
        } finally {
2000
            // Retrun db connection to pool
2001
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2002
        }
2003
    }
2004

    
2005
    /**
2006
     * Handle the "getprincipals" action. Read all principals from
2007
     * authentication scheme in XML format
2008
     */
2009
    private void handleGetPrincipalsAction(PrintWriter out, String user,
2010
            String password)
2011
    {
2012
        try {
2013
            AuthSession auth = new AuthSession();
2014
            String principals = auth.getPrincipals(user, password);
2015
            out.println(principals);
2016

    
2017
        } catch (Exception e) {
2018
            out.println("<?xml version=\"1.0\"?>");
2019
            out.println("<error>");
2020
            out.println(e.getMessage());
2021
            out.println("</error>");
2022
        }
2023
    }
2024

    
2025
    /**
2026
     * Handle "getdoctypes" action. Read all doctypes from db connection in XML
2027
     * format
2028
     */
2029
    private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
2030
            HttpServletResponse response)
2031
    {
2032
        try {
2033
            DBUtil dbutil = new DBUtil();
2034
            String doctypes = dbutil.readDoctypes();
2035
            out.println(doctypes);
2036
        } catch (Exception e) {
2037
            out.println("<?xml version=\"1.0\"?>");
2038
            out.println("<error>");
2039
            out.println(e.getMessage());
2040
            out.println("</error>");
2041
        }
2042
    }
2043

    
2044
    /**
2045
     * Handle the "getdtdschema" action. Read DTD or Schema file for a given
2046
     * doctype from Metacat catalog system
2047
     */
2048
    private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
2049
            HttpServletResponse response)
2050
    {
2051

    
2052
        String doctype = null;
2053
        String[] doctypeArr = (String[]) params.get("doctype");
2054

    
2055
        // get only the first doctype specified in the list of doctypes
2056
        // it could be done for all doctypes in that list
2057
        if (doctypeArr != null) {
2058
            doctype = ((String[]) params.get("doctype"))[0];
2059
        }
2060

    
2061
        try {
2062
            DBUtil dbutil = new DBUtil();
2063
            String dtdschema = dbutil.readDTDSchema(doctype);
2064
            out.println(dtdschema);
2065

    
2066
        } catch (Exception e) {
2067
            out.println("<?xml version=\"1.0\"?>");
2068
            out.println("<error>");
2069
            out.println(e.getMessage());
2070
            out.println("</error>");
2071
        }
2072

    
2073
    }
2074

    
2075
    /**
2076
     * Handle the "getlastdocid" action. Get the latest docid with rev number
2077
     * from db connection in XML format
2078
     */
2079
    private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
2080
            HttpServletResponse response)
2081
    {
2082

    
2083
        String scope = ((String[]) params.get("scope"))[0];
2084
        if (scope == null) {
2085
            scope = ((String[]) params.get("username"))[0];
2086
        }
2087

    
2088
        try {
2089

    
2090
            DBUtil dbutil = new DBUtil();
2091
            String lastDocid = dbutil.getMaxDocid(scope);
2092
            out.println("<?xml version=\"1.0\"?>");
2093
            out.println("<lastDocid>");
2094
            out.println("  <scope>" + scope + "</scope>");
2095
            out.println("  <docid>" + lastDocid + "</docid>");
2096
            out.println("</lastDocid>");
2097

    
2098
        } catch (Exception e) {
2099
            out.println("<?xml version=\"1.0\"?>");
2100
            out.println("<error>");
2101
            out.println(e.getMessage());
2102
            out.println("</error>");
2103
        }
2104
    }
2105

    
2106
    /**
2107
     * Print a report from the event log based on filter parameters passed in
2108
     * from the web.
2109
     *
2110
     * @param params the parameters from the web request
2111
     * @param request the http request object for getting request details
2112
     * @param response the http response object for writing output
2113
     */
2114
    private void handleGetLogAction(Hashtable params, HttpServletRequest request,
2115
            HttpServletResponse response, String username)
2116
    {
2117
        try {
2118
            response.setContentType("text/xml");
2119
            PrintWriter out = response.getWriter();
2120
            
2121
            // Check that the user is authenticated as an administrator account
2122
            boolean adminIsAuthenticated = false;
2123
            for (int i = 0; i < administrators.length; i++) {
2124
                if (username.equals(administrators[i])) {
2125
                        adminIsAuthenticated = true;
2126
                }
2127
            }
2128
            if (!adminIsAuthenticated) {
2129
                out.print("<error>");
2130
                out.print("The user \"" + username + 
2131
                        "\" is not authorized for this action.");
2132
                out.print("</error>");
2133
                return;
2134
            }
2135
    
2136
            // Get all of the parameters in the correct formats
2137
            String[] ipAddress = (String[])params.get("ipaddress");
2138
            String[] principal = (String[])params.get("principal");
2139
            String[] docid = (String[])params.get("docid");
2140
            String[] event = (String[])params.get("event");
2141
            String[] startArray = (String[]) params.get("start");
2142
            String[] endArray = (String[]) params.get("end");
2143
            String start = null;
2144
            String end = null;
2145
            if (startArray != null) {
2146
                start = startArray[0];
2147
            }
2148
            if (endArray != null) {
2149
                end = endArray[0];
2150
            }
2151
            Timestamp startDate = null;
2152
            Timestamp endDate = null;
2153
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2154
            try {
2155
                if (start != null) {
2156
                    startDate = new Timestamp((format.parse(start)).getTime());
2157
                }
2158
                if (end != null) {
2159
                    endDate = new Timestamp((format.parse(end)).getTime());
2160
                }
2161
            } catch (ParseException e) {
2162
                System.out.println("Failed to created Timestamp from input.");
2163
            }
2164
    
2165
            // Request the report by passing the filter parameters
2166
            out.println(EventLog.getInstance().getReport(ipAddress, principal,
2167
                    docid, event, startDate, endDate));
2168
            out.close();
2169
        } catch (IOException e) {
2170
            MetaCatUtil.debugMessage(
2171
                    "Could not open http response for writing: " + e.getMessage(), 5);
2172
        }
2173
    }
2174

    
2175
    /**
2176
     * Rebuild the index for one or more documents. If the docid parameter is
2177
     * provided, rebuild for just that one document or list of documents. If
2178
     * not, then rebuild the index for all documents in the xml_documents
2179
     * table.
2180
     *
2181
     * @param params the parameters from the web request
2182
     * @param request the http request object for getting request details
2183
     * @param response the http response object for writing output
2184
     * @param username the username of the authenticated user
2185
     */
2186
    private void handleBuildIndexAction(Hashtable params, 
2187
            HttpServletRequest request, HttpServletResponse response,
2188
            String username)
2189
    {
2190
        // Get all of the parameters in the correct formats
2191
        String[] docid = (String[])params.get("docid");
2192

    
2193
        // Rebuild the indices for appropriate documents
2194
        try {
2195
            response.setContentType("text/xml");
2196
            PrintWriter out = response.getWriter();
2197
            
2198
            // Check that the user is authenticated as an administrator account
2199
            boolean adminIsAuthenticated = false;
2200
            for (int i = 0; i < administrators.length; i++) {
2201
                if (username.equals(administrators[i])) {
2202
                        adminIsAuthenticated = true;
2203
                }
2204
            }
2205
            if (!adminIsAuthenticated) {
2206
                out.print("<error>");
2207
                out.print("The user \"" + username + 
2208
                        "\" is not authorized for this action.");
2209
                out.print("</error>");
2210
                return;
2211
            }
2212

    
2213
            // Process the documents
2214
            out.println("<success>");
2215
            if (docid == null || docid.length == 0) {
2216
                // Process all of the documents
2217
                try {
2218
                    Vector documents = getDocumentList();
2219
                    Iterator it = documents.iterator();
2220
                    while (it.hasNext()) {
2221
                        String id = (String) it.next();
2222
                        buildDocumentIndex(id, out);
2223
                    }
2224
                } catch (SQLException se) {
2225
                    out.print("<error>");
2226
                    out.print(se.getMessage());
2227
                    out.println("</error>");
2228
                }
2229
            } else {
2230
                // Only process the requested documents
2231
                for (int i = 0; i < docid.length; i++) {
2232
                    buildDocumentIndex(docid[i], out);
2233
                }
2234
            }
2235
            out.println("</success>");
2236
            out.close();
2237
        } catch (IOException e) {
2238
            MetaCatUtil.debugMessage(
2239
                    "Could not open http response for writing: "
2240
                    + e.getMessage(), 5);
2241
        }
2242
    }
2243

    
2244
    /**
2245
     * Build the index for one document by reading the document and 
2246
     * calling its buildIndex() method.
2247
     *
2248
     * @param docid the document (with revision) to rebuild
2249
     * @param out the PrintWriter to which output is printed
2250
     */
2251
    private void buildDocumentIndex(String docid, PrintWriter out)
2252
    {
2253
        try {
2254
            DocumentImpl doc = new DocumentImpl(docid, false);
2255
            doc.buildIndex();
2256
            out.print("<docid>" + docid);
2257
            out.println("</docid>");
2258
        } catch (McdbException me) {
2259
            out.print("<error>");
2260
            out.print(me.getMessage());
2261
            out.println("</error>");
2262
        }
2263
    }
2264

    
2265
    /**
2266
     * Handle documents passed to metacat that are encoded using the
2267
     * "multipart/form-data" mime type. This is typically used for uploading
2268
     * data files which may be binary and large.
2269
     */
2270
    private void handleMultipartForm(HttpServletRequest request,
2271
            HttpServletResponse response)
2272
    {
2273
        PrintWriter out = null;
2274
        String action = null;
2275

    
2276
        // Parse the multipart form, and save the parameters in a Hashtable and
2277
        // save the FileParts in a hashtable
2278

    
2279
        Hashtable params = new Hashtable();
2280
        Hashtable fileList = new Hashtable();
2281
        int sizeLimit = (new Integer(MetaCatUtil.getOption("datafilesizelimit")))
2282
                .intValue();
2283
        MetaCatUtil.debugMessage(
2284
                "The limit size of data file is: " + sizeLimit, 50);
2285

    
2286
        try {
2287
            // MBJ: need to put filesize limit in Metacat config
2288
            // (metacat.properties)
2289
            MultipartParser mp = new MultipartParser(request,
2290
                    sizeLimit * 1024 * 1024);
2291
            Part part;
2292
            while ((part = mp.readNextPart()) != null) {
2293
                String name = part.getName();
2294

    
2295
                if (part.isParam()) {
2296
                    // it's a parameter part
2297
                    ParamPart paramPart = (ParamPart) part;
2298
                    String value = paramPart.getStringValue();
2299
                    params.put(name, value);
2300
                    if (name.equals("action")) {
2301
                        action = value;
2302
                    }
2303
                } else if (part.isFile()) {
2304
                    // it's a file part
2305
                    FilePart filePart = (FilePart) part;
2306
                    fileList.put(name, filePart);
2307

    
2308
                    // Stop once the first file part is found, otherwise going
2309
                    // onto the
2310
                    // next part prevents access to the file contents. So...for
2311
                    // upload
2312
                    // to work, the datafile must be the last part
2313
                    break;
2314
                }
2315
            }
2316
        } catch (IOException ioe) {
2317
            try {
2318
                out = response.getWriter();
2319
            } catch (IOException ioe2) {
2320
                System.err
2321
                        .println("Fatal Error: couldn't get response output stream.");
2322
            }
2323
            out.println("<?xml version=\"1.0\"?>");
2324
            out.println("<error>");
2325
            out.println("Error: problem reading multipart data.");
2326
            out.println("</error>");
2327
        }
2328

    
2329
        // Get the session information
2330
        String username = null;
2331
        String password = null;
2332
        String[] groupnames = null;
2333
        String sess_id = null;
2334

    
2335
        // be aware of session expiration on every request
2336
        HttpSession sess = request.getSession(true);
2337
        if (sess.isNew()) {
2338
            // session expired or has not been stored b/w user requests
2339
            username = "public";
2340
            sess.setAttribute("username", username);
2341
        } else {
2342
            username = (String) sess.getAttribute("username");
2343
            password = (String) sess.getAttribute("password");
2344
            groupnames = (String[]) sess.getAttribute("groupnames");
2345
            try {
2346
                sess_id = (String) sess.getId();
2347
            } catch (IllegalStateException ise) {
2348
                System.out
2349
                        .println("error in  handleMultipartForm: this shouldn't "
2350
                                + "happen: the session should be valid: "
2351
                                + ise.getMessage());
2352
            }
2353
        }
2354

    
2355
        // Get the out stream
2356
        try {
2357
            out = response.getWriter();
2358
        } catch (IOException ioe2) {
2359
            MetaCatUtil.debugMessage("Fatal Error: couldn't get response "
2360
                    + "output stream.", 30);
2361
        }
2362

    
2363
        if (action.equals("upload")) {
2364
            if (username != null && !username.equals("public")) {
2365
                handleUploadAction(request, out, params, fileList, username,
2366
                        groupnames);
2367
            } else {
2368

    
2369
                out.println("<?xml version=\"1.0\"?>");
2370
                out.println("<error>");
2371
                out.println("Permission denied for " + action);
2372
                out.println("</error>");
2373
            }
2374
        } else {
2375
            /*
2376
             * try { out = response.getWriter(); } catch (IOException ioe2) {
2377
             * System.err.println("Fatal Error: couldn't get response output
2378
             * stream.");
2379
             */
2380
            out.println("<?xml version=\"1.0\"?>");
2381
            out.println("<error>");
2382
            out.println(
2383
                    "Error: action not registered.  Please report this error.");
2384
            out.println("</error>");
2385
        }
2386
        out.close();
2387
    }
2388

    
2389
    /**
2390
     * Handle the upload action by saving the attached file to disk and
2391
     * registering it in the Metacat db
2392
     */
2393
    private void handleUploadAction(HttpServletRequest request,
2394
            PrintWriter out, Hashtable params, Hashtable fileList,
2395
            String username, String[] groupnames)
2396
    {
2397
        //PrintWriter out = null;
2398
        //Connection conn = null;
2399
        String action = null;
2400
        String docid = null;
2401

    
2402
        /*
2403
         * response.setContentType("text/xml"); try { out =
2404
         * response.getWriter(); } catch (IOException ioe2) {
2405
         * System.err.println("Fatal Error: couldn't get response output
2406
         * stream.");
2407
         */
2408

    
2409
        if (params.containsKey("docid")) {
2410
            docid = (String) params.get("docid");
2411
        }
2412

    
2413
        // Make sure we have a docid and datafile
2414
        if (docid != null && fileList.containsKey("datafile")) {
2415

    
2416
            // Get a reference to the file part of the form
2417
            FilePart filePart = (FilePart) fileList.get("datafile");
2418
            String fileName = filePart.getFileName();
2419
            MetaCatUtil.debugMessage("Uploading filename: " + fileName, 10);
2420

    
2421
            // Check if the right file existed in the uploaded data
2422
            if (fileName != null) {
2423

    
2424
                try {
2425
                    //MetaCatUtil.debugMessage("Upload datafile " + docid
2426
                    // +"...", 10);
2427
                    //If document get lock data file grant
2428
                    if (DocumentImpl.getDataFileLockGrant(docid)) {
2429
                        // register the file in the database (which generates
2430
                        // an exception
2431
                        //if the docid is not acceptable or other untoward
2432
                        // things happen
2433
                        DocumentImpl.registerDocument(fileName, "BIN", docid,
2434
                                username, groupnames);
2435

    
2436
                        // Save the data file to disk using "docid" as the name
2437
                        dataDirectory.mkdirs();
2438
                        File newFile = new File(dataDirectory, docid);
2439
                        long size = filePart.writeTo(newFile);
2440

    
2441
                        EventLog.getInstance().log(request.getRemoteAddr(),
2442
                                username, docid, "upload");
2443
                        // Force replication this data file
2444
                        // To data file, "insert" and update is same
2445
                        // The fourth parameter is null. Because it is
2446
                        // notification server
2447
                        // and this method is in MetaCatServerlet. It is
2448
                        // original command,
2449
                        // not get force replication info from another metacat
2450
                        ForceReplicationHandler frh = new ForceReplicationHandler(
2451
                                docid, "insert", false, null);
2452

    
2453
                        // set content type and other response header fields
2454
                        // first
2455
                        out.println("<?xml version=\"1.0\"?>");
2456
                        out.println("<success>");
2457
                        out.println("<docid>" + docid + "</docid>");
2458
                        out.println("<size>" + size + "</size>");
2459
                        out.println("</success>");
2460
                    }
2461

    
2462
                } catch (Exception e) {
2463
                    out.println("<?xml version=\"1.0\"?>");
2464
                    out.println("<error>");
2465
                    out.println(e.getMessage());
2466
                    out.println("</error>");
2467
                }
2468
            } else {
2469
                // the field did not contain a file
2470
                out.println("<?xml version=\"1.0\"?>");
2471
                out.println("<error>");
2472
                out.println("The uploaded data did not contain a valid file.");
2473
                out.println("</error>");
2474
            }
2475
        } else {
2476
            // Error bcse docid missing or file missing
2477
            out.println("<?xml version=\"1.0\"?>");
2478
            out.println("<error>");
2479
            out.println("The uploaded data did not contain a valid docid "
2480
                    + "or valid file.");
2481
            out.println("</error>");
2482
        }
2483
    }
2484

    
2485
    /*
2486
     * A method to handle set access action
2487
     */
2488
    private void handleSetAccessAction(PrintWriter out, Hashtable params,
2489
            String username)
2490
    {
2491
        String[] docList = null;
2492
        String[] principalList = null;
2493
        String[] permissionList = null;
2494
        String[] permTypeList = null;
2495
        String[] permOrderList = null;
2496
        String permission = null;
2497
        String permType = null;
2498
        String permOrder = null;
2499
        Vector errorList = new Vector();
2500
        String error = null;
2501
        Vector successList = new Vector();
2502
        String success = null;
2503

    
2504
        // Get parameters
2505
        if (params.containsKey("docid")) {
2506
            docList = (String[]) params.get("docid");
2507
        }
2508
        if (params.containsKey("principal")) {
2509
            principalList = (String[]) params.get("principal");
2510
        }
2511
        if (params.containsKey("permission")) {
2512
            permissionList = (String[]) params.get("permission");
2513

    
2514
        }
2515
        if (params.containsKey("permType")) {
2516
            permTypeList = (String[]) params.get("permType");
2517

    
2518
        }
2519
        if (params.containsKey("permOrder")) {
2520
            permOrderList = (String[]) params.get("permOrder");
2521

    
2522
        }
2523

    
2524
        // Make sure the parameter is not null
2525
        if (docList == null || principalList == null || permTypeList == null
2526
                || permissionList == null) {
2527
            error = "Please check your parameter list, it should look like: "
2528
                    + "?action=setaccess&docid=pipeline.1.1&principal=public"
2529
                    + "&permission=read&permType=allow&permOrder=allowFirst";
2530
            errorList.addElement(error);
2531
            outputResponse(successList, errorList, out);
2532
            return;
2533
        }
2534

    
2535
        // Only select first element for permission, type and order
2536
        permission = permissionList[0];
2537
        permType = permTypeList[0];
2538
        if (permOrderList != null) {
2539
            permOrder = permOrderList[0];
2540
        }
2541

    
2542
        // Get package doctype set
2543
        Vector packageSet = MetaCatUtil.getOptionList(MetaCatUtil
2544
                .getOption("packagedoctypeset"));
2545
        //debug
2546
        if (packageSet != null) {
2547
            for (int i = 0; i < packageSet.size(); i++) {
2548
                MetaCatUtil.debugMessage("doctype in package set: "
2549
                        + (String) packageSet.elementAt(i), 34);
2550
            }
2551
        }
2552

    
2553
        // handle every accessionNumber
2554
        for (int i = 0; i < docList.length; i++) {
2555
            String accessionNumber = docList[i];
2556
            String owner = null;
2557
            String publicId = null;
2558
            // Get document owner and public id
2559
            try {
2560
                owner = getFieldValueForDoc(accessionNumber, "user_owner");
2561
                publicId = getFieldValueForDoc(accessionNumber, "doctype");
2562
            } catch (Exception e) {
2563
                MetaCatUtil.debugMessage("Error in handleSetAccessAction: "
2564
                        + e.getMessage(), 30);
2565
                error = "Error in set access control for document - "
2566
                        + accessionNumber + e.getMessage();
2567
                errorList.addElement(error);
2568
                continue;
2569
            }
2570
            //check if user is the owner. Only owner can do owner
2571
            if (username == null || owner == null || !username.equals(owner)) {
2572
                error = "User - " + username
2573
                        + " does not have permission to set "
2574
                        + "access control for docid - " + accessionNumber;
2575
                errorList.addElement(error);
2576
                continue;
2577
            }
2578

    
2579
            // If docid publicid is BIN data file or other beta4, 6 package
2580
            // document
2581
            // we could not do set access control. Because we don't want
2582
            // inconsistent
2583
            // to its access docuemnt
2584
            if (publicId != null && packageSet != null
2585
                    && packageSet.contains(publicId)) {
2586
                error = "Could not set access control to document "
2587
                        + accessionNumber
2588
                        + "because it is in a pakcage and it has a access file for it";
2589
                errorList.addElement(error);
2590
                continue;
2591
            }
2592

    
2593
            // for every principle
2594
            for (int j = 0; j < principalList.length; j++) {
2595
                String principal = principalList[j];
2596
                try {
2597
                    //insert permission
2598
                    AccessControlForSingleFile accessControl = new AccessControlForSingleFile(
2599
                            accessionNumber, principal, permission, permType,
2600
                            permOrder);
2601
                    accessControl.insertPermissions();
2602
                    success = "Set access control to document "
2603
                            + accessionNumber + " successfully";
2604
                    successList.addElement(success);
2605
                } catch (Exception ee) {
2606
                    MetaCatUtil.debugMessage(
2607
                            "Erorr in handleSetAccessAction2: "
2608
                                    + ee.getMessage(), 30);
2609
                    error = "Faild to set access control for document "
2610
                            + accessionNumber + " because " + ee.getMessage();
2611
                    errorList.addElement(error);
2612
                    continue;
2613
                }
2614
            }
2615
        }
2616
        outputResponse(successList, errorList, out);
2617
    }
2618

    
2619
    /*
2620
     * A method try to determin a docid's public id, if couldn't find null will
2621
     * be returned.
2622
     */
2623
    private String getFieldValueForDoc(String accessionNumber, String fieldName)
2624
            throws Exception
2625
    {
2626
        if (accessionNumber == null || accessionNumber.equals("")
2627
                || fieldName == null || fieldName.equals("")) { throw new Exception(
2628
                "Docid or field name was not specified"); }
2629

    
2630
        PreparedStatement pstmt = null;
2631
        ResultSet rs = null;
2632
        String fieldValue = null;
2633
        String docId = null;
2634
        DBConnection conn = null;
2635
        int serialNumber = -1;
2636

    
2637
        // get rid of revision if access number has
2638
        docId = MetaCatUtil.getDocIdFromString(accessionNumber);
2639
        try {
2640
            //check out DBConnection
2641
            conn = DBConnectionPool
2642
                    .getDBConnection("MetaCatServlet.getPublicIdForDoc");
2643
            serialNumber = conn.getCheckOutSerialNumber();
2644
            pstmt = conn.prepareStatement("SELECT " + fieldName
2645
                    + " FROM xml_documents " + "WHERE docid = ? ");
2646

    
2647
            pstmt.setString(1, docId);
2648
            pstmt.execute();
2649
            rs = pstmt.getResultSet();
2650
            boolean hasRow = rs.next();
2651
            int perm = 0;
2652
            if (hasRow) {
2653
                fieldValue = rs.getString(1);
2654
            } else {
2655
                throw new Exception("Could not find document: "
2656
                        + accessionNumber);
2657
            }
2658
        } catch (Exception e) {
2659
            MetaCatUtil.debugMessage(
2660
                    "Exception in MetacatServlet.getPublicIdForDoc: "
2661
                            + e.getMessage(), 30);
2662
            throw e;
2663
        } finally {
2664
            try {
2665
                rs.close();
2666
                pstmt.close();
2667

    
2668
            } finally {
2669
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2670
            }
2671
        }
2672
        return fieldValue;
2673
    }
2674

    
2675
    /*
2676
     * Get the list of documents from the database and return the list in an
2677
     * Vector of identifiers.
2678
     *
2679
     * @ returns the array of identifiers
2680
     */
2681
    private Vector getDocumentList() throws SQLException
2682
    {
2683
        Vector docList = new Vector();
2684
        PreparedStatement pstmt = null;
2685
        ResultSet rs = null;
2686
        DBConnection conn = null;
2687
        int serialNumber = -1;
2688

    
2689
        try {
2690
            //check out DBConnection
2691
            conn = DBConnectionPool
2692
                    .getDBConnection("MetaCatServlet.getDocumentList");
2693
            serialNumber = conn.getCheckOutSerialNumber();
2694
            pstmt = conn.prepareStatement("SELECT docid, rev"
2695
                    + " FROM xml_documents ");
2696
            pstmt.execute();
2697
            rs = pstmt.getResultSet();
2698
            while (rs.next()) {
2699
                String docid = rs.getString(1);
2700
                String rev = rs.getString(2);
2701
                docList.add(docid + "." + rev);
2702
            }
2703
        } catch (SQLException e) {
2704
            MetaCatUtil.debugMessage(
2705
                    "Exception in MetacatServlet.getDocumentList: "
2706
                            + e.getMessage(), 30);
2707
            throw e;
2708
        } finally {
2709
            try {
2710
                rs.close();
2711
                pstmt.close();
2712

    
2713
            } catch (SQLException se) {
2714
                MetaCatUtil.debugMessage(
2715
                    "Exception in MetacatServlet.getDocumentList: "
2716
                            + se.getMessage(), 30);
2717
                throw se;
2718
            } finally {
2719
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2720
            }
2721
        }
2722
        return docList;
2723
    }
2724

    
2725
    /*
2726
     * A method to output setAccess action result
2727
     */
2728
    private void outputResponse(Vector successList, Vector errorList,
2729
            PrintWriter out)
2730
    {
2731
        boolean error = false;
2732
        boolean success = false;
2733
        // Output prolog
2734
        out.println(PROLOG);
2735
        // output success message
2736
        if (successList != null) {
2737
            for (int i = 0; i < successList.size(); i++) {
2738
                out.println(SUCCESS);
2739
                out.println((String) successList.elementAt(i));
2740
                out.println(SUCCESSCLOSE);
2741
                success = true;
2742
            }
2743
        }
2744
        // output error message
2745
        if (errorList != null) {
2746
            for (int i = 0; i < errorList.size(); i++) {
2747
                out.println(ERROR);
2748
                out.println((String) errorList.elementAt(i));
2749
                out.println(ERRORCLOSE);
2750
                error = true;
2751
            }
2752
        }
2753

    
2754
        // if no error and no success info, send a error that nothing happened
2755
        if (!error && !success) {
2756
            out.println(ERROR);
2757
            out.println("Nothing happend for setaccess action");
2758
            out.println(ERRORCLOSE);
2759
        }
2760
    }
2761
}
(42-42/63)