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: 2005-09-08 10:04:14 -0700 (Thu, 08 Sep 2005) $'
11
 * '$Revision: 2570 $'
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.zip.ZipEntry;
50
import java.util.zip.ZipOutputStream;
51

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

    
61
import org.ecoinformatics.eml.EMLParser;
62

    
63
import com.oreilly.servlet.multipart.FilePart;
64
import com.oreilly.servlet.multipart.MultipartParser;
65
import com.oreilly.servlet.multipart.ParamPart;
66
import com.oreilly.servlet.multipart.Part;
67

    
68
import edu.ucsb.nceas.utilities.Options;
69

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

    
117
    private ServletConfig config = null;
118

    
119
    private ServletContext context = null;
120

    
121
    private String resultStyleURL = null;
122

    
123
    private String xmlcatalogfile = null;
124

    
125
    private String saxparser = null;
126

    
127
    private String datafilepath = null;
128

    
129
    private File dataDirectory = null;
130

    
131
    private String servletpath = null;
132

    
133
    private String htmlpath = null;
134

    
135
    private PropertyResourceBundle options = null;
136

    
137
    private MetaCatUtil util = null;
138

    
139
    private DBConnectionPool connPool = null;
140

    
141
    private Hashtable sessionHash = new Hashtable();
142

    
143
    private static final String PROLOG = "<?xml version=\"1.0\"?>";
144

    
145
    private static final String SUCCESS = "<success>";
146

    
147
    private static final String SUCCESSCLOSE = "</success>";
148

    
149
    private static final String ERROR = "<error>";
150

    
151
    private static final String ERRORCLOSE = "</error>";
152

    
153
    public static final String SCHEMALOCATIONKEYWORD = ":schemaLocation";
154

    
155
    public static final String NONAMESPACELOCATION = ":noNamespaceSchemaLocation";
156

    
157
    public static final String EML2KEYWORD = ":eml";
158

    
159
    public static final String XMLFORMAT = "xml";
160

    
161
    private static final String CONFIG_DIR = "WEB-INF";
162

    
163
    private static final String CONFIG_NAME = "metacat.properties";
164

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

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

    
188
            util = new MetaCatUtil();
189

    
190
            //initial DBConnection pool
191
            connPool = DBConnectionPool.getInstance();
192

    
193
            // Get the configuration file information
194
            resultStyleURL = MetaCatUtil.getOption("resultStyleURL");
195
            xmlcatalogfile = MetaCatUtil.getOption("xmlcatalogfile");
196
            saxparser = MetaCatUtil.getOption("saxparser");
197
            datafilepath = MetaCatUtil.getOption("datafilepath");
198
            dataDirectory = new File(datafilepath);
199
            servletpath = MetaCatUtil.getOption("servletpath");
200
            htmlpath = MetaCatUtil.getOption("htmlpath");
201

    
202
            // Index the paths specified in the metacat.properties
203
            checkIndexPaths();
204

    
205
            System.out.println("Metacat (" + Version.getVersion()
206
                               + ") initialized.");
207

    
208
        } catch (ServletException ex) {
209
            throw ex;
210
        } catch (SQLException e) {
211
            MetaCatUtil.debugMessage("Error in MetacatServlet.init: "
212
                    + e.getMessage(), 20);
213
        }
214
    }
215

    
216
    /**
217
     * Close all db connections from the pool
218
     */
219
    public void destroy()
220
    {
221
        // Close all db connection
222
        System.out.println("Destroying MetacatServlet");
223
        DBConnectionPool.release();
224
    }
225

    
226
    /** Handle "GET" method requests from HTTP clients */
227
    public void doGet(HttpServletRequest request, HttpServletResponse response)
228
            throws ServletException, IOException
229
    {
230

    
231
        // Process the data and send back the response
232
        handleGetOrPost(request, response);
233
    }
234

    
235
    /** Handle "POST" method requests from HTTP clients */
236
    public void doPost(HttpServletRequest request, HttpServletResponse response)
237
            throws ServletException, IOException
238
    {
239

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

    
244
    /**
245
     * Index the paths specified in the metacat.properties
246
     */
247
    private void checkIndexPaths(){
248
        MetaCatUtil.pathsForIndexing
249
            = MetaCatUtil.getOptionList(MetaCatUtil.getOption("indexed_paths"));
250
    
251
        if (MetaCatUtil.pathsForIndexing != null) {
252
    
253
            MetaCatUtil.debugMessage("Indexing paths....", 20);
254
    
255
            DBConnection conn = null;
256
            int serialNumber = -1;
257
            PreparedStatement pstmt = null;
258
            PreparedStatement pstmt1 = null;
259
            ResultSet rs = null;
260
    
261
            for (int i = 0; i < MetaCatUtil.pathsForIndexing.size(); i++) {
262
                MetaCatUtil.formattedDebugMessage("Checking if '"
263
                           + (String) MetaCatUtil.pathsForIndexing.elementAt(i)
264
                           + "' is indexed.... ",30, false, true);
265
    
266
                try {
267
                    //check out DBConnection
268
                    conn = DBConnectionPool.
269
                        getDBConnection("MetaCatServlet.checkIndexPaths");
270
                    serialNumber = conn.getCheckOutSerialNumber();
271
    
272
                    pstmt = conn.prepareStatement(
273
                        "SELECT * FROM xml_path_index " + "WHERE path = ?");
274
                    pstmt.setString(1, (String) MetaCatUtil.pathsForIndexing
275
                                    .elementAt(i));
276
    
277
                    pstmt.execute();
278
                    rs = pstmt.getResultSet();
279
    
280
                    if (!rs.next()) {
281
                        MetaCatUtil.formattedDebugMessage("not indexed yet.", 30,
282
                                                       true, false);
283
                        rs.close();
284
                        pstmt.close();
285
                        conn.increaseUsageCount(1);
286
    
287
                        MetaCatUtil.debugMessage(
288
                              "Inserting following path in xml_path_index: "
289
                              + (String)MetaCatUtil.pathsForIndexing
290
                                                   .elementAt(i), 60);
291
    
292
                        pstmt = conn.prepareStatement("SELECT DISTINCT n.docid, "
293
                              + "n.nodedata, n.nodedatanumerical, n.parentnodeid"
294
                              + " FROM xml_nodes n, xml_index i WHERE"
295
                              + " i.path = ? and n.parentnodeid=i.nodeid and"
296
                              + " n.nodetype LIKE 'TEXT'");
297
                        pstmt.setString(1, (String) MetaCatUtil.
298
                                        pathsForIndexing.elementAt(i));
299
                        pstmt.execute();
300
                        rs = pstmt.getResultSet();
301
    
302
                        int count = 0;
303
                        MetaCatUtil.debugMessage(
304
                                       "Executed the select statement for: "
305
                                       + (String) MetaCatUtil.pathsForIndexing
306
                                         .elementAt(i), 60);
307
    
308
                        try {
309
                            while (rs.next()) {
310
    
311
                                String docid = rs.getString(1);
312
                                String nodedata = rs.getString(2);
313
                                float nodedatanumerical = rs.getFloat(3);
314
                                int parentnodeid = rs.getInt(4);
315
    
316
                                if (!nodedata.trim().equals("")) {
317
                                    pstmt1 = conn.prepareStatement(
318
                                        "INSERT INTO xml_path_index"
319
                                        + " (docid, path, nodedata, "
320
                                        + "nodedatanumerical, parentnodeid)"
321
                                        + " VALUES (?, ?, ?, ?, ?)");
322
    
323
                                    pstmt1.setString(1, docid);
324
                                    pstmt1.setString(2, (String) MetaCatUtil.
325
                                                pathsForIndexing.elementAt(i));
326
                                    pstmt1.setString(3, nodedata);
327
                                    pstmt1.setFloat(4, nodedatanumerical);
328
                                    pstmt1.setFloat(5, parentnodeid);
329
    
330
                                    pstmt1.execute();
331
                                    pstmt1.close();
332
    
333
                                    count++;
334
    
335
                                }
336
                            }
337
                        }
338
                        catch (Exception e) {
339
                            System.out.println("Exception:" + e.getMessage());
340
                            e.printStackTrace();
341
                        }
342
    
343
                        rs.close();
344
                        pstmt.close();
345
                        conn.increaseUsageCount(1);
346
    
347
                        MetaCatUtil.debugMessage("Indexed " + count
348
                                + " records from xml_nodes for '"
349
                                + (String) MetaCatUtil.pathsForIndexing.elementAt(i)
350
                                + "'", 20);
351
    
352
                    } else {
353
                        MetaCatUtil.formattedDebugMessage("already indexed.", 30,
354
                                                       true, false);
355
                    }
356
    
357
                    rs.close();
358
                    pstmt.close();
359
                    conn.increaseUsageCount(1);
360
    
361
                } catch (Exception e) {
362
                    MetaCatUtil.debugMessage("error in DocumentImpl.delete: "
363
                                             + e.getMessage(), 30);
364
                }finally {
365
                    //check in DBonnection
366
                    DBConnectionPool.returnDBConnection(conn, serialNumber);
367
                }
368
    
369
    
370
            }
371
    
372
            MetaCatUtil.debugMessage("Path Indexing Completed", 20);
373
        }
374
    }
375

    
376

    
377
    /**
378
     * Control servlet response depending on the action parameter specified
379
     */
380
    private void handleGetOrPost(HttpServletRequest request,
381
            HttpServletResponse response) throws ServletException, IOException
382
    {
383

    
384
        if (util == null) {
385
            util = new MetaCatUtil();
386
        }
387
        /*
388
         * MetaCatUtil.debugMessage("Connection pool size: "
389
         * +connPool.getSizeOfDBConnectionPool(),10);
390
         * MetaCatUtil.debugMessage("Free DBConnection number: "
391
         */
392
        //If all DBConnection in the pool are free and DBConnection pool
393
        //size is greater than initial value, shrink the connection pool
394
        //size to initial value
395
        DBConnectionPool.shrinkDBConnectionPoolSize();
396

    
397
        //Debug message to print out the method which have a busy DBConnection
398
        connPool.printMethodNameHavingBusyDBConnection();
399

    
400
        String ctype = request.getContentType();
401
        if (ctype != null && ctype.startsWith("multipart/form-data")) {
402
            handleMultipartForm(request, response);
403
        } else {
404

    
405
            String name = null;
406
            String[] value = null;
407
            String[] docid = new String[3];
408
            Hashtable params = new Hashtable();
409
            Enumeration paramlist = request.getParameterNames();
410

    
411
            while (paramlist.hasMoreElements()) {
412

    
413
                name = (String) paramlist.nextElement();
414
                value = request.getParameterValues(name);
415

    
416
                // Decode the docid and mouse click information
417
                if (name.endsWith(".y")) {
418
                    docid[0] = name.substring(0, name.length() - 2);
419
                    params.put("docid", docid);
420
                    name = "ypos";
421
                }
422
                if (name.endsWith(".x")) {
423
                    name = "xpos";
424
                }
425

    
426
                params.put(name, value);
427
            }
428

    
429
            //handle param is emptpy
430
            if (params.isEmpty() || params == null) { return; }
431

    
432
            //if the user clicked on the input images, decode which image
433
            //was clicked then set the action.
434
            if(params.get("action") == null){
435
                PrintWriter out = response.getWriter();
436
                response.setContentType("text/xml");
437
                out.println("<?xml version=\"1.0\"?>");
438
                out.println("<error>");
439
                out.println("Action not specified");
440
                out.println("</error>");
441
                out.close();
442
                return;
443
            }
444

    
445
            String action = ((String[]) params.get("action"))[0];
446
            MetaCatUtil.debugMessage("Line 230: Action is: " + action, 1);
447

    
448
            // This block handles session management for the servlet
449
            // by looking up the current session information for all actions
450
            // other than "login" and "logout"
451
            String username = null;
452
            String password = null;
453
            String[] groupnames = null;
454
            String sess_id = null;
455

    
456
            // handle login action
457
            if (action.equals("login")) {
458
                PrintWriter out = response.getWriter();
459
                handleLoginAction(out, params, request, response);
460
                out.close();
461

    
462
                // handle logout action
463
            } else if (action.equals("logout")) {
464
                PrintWriter out = response.getWriter();
465
                handleLogoutAction(out, params, request, response);
466
                out.close();
467

    
468
                // handle shrink DBConnection request
469
            } else if (action.equals("shrink")) {
470
                PrintWriter out = response.getWriter();
471
                boolean success = false;
472
                //If all DBConnection in the pool are free and DBConnection
473
                // pool
474
                //size is greater than initial value, shrink the connection
475
                // pool
476
                //size to initial value
477
                success = DBConnectionPool.shrinkConnectionPoolSize();
478
                if (success) {
479
                    //if successfully shrink the pool size to initial value
480
                    out.println("DBConnection Pool shrunk successfully.");
481
                }//if
482
                else {
483
                    out.println("DBConnection pool not shrunk successfully.");
484
                }
485
                //close out put
486
                out.close();
487

    
488
                // aware of session expiration on every request
489
            } else {
490
                HttpSession sess = request.getSession(true);
491
                if (sess.isNew() && !params.containsKey("sessionid")) {
492
                    // session expired or has not been stored b/w user requests
493
                    MetaCatUtil.debugMessage(
494
                            "in session is new or no sessionid", 40);
495
                    username = "public";
496
                    sess.setAttribute("username", username);
497
                } else {
498
                    MetaCatUtil.debugMessage("in session is not new or "
499
                            + " has sessionid parameter", 40);
500
                    try {
501
                        if (params.containsKey("sessionid")) {
502
                            sess_id = ((String[]) params.get("sessionid"))[0];
503
                            MetaCatUtil.debugMessage("in has sessionid "
504
                                    + sess_id, 40);
505
                            if (sessionHash.containsKey(sess_id)) {
506
                                MetaCatUtil.debugMessage("find the id "
507
                                        + sess_id + " in hash table", 40);
508
                                sess = (HttpSession) sessionHash.get(sess_id);
509
                            }
510
                        } else {
511
                            // we already store the session in login, so we
512
                            // don't need here
513
                            /*
514
                             * MetaCatUtil.debugMessage("in no sessionid
515
                             * parameter ", 40); sess_id =
516
                             * (String)sess.getId();
517
                             * MetaCatUtil.debugMessage("storing the session id "
518
                             * + sess_id + " which has username " +
519
                             * sess.getAttribute("username") + " into session
520
                             * hash in handleGetOrPost method", 35);
521
                             */
522
                        }
523
                    } catch (IllegalStateException ise) {
524
                        System.out.println(
525
                                "error in handleGetOrPost: this shouldn't "
526
                                + "happen: the session should be valid: "
527
                                + ise.getMessage());
528
                    }
529

    
530
                    username = (String) sess.getAttribute("username");
531
                    MetaCatUtil.debugMessage("The user name from session is: "
532
                            + username, 20);
533
                    password = (String) sess.getAttribute("password");
534
                    groupnames = (String[]) sess.getAttribute("groupnames");
535
                }
536

    
537
                //make user user username should be public
538
                if (username == null || (username.trim().equals(""))) {
539
                    username = "public";
540
                }
541
                MetaCatUtil.debugMessage("The user is : " + username, 5);
542
            }
543
            // Now that we know the session is valid, we can delegate the
544
            // request
545
            // to a particular action handler
546
            if (action.equals("query")) {
547
                PrintWriter out = response.getWriter();
548
                handleQuery(out, params, response, username, groupnames,
549
                        sess_id);
550
                out.close();
551
            } else if (action.equals("squery")) {
552
                PrintWriter out = response.getWriter();
553
                if (params.containsKey("query")) {
554
                    handleSQuery(out, params, response, username, groupnames,
555
                            sess_id);
556
                    out.close();
557
                } else {
558
                    out.println(
559
                            "Illegal action squery without \"query\" parameter");
560
                    out.close();
561
                }
562
            } else if (action.equals("export")) {
563

    
564
                handleExportAction(params, response, username,
565
                        groupnames, password);
566
            } else if (action.equals("read")) {
567
                handleReadAction(params, request, response, username, password,
568
                        groupnames);
569
            } else if (action.equals("readinlinedata")) {
570
                handleReadInlineDataAction(params, request, response, username,
571
                        password, groupnames);
572
            } else if (action.equals("insert") || action.equals("update")) {
573
                PrintWriter out = response.getWriter();
574
                if ((username != null) && !username.equals("public")) {
575
                    handleInsertOrUpdateAction(request, response,
576
                            out, params, username, groupnames);
577
                } else {
578
                    response.setContentType("text/xml");
579
                    out.println("<?xml version=\"1.0\"?>");
580
                    out.println("<error>");
581
                    out.println("Permission denied for user " + username + " "
582
                            + action);
583
                    out.println("</error>");
584
                }
585
                out.close();
586
            } else if (action.equals("delete")) {
587
                PrintWriter out = response.getWriter();
588
                if ((username != null) && !username.equals("public")) {
589
                    handleDeleteAction(out, params, request, response, username,
590
                            groupnames);
591
                } else {
592
                    response.setContentType("text/xml");
593
                    out.println("<?xml version=\"1.0\"?>");
594
                    out.println("<error>");
595
                    out.println("Permission denied for " + action);
596
                    out.println("</error>");
597
                }
598
                out.close();
599
            } else if (action.equals("validate")) {
600
                PrintWriter out = response.getWriter();
601
                handleValidateAction(out, params);
602
                out.close();
603
            } else if (action.equals("setaccess")) {
604
                PrintWriter out = response.getWriter();
605
                handleSetAccessAction(out, params, username);
606
                out.close();
607
            } else if (action.equals("getaccesscontrol")) {
608
                PrintWriter out = response.getWriter();
609
                handleGetAccessControlAction(out, params, response, username,
610
                        groupnames);
611
                out.close();
612
            } else if (action.equals("getprincipals")) {
613
                PrintWriter out = response.getWriter();
614
                handleGetPrincipalsAction(out, username, password);
615
                out.close();
616
            } else if (action.equals("getdoctypes")) {
617
                PrintWriter out = response.getWriter();
618
                handleGetDoctypesAction(out, params, response);
619
                out.close();
620
            } else if (action.equals("getdtdschema")) {
621
                PrintWriter out = response.getWriter();
622
                handleGetDTDSchemaAction(out, params, response);
623
                out.close();
624
            } else if (action.equals("getlastdocid")) {
625
                PrintWriter out = response.getWriter();
626
                handleGetMaxDocidAction(out, params, response);
627
                out.close();
628
            } else if (action.equals("getrevisionanddoctype")) {
629
                PrintWriter out = response.getWriter();
630
                handleGetRevisionAndDocTypeAction(out, params);
631
                out.close();
632
            } else if (action.equals("getversion")) {
633
                response.setContentType("text/xml");
634
                PrintWriter out = response.getWriter();
635
                out.println(Version.getVersionAsXml());
636
                out.close();
637
            } else if (action.equals("getlog")) {
638
                handleGetLogAction(params, request, response, username, groupnames);
639
            } else if (action.equals("buildindex")) {
640
                handleBuildIndexAction(params, request, response, username, groupnames);
641
            } else if (action.equals("login") || action.equals("logout")) {
642
                /*
643
            } else if (action.equals("protocoltest")) {
644
                String testURL = "metacat://dev.nceas.ucsb.edu/NCEAS.897766.9";
645
                try {
646
                    testURL = ((String[]) params.get("url"))[0];
647
                } catch (Throwable t) {
648
                }
649
                String phandler = System
650
                        .getProperty("java.protocol.handler.pkgs");
651
                response.setContentType("text/html");
652
                PrintWriter out = response.getWriter();
653
                out.println("<body bgcolor=\"white\">");
654
                out.println("<p>Handler property: <code>" + phandler
655
                        + "</code></p>");
656
                out.println("<p>Starting test for:<br>");
657
                out.println("    " + testURL + "</p>");
658
                try {
659
                    URL u = new URL(testURL);
660
                    out.println("<pre>");
661
                    out.println("Protocol: " + u.getProtocol());
662
                    out.println("    Host: " + u.getHost());
663
                    out.println("    Port: " + u.getPort());
664
                    out.println("    Path: " + u.getPath());
665
                    out.println("     Ref: " + u.getRef());
666
                    String pquery = u.getQuery();
667
                    out.println("   Query: " + pquery);
668
                    out.println("  Params: ");
669
                    if (pquery != null) {
670
                        Hashtable qparams = MetaCatUtil.parseQuery(u.getQuery());
671
                        for (Enumeration en = qparams.keys(); en
672
                                .hasMoreElements();) {
673
                            String pname = (String) en.nextElement();
674
                            String pvalue = (String) qparams.get(pname);
675
                            out.println("    " + pname + ": " + pvalue);
676
                        }
677
                    }
678
                    out.println("</pre>");
679
                    out.println("</body>");
680
                    out.close();
681
                } catch (MalformedURLException mue) {
682
                    System.out.println(
683
                            "bad url from MetacatServlet.handleGetOrPost");
684
                    out.println(mue.getMessage());
685
                    mue.printStackTrace(out);
686
                    out.close();
687
                }
688
                */
689
            } else {
690
                PrintWriter out = response.getWriter();
691
                out.println("<?xml version=\"1.0\"?>");
692
                out.println("<error>");
693
                out.println(
694
                     "Error: action not registered.  Please report this error.");
695
                out.println("</error>");
696
                out.close();
697
            }
698

    
699
            //util.closeConnections();
700
            // Close the stream to the client
701
            //out.close();
702
        }
703
    }
704

    
705
    // LOGIN & LOGOUT SECTION
706
    /**
707
     * Handle the login request. Create a new session object. Do user
708
     * authentication through the session.
709
     */
710
    private void handleLoginAction(PrintWriter out, Hashtable params,
711
            HttpServletRequest request, HttpServletResponse response)
712
    {
713

    
714
        AuthSession sess = null;
715

    
716
        if(params.get("username") == null){
717
            response.setContentType("text/xml");
718
            out.println("<?xml version=\"1.0\"?>");
719
            out.println("<error>");
720
            out.println("Username not specified");
721
            out.println("</error>");
722
            return;
723
        }
724

    
725
        if(params.get("password") == null){
726
            response.setContentType("text/xml");
727
            out.println("<?xml version=\"1.0\"?>");
728
            out.println("<error>");
729
            out.println("Password not specified");
730
            out.println("</error>");
731
            return;
732
        }
733

    
734
        String un = ((String[]) params.get("username"))[0];
735
        MetaCatUtil.debugMessage("user " + un + " try to login", 20);
736
        String pw = ((String[]) params.get("password"))[0];
737

    
738
        String qformat = "xml";
739
        if(params.get("qformat") != null){
740
            qformat = ((String[]) params.get("qformat"))[0];
741
        }
742

    
743
        try {
744
            sess = new AuthSession();
745
        } catch (Exception e) {
746
            System.out.println("error in MetacatServlet.handleLoginAction: "
747
                    + e.getMessage());
748
            out.println(e.getMessage());
749
            return;
750
        }
751
        boolean isValid = sess.authenticate(request, un, pw);
752

    
753
        //if it is authernticate is true, store the session
754
        if (isValid) {
755
            HttpSession session = sess.getSessions();
756
            String id = session.getId();
757
            MetaCatUtil.debugMessage("Store session id " + id
758
                    + "which has username" + session.getAttribute("username")
759
                    + " into hash in login method", 35);
760
            sessionHash.put(id, session);
761
        }
762

    
763
        // format and transform the output
764
        if (qformat.equals("xml")) {
765
            response.setContentType("text/xml");
766
            out.println(sess.getMessage());
767
        } else {
768
            try {
769
                DBTransform trans = new DBTransform();
770
                response.setContentType("text/html");
771
                trans.transformXMLDocument(sess.getMessage(),
772
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
773
                        out, null);
774
            } catch (Exception e) {
775

    
776
                MetaCatUtil.debugMessage(
777
                        "Error in MetaCatServlet.handleLoginAction: "
778
                                + e.getMessage(), 30);
779
            }
780
        }
781
    }
782

    
783
    /**
784
     * Handle the logout request. Close the connection.
785
     */
786
    private void handleLogoutAction(PrintWriter out, Hashtable params,
787
            HttpServletRequest request, HttpServletResponse response)
788
    {
789

    
790
        String qformat = "xml";
791
        if(params.get("qformat") != null){
792
            qformat = ((String[]) params.get("qformat"))[0];
793
        }
794

    
795
        // close the connection
796
        HttpSession sess = request.getSession(false);
797
        MetaCatUtil.debugMessage("After get session in logout request", 40);
798
        if (sess != null) {
799
            MetaCatUtil.debugMessage("The session id " + sess.getId()
800
                    + " will be invalidate in logout action", 30);
801
            MetaCatUtil.debugMessage("The session contains user "
802
                    + sess.getAttribute("username")
803
                    + " will be invalidate in logout action", 30);
804
            sess.invalidate();
805
        }
806

    
807
        // produce output
808
        StringBuffer output = new StringBuffer();
809
        output.append("<?xml version=\"1.0\"?>");
810
        output.append("<logout>");
811
        output.append("User logged out");
812
        output.append("</logout>");
813

    
814
        //format and transform the output
815
        if (qformat.equals("xml")) {
816
            response.setContentType("text/xml");
817
            out.println(output.toString());
818
        } else {
819
            try {
820
                DBTransform trans = new DBTransform();
821
                response.setContentType("text/html");
822
                trans.transformXMLDocument(output.toString(),
823
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
824
                        out, null);
825
            } catch (Exception e) {
826
                MetaCatUtil.debugMessage(
827
                        "Error in MetaCatServlet.handleLogoutAction"
828
                                + e.getMessage(), 30);
829
            }
830
        }
831
    }
832

    
833
    // END OF LOGIN & LOGOUT SECTION
834

    
835
    // SQUERY & QUERY SECTION
836
    /**
837
     * Retreive the squery xml, execute it and display it
838
     *
839
     * @param out the output stream to the client
840
     * @param params the Hashtable of parameters that should be included in the
841
     *            squery.
842
     * @param response the response object linked to the client
843
     * @param conn the database connection
844
     */
845
    private void handleSQuery(PrintWriter out, Hashtable params,
846
            HttpServletResponse response, String user, String[] groups,
847
            String sessionid)
848
    {
849
        double startTime = System.currentTimeMillis() / 1000;
850
        DBQuery queryobj = new DBQuery(saxparser);
851
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
852
        double outPutTime = System.currentTimeMillis() / 1000;
853
        MetaCatUtil.debugMessage("total search time: "
854
                + (outPutTime - startTime), 30);
855

    
856
    }
857

    
858
    /**
859
     * Create the xml query, execute it and display the results.
860
     *
861
     * @param out the output stream to the client
862
     * @param params the Hashtable of parameters that should be included in the
863
     *            squery.
864
     * @param response the response object linked to the client
865
     */
866
    private void handleQuery(PrintWriter out, Hashtable params,
867
            HttpServletResponse response, String user, String[] groups,
868
            String sessionid)
869
    {
870
        //create the query and run it
871
        String xmlquery = DBQuery.createSQuery(params);
872
        String[] queryArray = new String[1];
873
        queryArray[0] = xmlquery;
874
        params.put("query", queryArray);
875
        double startTime = System.currentTimeMillis() / 1000;
876
        DBQuery queryobj = new DBQuery(saxparser);
877
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
878
        double outPutTime = System.currentTimeMillis() / 1000;
879
        MetaCatUtil.debugMessage("total search time: "
880
                + (outPutTime - startTime), 30);
881

    
882
        //handleSQuery(out, params, response,user, groups, sessionid);
883
    }
884

    
885
    // END OF SQUERY & QUERY SECTION
886

    
887
    //Exoport section
888
    /**
889
     * Handle the "export" request of data package from Metacat in zip format
890
     *
891
     * @param params the Hashtable of HTTP request parameters
892
     * @param response the HTTP response object linked to the client
893
     * @param user the username sent the request
894
     * @param groups the user's groupnames
895
     */
896
    private void handleExportAction(Hashtable params,
897
            HttpServletResponse response,
898
            String user, String[] groups, String passWord)
899
    {
900
        // Output stream
901
        ServletOutputStream out = null;
902
        // Zip output stream
903
        ZipOutputStream zOut = null;
904
        DBQuery queryObj = null;
905

    
906
        String[] docs = new String[10];
907
        String docId = "";
908

    
909
        try {
910
            // read the params
911
            if (params.containsKey("docid")) {
912
                docs = (String[]) params.get("docid");
913
            }
914
            // Create a DBuery to handle export
915
            queryObj = new DBQuery(saxparser);
916
            // Get the docid
917
            docId = docs[0];
918
            // Make sure the client specify docid
919
            if (docId == null || docId.equals("")) {
920
                response.setContentType("text/xml"); //MIME type
921
                // Get a printwriter
922
                PrintWriter pw = response.getWriter();
923
                // Send back message
924
                pw.println("<?xml version=\"1.0\"?>");
925
                pw.println("<error>");
926
                pw.println("You didn't specify requested docid");
927
                pw.println("</error>");
928
                // Close printwriter
929
                pw.close();
930
                return;
931
            }
932
            // Get output stream
933
            out = response.getOutputStream();
934
            response.setContentType("application/zip"); //MIME type
935
            response.setHeader("Content-Disposition", 
936
            		"attachment; filename=" 
937
            		+ docId + ".zip"); // Set the name of the zip file
938
            		
939
            zOut = new ZipOutputStream(out);
940
            zOut = queryObj
941
                    .getZippedPackage(docId, out, user, groups, passWord);
942
            zOut.finish(); //terminate the zip file
943
            zOut.close(); //close the zip stream
944

    
945
        } catch (Exception e) {
946
            try {
947
                response.setContentType("text/xml"); //MIME type
948
                // Send error message back
949
                if (out != null) {
950
                    PrintWriter pw = new PrintWriter(out);
951
                    pw.println("<?xml version=\"1.0\"?>");
952
                    pw.println("<error>");
953
                    pw.println(e.getMessage());
954
                    pw.println("</error>");
955
                    // Close printwriter
956
                    pw.close();
957
                    // Close output stream
958
                    out.close();
959
                }
960
                // Close zip output stream
961
                if (zOut != null) {
962
                    zOut.close();
963
                }
964
            } catch (IOException ioe) {
965
                MetaCatUtil.debugMessage("Problem with the servlet output "
966
                        + "in MetacatServlet.handleExportAction: "
967
                        + ioe.getMessage(), 30);
968
            }
969

    
970
            MetaCatUtil.debugMessage(
971
                    "Error in MetacatServlet.handleExportAction: "
972
                            + e.getMessage(), 30);
973
            e.printStackTrace(System.out);
974

    
975
        }
976

    
977
    }
978

    
979
    /**
980
     * In eml2 document, the xml can have inline data and data was stripped off
981
     * and store in file system. This action can be used to read inline data
982
     * only
983
     *
984
     * @param params the Hashtable of HTTP request parameters
985
     * @param response the HTTP response object linked to the client
986
     * @param user the username sent the request
987
     * @param groups the user's groupnames
988
     */
989
    private void handleReadInlineDataAction(Hashtable params,
990
            HttpServletRequest request, HttpServletResponse response,
991
            String user, String passWord, String[] groups)
992
    {
993
        String[] docs = new String[10];
994
        String inlineDataId = null;
995
        String docId = "";
996
        ServletOutputStream out = null;
997

    
998
        try {
999
            // read the params
1000
            if (params.containsKey("inlinedataid")) {
1001
                docs = (String[]) params.get("inlinedataid");
1002
            }
1003
            // Get the docid
1004
            inlineDataId = docs[0];
1005
            // Make sure the client specify docid
1006
            if (inlineDataId == null || inlineDataId.equals("")) {
1007
                throw new Exception("You didn't specify requested inlinedataid"); }
1008

    
1009
            // check for permission
1010
            docId = MetaCatUtil
1011
                    .getDocIdWithoutRevFromInlineDataID(inlineDataId);
1012
            PermissionController controller = new PermissionController(docId);
1013
            // check top level read permission
1014
            if (!controller.hasPermission(user, groups,
1015
                    AccessControlInterface.READSTRING))
1016
            {
1017
                throw new Exception("User " + user
1018
                        + " doesn't have permission " + " to read document "
1019
                        + docId);
1020
            }
1021
            else
1022
            {
1023
              //check data access level
1024
              try
1025
              {
1026
                Hashtable unReadableInlineDataList =
1027
                    PermissionController.getUnReadableInlineDataIdList(docId,
1028
                    user, groups, false);
1029
                if (unReadableInlineDataList.containsValue(
1030
                          MetaCatUtil.getInlineDataIdWithoutRev(inlineDataId)))
1031
                {
1032
                  throw new Exception("User " + user
1033
                       + " doesn't have permission " + " to read inlinedata "
1034
                       + inlineDataId);
1035

    
1036
                }//if
1037
              }//try
1038
              catch (Exception e)
1039
              {
1040
                throw e;
1041
              }//catch
1042
            }//else
1043

    
1044
            // Get output stream
1045
            out = response.getOutputStream();
1046
            // read the inline data from the file
1047
            String inlinePath = MetaCatUtil.getOption("inlinedatafilepath");
1048
            File lineData = new File(inlinePath, inlineDataId);
1049
            FileInputStream input = new FileInputStream(lineData);
1050
            byte[] buffer = new byte[4 * 1024];
1051
            int bytes = input.read(buffer);
1052
            while (bytes != -1) {
1053
                out.write(buffer, 0, bytes);
1054
                bytes = input.read(buffer);
1055
            }
1056
            out.close();
1057

    
1058
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1059
                    inlineDataId, "readinlinedata");
1060
        } catch (Exception e) {
1061
            try {
1062
                PrintWriter pw = null;
1063
                // Send error message back
1064
                if (out != null) {
1065
                    pw = new PrintWriter(out);
1066
                } else {
1067
                    pw = response.getWriter();
1068
                }
1069
                pw.println("<?xml version=\"1.0\"?>");
1070
                pw.println("<error>");
1071
                pw.println(e.getMessage());
1072
                pw.println("</error>");
1073
                // Close printwriter
1074
                pw.close();
1075
                // Close output stream if out is not null
1076
                if (out != null) {
1077
                    out.close();
1078
                }
1079
            } catch (IOException ioe) {
1080
                MetaCatUtil.debugMessage("Problem with the servlet output "
1081
                        + "in MetacatServlet.handleExportAction: "
1082
                        + ioe.getMessage(), 30);
1083
            }
1084
            MetaCatUtil.debugMessage(
1085
                    "Error in MetacatServlet.handleReadInlineDataAction: "
1086
                            + e.getMessage(), 30);
1087
        }
1088
    }
1089

    
1090
    /*
1091
     * Get the nodeid from xml_nodes for the inlinedataid
1092
     */
1093
    private long getInlineDataNodeId(String inLineDataId, String docId)
1094
            throws SQLException
1095
    {
1096
        long nodeId = 0;
1097
        String INLINE = "inline";
1098
        boolean hasRow;
1099
        PreparedStatement pStmt = null;
1100
        DBConnection conn = null;
1101
        int serialNumber = -1;
1102
        String sql = "SELECT nodeid FROM xml_nodes WHERE docid=? AND nodedata=? "
1103
                + "AND nodetype='TEXT' AND parentnodeid IN "
1104
                + "(SELECT nodeid FROM xml_nodes WHERE docid=? AND "
1105
                + "nodetype='ELEMENT' AND nodename='" + INLINE + "')";
1106

    
1107
        try {
1108
            //check out DBConnection
1109
            conn = DBConnectionPool
1110
                    .getDBConnection("AccessControlList.isAllowFirst");
1111
            serialNumber = conn.getCheckOutSerialNumber();
1112

    
1113
            pStmt = conn.prepareStatement(sql);
1114
            //bind value
1115
            pStmt.setString(1, docId);//docid
1116
            pStmt.setString(2, inLineDataId);//inlinedataid
1117
            pStmt.setString(3, docId);
1118
            // excute query
1119
            pStmt.execute();
1120
            ResultSet rs = pStmt.getResultSet();
1121
            hasRow = rs.next();
1122
            // get result
1123
            if (hasRow) {
1124
                nodeId = rs.getLong(1);
1125
            }//if
1126

    
1127
        } catch (SQLException e) {
1128
            throw e;
1129
        } finally {
1130
            try {
1131
                pStmt.close();
1132
            } finally {
1133
                DBConnectionPool.returnDBConnection(conn, serialNumber);
1134
            }
1135
        }
1136
        MetaCatUtil.debugMessage("The nodeid for inlinedataid " + inLineDataId
1137
                + " is: " + nodeId, 35);
1138
        return nodeId;
1139
    }
1140

    
1141
    /**
1142
     * Handle the "read" request of metadata/data files from Metacat or any
1143
     * files from Internet; transformed metadata XML document into HTML
1144
     * presentation if requested; zip files when more than one were requested.
1145
     *
1146
     * @param params the Hashtable of HTTP request parameters
1147
     * @param request the HTTP request object linked to the client
1148
     * @param response the HTTP response object linked to the client
1149
     * @param user the username sent the request
1150
     * @param groups the user's groupnames
1151
     */
1152
    private void handleReadAction(Hashtable params, HttpServletRequest request,
1153
            HttpServletResponse response, String user, String passWord,
1154
            String[] groups)
1155
    {
1156
        ServletOutputStream out = null;
1157
        ZipOutputStream zout = null;
1158
        PrintWriter pw = null;
1159
        boolean zip = false;
1160
        boolean withInlineData = true;
1161

    
1162
        try {
1163
            String[] docs = new String[0];
1164
            String docid = "";
1165
            String qformat = "";
1166
            String abstrpath = null;
1167

    
1168
            // read the params
1169
            if (params.containsKey("docid")) {
1170
                docs = (String[]) params.get("docid");
1171
            }
1172
            if (params.containsKey("qformat")) {
1173
                qformat = ((String[]) params.get("qformat"))[0];
1174
            }
1175
            // the param for only metadata (eml)
1176
            // we don't support read a eml document without inline data now.
1177
            /*if (params.containsKey("inlinedata")) {
1178

    
1179
                String inlineData = ((String[]) params.get("inlinedata"))[0];
1180
                if (inlineData.equalsIgnoreCase("false")) {
1181
                    withInlineData = false;
1182
                }
1183
            }*/
1184
            if ((docs.length > 1) || qformat.equals("zip")) {
1185
                zip = true;
1186
                out = response.getOutputStream();
1187
                response.setContentType("application/zip"); //MIME type
1188
                zout = new ZipOutputStream(out);
1189
            }
1190
            // go through the list of docs to read
1191
            for (int i = 0; i < docs.length; i++) {
1192
                try {
1193

    
1194
                    URL murl = new URL(docs[i]);
1195
                    Hashtable murlQueryStr = MetaCatUtil.parseQuery(
1196
                            murl.getQuery());
1197
                    // case docid="http://.../?docid=aaa"
1198
                    // or docid="metacat://.../?docid=bbb"
1199
                    if (murlQueryStr.containsKey("docid")) {
1200
                        // get only docid, eliminate the rest
1201
                        docid = (String) murlQueryStr.get("docid");
1202
                        if (zip) {
1203
                            addDocToZip(request, docid, zout, user, groups);
1204
                        } else {
1205
                            readFromMetacat(request, response, docid, qformat,
1206
                                    abstrpath, user, groups, zip, zout,
1207
                                    withInlineData, params);
1208
                        }
1209

    
1210
                        // case docid="http://.../filename"
1211
                    } else {
1212
                        docid = docs[i];
1213
                        if (zip) {
1214
                            addDocToZip(request, docid, zout, user, groups);
1215
                        } else {
1216
                            readFromURLConnection(response, docid);
1217
                        }
1218
                    }
1219

    
1220
                } catch (MalformedURLException mue) {
1221
                    docid = docs[i];
1222
                    if (zip) {
1223
                        addDocToZip(request, docid, zout, user, groups);
1224
                    } else {
1225
                        readFromMetacat(request, response, docid, qformat,
1226
                                abstrpath, user, groups, zip, zout,
1227
                                withInlineData, params);
1228
                    }
1229
                }
1230
            }
1231

    
1232
            if (zip) {
1233
                zout.finish(); //terminate the zip file
1234
                zout.close(); //close the zip stream
1235
            }
1236

    
1237
        } catch (McdbDocNotFoundException notFoundE) {
1238
            // To handle doc not found exception
1239
            // the docid which didn't be found
1240
            String notFoundDocId = notFoundE.getUnfoundDocId();
1241
            String notFoundRevision = notFoundE.getUnfoundRevision();
1242
            MetaCatUtil.debugMessage("Missed id: " + notFoundDocId, 30);
1243
            MetaCatUtil.debugMessage("Missed rev: " + notFoundRevision, 30);
1244
            try {
1245
                // read docid from remote server
1246
                readFromRemoteMetaCat(response, notFoundDocId,
1247
                        notFoundRevision, user, passWord, out, zip, zout);
1248
                // Close zout outputstream
1249
                if (zout != null) {
1250
                    zout.close();
1251
                }
1252
                // close output stream
1253
                if (out != null) {
1254
                    out.close();
1255
                }
1256

    
1257
            } catch (Exception exc) {
1258
                MetaCatUtil.debugMessage(
1259
                        "Erorr in MetacatServlet.hanldReadAction: "
1260
                                + exc.getMessage(), 30);
1261
                try {
1262
                    if (out != null) {
1263
                        response.setContentType("text/xml");
1264
                        // Send back error message by printWriter
1265
                        pw = new PrintWriter(out);
1266
                        pw.println("<?xml version=\"1.0\"?>");
1267
                        pw.println("<error>");
1268
                        pw.println(notFoundE.getMessage());
1269
                        pw.println("</error>");
1270
                        pw.close();
1271
                        out.close();
1272

    
1273
                    } else {
1274
                        response.setContentType("text/xml"); //MIME type
1275
                        // Send back error message if out = null
1276
                        if (pw == null) {
1277
                            // If pw is null, open the respnose
1278
                            pw = response.getWriter();
1279
                        }
1280
                        pw.println("<?xml version=\"1.0\"?>");
1281
                        pw.println("<error>");
1282
                        pw.println(notFoundE.getMessage());
1283
                        pw.println("</error>");
1284
                        pw.close();
1285
                    }
1286
                    // close zout
1287
                    if (zout != null) {
1288
                        zout.close();
1289
                    }
1290
                } catch (IOException ie) {
1291
                    MetaCatUtil.debugMessage("Problem with the servlet output "
1292
                            + "in MetacatServlet.handleReadAction: "
1293
                            + ie.getMessage(), 30);
1294
                }
1295
            }
1296
        } catch (Exception e) {
1297
            try {
1298

    
1299
                if (out != null) {
1300
                    response.setContentType("text/xml"); //MIME type
1301
                    pw = new PrintWriter(out);
1302
                    pw.println("<?xml version=\"1.0\"?>");
1303
                    pw.println("<error>");
1304
                    pw.println(e.getMessage());
1305
                    pw.println("</error>");
1306
                    pw.close();
1307
                    out.close();
1308
                } else {
1309
                    response.setContentType("text/xml"); //MIME type
1310
                    // Send back error message if out = null
1311
                    if (pw == null) {
1312
                        pw = response.getWriter();
1313
                    }
1314
                    pw.println("<?xml version=\"1.0\"?>");
1315
                    pw.println("<error>");
1316
                    pw.println(e.getMessage());
1317
                    pw.println("</error>");
1318
                    pw.close();
1319

    
1320
                }
1321
                // Close zip output stream
1322
                if (zout != null) {
1323
                    zout.close();
1324
                }
1325

    
1326
            } catch (IOException ioe) {
1327
                MetaCatUtil.debugMessage("Problem with the servlet output "
1328
                        + "in MetacatServlet.handleReadAction: "
1329
                        + ioe.getMessage(), 30);
1330
                ioe.printStackTrace(System.out);
1331

    
1332
            }
1333

    
1334
            MetaCatUtil.debugMessage(
1335
                    "Error in MetacatServlet.handleReadAction: "
1336
                            + e.getMessage(), 30);
1337
            //e.printStackTrace(System.out);
1338
        }
1339
    }
1340

    
1341
    /** read metadata or data from Metacat
1342
     */
1343
    private void readFromMetacat(HttpServletRequest request,
1344
            HttpServletResponse response, String docid, String qformat,
1345
            String abstrpath, String user, String[] groups, boolean zip,
1346
            ZipOutputStream zout, boolean withInlineData, Hashtable params)
1347
            throws ClassNotFoundException, IOException, SQLException,
1348
            McdbException, Exception
1349
    {
1350

    
1351
        try {
1352

    
1353
            DocumentImpl doc = new DocumentImpl(docid);
1354

    
1355
            //check the permission for read
1356
            if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1357
                Exception e = new Exception("User " + user
1358
                        + " does not have permission"
1359
                        + " to read the document with the docid " + docid);
1360

    
1361
                throw e;
1362
            }
1363

    
1364
            if (doc.getRootNodeID() == 0) {
1365
                // this is data file
1366
                String filepath = MetaCatUtil.getOption("datafilepath");
1367
                if (!filepath.endsWith("/")) {
1368
                    filepath += "/";
1369
                }
1370
                String filename = filepath + docid;
1371
                FileInputStream fin = null;
1372
                fin = new FileInputStream(filename);
1373

    
1374
                //MIME type
1375
                String contentType = getServletContext().getMimeType(filename);
1376
                if (contentType == null) {
1377
                    ContentTypeProvider provider = new ContentTypeProvider(
1378
                            docid);
1379
                    contentType = provider.getContentType();
1380
                    MetaCatUtil.debugMessage("Final contenttype is: "
1381
                            + contentType, 30);
1382
                }
1383

    
1384
                response.setContentType(contentType);
1385
                // if we decide to use "application/octet-stream" for all data
1386
                // returns
1387
                // response.setContentType("application/octet-stream");
1388

    
1389
                try {
1390

    
1391
                    ServletOutputStream out = response.getOutputStream();
1392
                    byte[] buf = new byte[4 * 1024]; // 4K buffer
1393
                    int b = fin.read(buf);
1394
                    while (b != -1) {
1395
                        out.write(buf, 0, b);
1396
                        b = fin.read(buf);
1397
                    }
1398
                } finally {
1399
                    if (fin != null) fin.close();
1400
                }
1401

    
1402
            } else {
1403
                // this is metadata doc
1404
                if (qformat.equals("xml") || qformat.equals("")) {
1405
                    // if equals "", that means no qformat is specified. hence
1406
                    // by default the document should be returned in xml format
1407
                    // set content type first
1408
                    response.setContentType("text/xml"); //MIME type
1409
                    PrintWriter out = response.getWriter();
1410
                    doc.toXml(out, user, groups, withInlineData);
1411
                } else {
1412
                    response.setContentType("text/html"); //MIME type
1413
                    PrintWriter out = response.getWriter();
1414

    
1415
                    // Look up the document type
1416
                    String doctype = doc.getDoctype();
1417
                    // Transform the document to the new doctype
1418
                    DBTransform dbt = new DBTransform();
1419
                    dbt.transformXMLDocument(doc.toString(user, groups,
1420
                            withInlineData), doctype, "-//W3C//HTML//EN",
1421
                            qformat, out, params);
1422
                }
1423

    
1424
            }
1425
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1426
                    docid, "read");
1427
        } catch (Exception except) {
1428
            throw except;
1429
        }
1430
    }
1431

    
1432
    /**
1433
     * read data from URLConnection
1434
     */
1435
    private void readFromURLConnection(HttpServletResponse response,
1436
            String docid) throws IOException, MalformedURLException
1437
    {
1438
        ServletOutputStream out = response.getOutputStream();
1439
        String contentType = getServletContext().getMimeType(docid); //MIME
1440
                                                                     // type
1441
        if (contentType == null) {
1442
            if (docid.endsWith(".xml")) {
1443
                contentType = "text/xml";
1444
            } else if (docid.endsWith(".css")) {
1445
                contentType = "text/css";
1446
            } else if (docid.endsWith(".dtd")) {
1447
                contentType = "text/plain";
1448
            } else if (docid.endsWith(".xsd")) {
1449
                contentType = "text/xml";
1450
            } else if (docid.endsWith("/")) {
1451
                contentType = "text/html";
1452
            } else {
1453
                File f = new File(docid);
1454
                if (f.isDirectory()) {
1455
                    contentType = "text/html";
1456
                } else {
1457
                    contentType = "application/octet-stream";
1458
                }
1459
            }
1460
        }
1461
        response.setContentType(contentType);
1462
        // if we decide to use "application/octet-stream" for all data returns
1463
        // response.setContentType("application/octet-stream");
1464

    
1465
        // this is http url
1466
        URL url = new URL(docid);
1467
        BufferedInputStream bis = null;
1468
        try {
1469
            bis = new BufferedInputStream(url.openStream());
1470
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1471
            int b = bis.read(buf);
1472
            while (b != -1) {
1473
                out.write(buf, 0, b);
1474
                b = bis.read(buf);
1475
            }
1476
        } finally {
1477
            if (bis != null) bis.close();
1478
        }
1479

    
1480
    }
1481

    
1482
    /**
1483
     * read file/doc and write to ZipOutputStream
1484
     *
1485
     * @param docid
1486
     * @param zout
1487
     * @param user
1488
     * @param groups
1489
     * @throws ClassNotFoundException
1490
     * @throws IOException
1491
     * @throws SQLException
1492
     * @throws McdbException
1493
     * @throws Exception
1494
     */
1495
    private void addDocToZip(HttpServletRequest request, String docid,
1496
            ZipOutputStream zout, String user, String[] groups) throws
1497
            ClassNotFoundException, IOException, SQLException, McdbException,
1498
            Exception
1499
    {
1500
        byte[] bytestring = null;
1501
        ZipEntry zentry = null;
1502

    
1503
        try {
1504
            URL url = new URL(docid);
1505

    
1506
            // this http url; read from URLConnection; add to zip
1507
            zentry = new ZipEntry(docid);
1508
            zout.putNextEntry(zentry);
1509
            BufferedInputStream bis = null;
1510
            try {
1511
                bis = new BufferedInputStream(url.openStream());
1512
                byte[] buf = new byte[4 * 1024]; // 4K buffer
1513
                int b = bis.read(buf);
1514
                while (b != -1) {
1515
                    zout.write(buf, 0, b);
1516
                    b = bis.read(buf);
1517
                }
1518
            } finally {
1519
                if (bis != null) bis.close();
1520
            }
1521
            zout.closeEntry();
1522

    
1523
        } catch (MalformedURLException mue) {
1524

    
1525
            // this is metacat doc (data file or metadata doc)
1526
            try {
1527
                DocumentImpl doc = new DocumentImpl(docid);
1528

    
1529
                //check the permission for read
1530
                if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1531
                    Exception e = new Exception("User " + user
1532
                            + " does not have "
1533
                            + "permission to read the document with the docid "
1534
                            + docid);
1535
                    throw e;
1536
                }
1537

    
1538
                if (doc.getRootNodeID() == 0) {
1539
                    // this is data file; add file to zip
1540
                    String filepath = MetaCatUtil.getOption("datafilepath");
1541
                    if (!filepath.endsWith("/")) {
1542
                        filepath += "/";
1543
                    }
1544
                    String filename = filepath + docid;
1545
                    FileInputStream fin = null;
1546
                    fin = new FileInputStream(filename);
1547
                    try {
1548

    
1549
                        zentry = new ZipEntry(docid);
1550
                        zout.putNextEntry(zentry);
1551
                        byte[] buf = new byte[4 * 1024]; // 4K buffer
1552
                        int b = fin.read(buf);
1553
                        while (b != -1) {
1554
                            zout.write(buf, 0, b);
1555
                            b = fin.read(buf);
1556
                        }
1557
                    } finally {
1558
                        if (fin != null) fin.close();
1559
                    }
1560
                    zout.closeEntry();
1561

    
1562
                } else {
1563
                    // this is metadata doc; add doc to zip
1564
                    bytestring = doc.toString().getBytes();
1565
                    zentry = new ZipEntry(docid + ".xml");
1566
                    zentry.setSize(bytestring.length);
1567
                    zout.putNextEntry(zentry);
1568
                    zout.write(bytestring, 0, bytestring.length);
1569
                    zout.closeEntry();
1570
                }
1571
                EventLog.getInstance().log(request.getRemoteAddr(), user,
1572
                        docid, "read");
1573
            } catch (Exception except) {
1574
                throw except;
1575
            }
1576
        }
1577
    }
1578

    
1579
    /**
1580
     * If metacat couldn't find a data file or document locally, it will read
1581
     * this docid from its home server. This is for the replication feature
1582
     */
1583
    private void readFromRemoteMetaCat(HttpServletResponse response,
1584
            String docid, String rev, String user, String password,
1585
            ServletOutputStream out, boolean zip, ZipOutputStream zout)
1586
            throws Exception
1587
    {
1588
        // Create a object of RemoteDocument, "" is for zipEntryPath
1589
        RemoteDocument remoteDoc = new RemoteDocument(docid, rev, user,
1590
                password, "");
1591
        String docType = remoteDoc.getDocType();
1592
        // Only read data file
1593
        if (docType.equals("BIN")) {
1594
            // If it is zip format
1595
            if (zip) {
1596
                remoteDoc.readDocumentFromRemoteServerByZip(zout);
1597
            } else {
1598
                if (out == null) {
1599
                    out = response.getOutputStream();
1600
                }
1601
                response.setContentType("application/octet-stream");
1602
                remoteDoc.readDocumentFromRemoteServer(out);
1603
            }
1604
        } else {
1605
            throw new Exception("Docid: " + docid + "." + rev
1606
                    + " couldn't find");
1607
        }
1608
    }
1609

    
1610
    /**
1611
     * Handle the database putdocument request and write an XML document to the
1612
     * database connection
1613
     */
1614
    private void handleInsertOrUpdateAction(HttpServletRequest request,
1615
            HttpServletResponse response, PrintWriter out, Hashtable params,
1616
            String user, String[] groups)
1617
    {
1618
        DBConnection dbConn = null;
1619
        int serialNumber = -1;
1620

    
1621
        if(params.get("docid") == null){
1622
            out.println("<?xml version=\"1.0\"?>");
1623
            out.println("<error>");
1624
            out.println("Docid not specified");
1625
            out.println("</error>");
1626
            return;
1627
        }
1628

    
1629
        try {
1630
            // Get the document indicated
1631
            String[] doctext = (String[]) params.get("doctext");
1632
            String pub = null;
1633
            if (params.containsKey("public")) {
1634
                pub = ((String[]) params.get("public"))[0];
1635
            }
1636

    
1637
            StringReader dtd = null;
1638
            if (params.containsKey("dtdtext")) {
1639
                String[] dtdtext = (String[]) params.get("dtdtext");
1640
                try {
1641
                    if (!dtdtext[0].equals("")) {
1642
                        dtd = new StringReader(dtdtext[0]);
1643
                    }
1644
                } catch (NullPointerException npe) {
1645
                }
1646
            }
1647

    
1648
            if(doctext == null){
1649
                out.println("<?xml version=\"1.0\"?>");
1650
                out.println("<error>");
1651
                out.println("Document text not submitted");
1652
                out.println("</error>");
1653
                return;
1654
            }
1655

    
1656
            StringReader xml = new StringReader(doctext[0]);
1657
            boolean validate = false;
1658
            DocumentImplWrapper documentWrapper = null;
1659
            try {
1660
                // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ...
1661
                // >
1662
                // in order to decide whether to use validation parser
1663
                validate = needDTDValidation(xml);
1664
                if (validate) {
1665
                    // set a dtd base validation parser
1666
                    String rule = DocumentImpl.DTD;
1667
                    documentWrapper = new DocumentImplWrapper(rule, validate);
1668
                } else if (needSchemaValidation(xml)) {
1669
                    // for eml2
1670
                    String namespace = findNamespace(xml);
1671
                    if (namespace.compareTo(DocumentImpl.EML2_0_0NAMESPACE) == 0
1672
                                || namespace.compareTo(
1673
                                DocumentImpl.EML2_0_1NAMESPACE) == 0) {
1674
                        // set eml2 base validation parser
1675
                        String rule = DocumentImpl.EML200;
1676
                        // using emlparser to check id validation
1677
                        EMLParser parser = new EMLParser(doctext[0]);
1678
                        documentWrapper = new DocumentImplWrapper(rule, true);
1679
                    } else if (namespace.compareTo(
1680
                                DocumentImpl.EML2_1_0NAMESPACE) == 0) {
1681
                        // set eml2 base validation parser
1682
                        String rule = DocumentImpl.EML210;
1683
                        // using emlparser to check id validation
1684
                        EMLParser parser = new EMLParser(doctext[0]);
1685
                        documentWrapper = new DocumentImplWrapper(rule, true);
1686
                    } else {
1687
                        // set schema base validation parser
1688
                        String rule = DocumentImpl.SCHEMA;
1689
                        documentWrapper = new DocumentImplWrapper(rule, true);
1690
                    }
1691
                } else {
1692
                    documentWrapper = new DocumentImplWrapper("", false);
1693
                }
1694

    
1695
                String[] action = (String[]) params.get("action");
1696
                String[] docid = (String[]) params.get("docid");
1697
                String newdocid = null;
1698

    
1699
                String doAction = null;
1700
                if (action[0].equals("insert")) {
1701
                    doAction = "INSERT";
1702
                } else if (action[0].equals("update")) {
1703
                    doAction = "UPDATE";
1704
                }
1705

    
1706
                try {
1707
                    // get a connection from the pool
1708
                    dbConn = DBConnectionPool
1709
                            .getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1710
                    serialNumber = dbConn.getCheckOutSerialNumber();
1711

    
1712
                    // write the document to the database
1713
                    try {
1714
                        String accNumber = docid[0];
1715
                        MetaCatUtil.debugMessage("" + doAction + " "
1716
                                + accNumber + "...", 10);
1717
                        if (accNumber.equals("")) {
1718
                            accNumber = null;
1719
                        }
1720
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1721
                                doAction, accNumber, user, groups);
1722
                        EventLog.getInstance().log(request.getRemoteAddr(),
1723
                                user, accNumber, action[0]);
1724
                    } catch (NullPointerException npe) {
1725
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1726
                                doAction, null, user, groups);
1727
                        EventLog.getInstance().log(request.getRemoteAddr(),
1728
                                user, "", action[0]);
1729
                    }
1730
                }
1731
                finally {
1732
                    // Return db connection
1733
                    DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1734
                }
1735

    
1736
                // set content type and other response header fields first
1737
                //response.setContentType("text/xml");
1738
                out.println("<?xml version=\"1.0\"?>");
1739
                out.println("<success>");
1740
                out.println("<docid>" + newdocid + "</docid>");
1741
                out.println("</success>");
1742

    
1743
            } catch (NullPointerException npe) {
1744
                //response.setContentType("text/xml");
1745
                out.println("<?xml version=\"1.0\"?>");
1746
                out.println("<error>");
1747
                out.println(npe.getMessage());
1748
                out.println("</error>");
1749
            }
1750
        } catch (Exception e) {
1751
            //response.setContentType("text/xml");
1752
            out.println("<?xml version=\"1.0\"?>");
1753
            out.println("<error>");
1754
            out.println(e.getMessage());
1755
            out.println("</error>");
1756
        }
1757
    }
1758

    
1759
    /**
1760
     * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... > in
1761
     * order to decide whether to use validation parser
1762
     */
1763
    private static boolean needDTDValidation(StringReader xmlreader)
1764
            throws IOException
1765
    {
1766

    
1767
        StringBuffer cbuff = new StringBuffer();
1768
        java.util.Stack st = new java.util.Stack();
1769
        boolean validate = false;
1770
        int c;
1771
        int inx;
1772

    
1773
        // read from the stream until find the keywords
1774
        while ((st.empty() || st.size() < 4) && ((c = xmlreader.read()) != -1)) {
1775
            cbuff.append((char) c);
1776

    
1777
            // "<!DOCTYPE" keyword is found; put it in the stack
1778
            if ((inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1) {
1779
                cbuff = new StringBuffer();
1780
                st.push("<!DOCTYPE");
1781
            }
1782
            // "PUBLIC" keyword is found; put it in the stack
1783
            if ((inx = cbuff.toString().indexOf("PUBLIC")) != -1) {
1784
                cbuff = new StringBuffer();
1785
                st.push("PUBLIC");
1786
            }
1787
            // "SYSTEM" keyword is found; put it in the stack
1788
            if ((inx = cbuff.toString().indexOf("SYSTEM")) != -1) {
1789
                cbuff = new StringBuffer();
1790
                st.push("SYSTEM");
1791
            }
1792
            // ">" character is found; put it in the stack
1793
            // ">" is found twice: fisrt from <?xml ...?>
1794
            // and second from <!DOCTYPE ... >
1795
            if ((inx = cbuff.toString().indexOf(">")) != -1) {
1796
                cbuff = new StringBuffer();
1797
                st.push(">");
1798
            }
1799
        }
1800

    
1801
        // close the stream
1802
        xmlreader.reset();
1803

    
1804
        // check the stack whether it contains the keywords:
1805
        // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1806
        if (st.size() == 4) {
1807
            if (((String) st.pop()).equals(">")
1808
                    && (((String) st.peek()).equals("PUBLIC") | ((String) st
1809
                            .pop()).equals("SYSTEM"))
1810
                    && ((String) st.pop()).equals("<!DOCTYPE")) {
1811
                validate = true;
1812
            }
1813
        }
1814

    
1815
        MetaCatUtil.debugMessage("Validation for dtd is " + validate, 10);
1816
        return validate;
1817
    }
1818

    
1819
    // END OF INSERT/UPDATE SECTION
1820

    
1821
    /* check if the xml string contains key words to specify schema loocation */
1822
    private boolean needSchemaValidation(StringReader xml) throws IOException
1823
    {
1824
        boolean needSchemaValidate = false;
1825
        if (xml == null) {
1826
            MetaCatUtil.debugMessage("Validation for schema is "
1827
                    + needSchemaValidate, 10);
1828
            return needSchemaValidate;
1829
        }
1830
        System.out.println("before get target line");
1831
        String targetLine = getSchemaLine(xml);
1832
        System.out.println("after get target line");
1833
        // to see if the second line contain some keywords
1834
        if (targetLine != null
1835
                && (targetLine.indexOf(SCHEMALOCATIONKEYWORD) != -1 || targetLine
1836
                        .indexOf(NONAMESPACELOCATION) != -1)) {
1837
            // if contains schema location key word, should be validate
1838
            needSchemaValidate = true;
1839
        }
1840

    
1841
        MetaCatUtil.debugMessage("Validation for schema is "
1842
                + needSchemaValidate, 10);
1843
        return needSchemaValidate;
1844

    
1845
    }
1846

    
1847
    /* check if the xml string contains key words to specify schema loocation */
1848
    private String findNamespace(StringReader xml) throws IOException
1849
    {
1850
        String namespace = null;
1851

    
1852
        String eml2_0_0NameSpace = DocumentImpl.EML2_0_0NAMESPACE;
1853
        String eml2_0_1NameSpace = DocumentImpl.EML2_0_1NAMESPACE;
1854
        String eml2_1_0NameSpace = DocumentImpl.EML2_1_0NAMESPACE;
1855

    
1856
        if (xml == null) {
1857
            MetaCatUtil.debugMessage("Validation for schema is "
1858
                    + namespace, 10);
1859
            return namespace;
1860
        }
1861
        String targetLine = getSchemaLine(xml);
1862

    
1863
        if (targetLine != null) {
1864

    
1865
            int startIndex = targetLine.indexOf(SCHEMALOCATIONKEYWORD);
1866
            int start = 1;
1867
            int end = 1;
1868
            String schemaLocation = null;
1869
            int count = 0;
1870
            if (startIndex != -1) {
1871
                for (int i = startIndex; i < targetLine.length(); i++) {
1872
                    if (targetLine.charAt(i) == '"') {
1873
                        count++;
1874
                    }
1875
                    if (targetLine.charAt(i) == '"' && count == 1) {
1876
                        start = i;
1877
                    }
1878
                    if (targetLine.charAt(i) == '"' && count == 2) {
1879
                        end = i;
1880
                        break;
1881
                    }
1882
                }
1883
            }
1884
            schemaLocation = targetLine.substring(start + 1, end);
1885
            MetaCatUtil.debugMessage("schemaLocation in xml is: "
1886
                    + schemaLocation, 30);
1887
            if (schemaLocation.indexOf(eml2_0_0NameSpace) != -1) {
1888
                namespace = eml2_0_0NameSpace;
1889
            } else if (schemaLocation.indexOf(eml2_0_1NameSpace) != -1) {
1890
                namespace = eml2_0_1NameSpace;
1891
            } else if (schemaLocation.indexOf(eml2_1_0NameSpace) != -1) {
1892
                namespace = eml2_1_0NameSpace;
1893
            }
1894
        }
1895

    
1896
        MetaCatUtil.debugMessage("Validation for eml is " + namespace,
1897
                10);
1898

    
1899
        return namespace;
1900

    
1901
    }
1902

    
1903
    private String getSchemaLine(StringReader xml) throws IOException
1904
    {
1905
        // find the line
1906
        String secondLine = null;
1907
        int count = 0;
1908
        int endIndex = 0;
1909
        int startIndex = 0;
1910
        final int TARGETNUM = 2;
1911
        StringBuffer buffer = new StringBuffer();
1912
        boolean comment = false;
1913
        char thirdPreviousCharacter = '?';
1914
        char secondPreviousCharacter = '?';
1915
        char previousCharacter = '?';
1916
        char currentCharacter = '?';
1917
        int tmp = xml.read();
1918
        while (tmp != -1) {
1919
            currentCharacter = (char)tmp;
1920
            //in a comment
1921
            if (currentCharacter == '-' && previousCharacter == '-'
1922
                    && secondPreviousCharacter == '!'
1923
                    && thirdPreviousCharacter == '<') {
1924
                comment = true;
1925
            }
1926
            //out of comment
1927
            if (comment && currentCharacter == '>' && previousCharacter == '-'
1928
                    && secondPreviousCharacter == '-') {
1929
                comment = false;
1930
            }
1931

    
1932
            //this is not comment
1933
            if (currentCharacter != '!' && previousCharacter == '<' && !comment) {
1934
                count++;
1935
            }
1936
            // get target line
1937
            if (count == TARGETNUM && currentCharacter != '>') {
1938
                buffer.append(currentCharacter);
1939
            }
1940
            if (count == TARGETNUM && currentCharacter == '>') {
1941
                break;
1942
            }
1943
            thirdPreviousCharacter = secondPreviousCharacter;
1944
            secondPreviousCharacter = previousCharacter;
1945
            previousCharacter = currentCharacter;
1946
            tmp = xml.read();
1947
        }
1948
        secondLine = buffer.toString();
1949
        MetaCatUtil
1950
                .debugMessage("the second line string is: " + secondLine, 25);
1951
        xml.reset();
1952
        return secondLine;
1953
    }
1954

    
1955
    /**
1956
     * Handle the database delete request and delete an XML document from the
1957
     * database connection
1958
     */
1959
    private void handleDeleteAction(PrintWriter out, Hashtable params,
1960
            HttpServletRequest request, HttpServletResponse response,
1961
            String user, String[] groups)
1962
    {
1963

    
1964
        String[] docid = (String[]) params.get("docid");
1965

    
1966
        if(docid == null){
1967
          response.setContentType("text/xml");
1968
          out.println("<?xml version=\"1.0\"?>");
1969
          out.println("<error>");
1970
          out.println("Docid not specified.");
1971
          out.println("</error>");
1972
        } else {
1973

    
1974
            // delete the document from the database
1975
            try {
1976

    
1977
                try {
1978
                    // null means notify server is null
1979
                    DocumentImpl.delete(docid[0], user, groups, null);
1980
                    EventLog.getInstance().log(request.getRemoteAddr(),
1981
                                               user, docid[0], "delete");
1982
                    response.setContentType("text/xml");
1983
                    out.println("<?xml version=\"1.0\"?>");
1984
                    out.println("<success>");
1985
                    out.println("Document deleted.");
1986
                    out.println("</success>");
1987
                }
1988
                catch (AccessionNumberException ane) {
1989
                    response.setContentType("text/xml");
1990
                    out.println("<?xml version=\"1.0\"?>");
1991
                    out.println("<error>");
1992
                    //out.println("Error deleting document!!!");
1993
                    out.println(ane.getMessage());
1994
                    out.println("</error>");
1995
                }
1996
            }
1997
            catch (Exception e) {
1998
                response.setContentType("text/xml");
1999
                out.println("<?xml version=\"1.0\"?>");
2000
                out.println("<error>");
2001
                out.println(e.getMessage());
2002
                out.println("</error>");
2003
            }
2004
        }
2005
    }
2006

    
2007
    /**
2008
     * Handle the validation request and return the results to the requestor
2009
     */
2010
    private void handleValidateAction(PrintWriter out, Hashtable params)
2011
    {
2012

    
2013
        // Get the document indicated
2014
        String valtext = null;
2015
        DBConnection dbConn = null;
2016
        int serialNumber = -1;
2017

    
2018
        try {
2019
            valtext = ((String[]) params.get("valtext"))[0];
2020
        } catch (Exception nullpe) {
2021

    
2022
            String docid = null;
2023
            try {
2024
                // Find the document id number
2025
                docid = ((String[]) params.get("docid"))[0];
2026

    
2027
                // Get the document indicated from the db
2028
                DocumentImpl xmldoc = new DocumentImpl(docid);
2029
                valtext = xmldoc.toString();
2030

    
2031
            } catch (NullPointerException npe) {
2032

    
2033
                out.println("<error>Error getting document ID: " + docid
2034
                        + "</error>");
2035
                //if ( conn != null ) { util.returnConnection(conn); }
2036
                return;
2037
            } catch (Exception e) {
2038

    
2039
                out.println(e.getMessage());
2040
            }
2041
        }
2042

    
2043
        try {
2044
            // get a connection from the pool
2045
            dbConn = DBConnectionPool
2046
                    .getDBConnection("MetaCatServlet.handleValidateAction");
2047
            serialNumber = dbConn.getCheckOutSerialNumber();
2048
            DBValidate valobj = new DBValidate(saxparser, dbConn);
2049
            boolean valid = valobj.validateString(valtext);
2050

    
2051
            // set content type and other response header fields first
2052

    
2053
            out.println(valobj.returnErrors());
2054

    
2055
        } catch (NullPointerException npe2) {
2056
            // set content type and other response header fields first
2057

    
2058
            out.println("<error>Error validating document.</error>");
2059
        } catch (Exception e) {
2060

    
2061
            out.println(e.getMessage());
2062
        } finally {
2063
            // Return db connection
2064
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2065
        }
2066
    }
2067

    
2068
    /**
2069
     * Handle "getrevsionanddoctype" action Given a docid, return it's current
2070
     * revision and doctype from data base The output is String look like
2071
     * "rev;doctype"
2072
     */
2073
    private void handleGetRevisionAndDocTypeAction(PrintWriter out,
2074
            Hashtable params)
2075
    {
2076
        // To store doc parameter
2077
        String[] docs = new String[10];
2078
        // Store a single doc id
2079
        String givenDocId = null;
2080
        // Get docid from parameters
2081
        if (params.containsKey("docid")) {
2082
            docs = (String[]) params.get("docid");
2083
        }
2084
        // Get first docid form string array
2085
        givenDocId = docs[0];
2086

    
2087
        try {
2088
            // Make sure there is a docid
2089
            if (givenDocId == null || givenDocId.equals("")) { throw new Exception(
2090
                    "User didn't specify docid!"); }//if
2091

    
2092
            // Create a DBUtil object
2093
            DBUtil dbutil = new DBUtil();
2094
            // Get a rev and doctype
2095
            String revAndDocType = dbutil
2096
                    .getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
2097
            out.println(revAndDocType);
2098

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

    
2107
    }
2108

    
2109
    /**
2110
     * Handle "getaccesscontrol" action. Read Access Control List from db
2111
     * connection in XML format
2112
     */
2113
    private void handleGetAccessControlAction(PrintWriter out,
2114
            Hashtable params, HttpServletResponse response, String username,
2115
            String[] groupnames)
2116
    {
2117
        DBConnection dbConn = null;
2118
        int serialNumber = -1;
2119
        String docid = ((String[]) params.get("docid"))[0];
2120

    
2121
        try {
2122

    
2123
            // get connection from the pool
2124
            dbConn = DBConnectionPool
2125
                    .getDBConnection("MetaCatServlet.handleGetAccessControlAction");
2126
            serialNumber = dbConn.getCheckOutSerialNumber();
2127
            AccessControlList aclobj = new AccessControlList(dbConn);
2128
            String acltext = aclobj.getACL(docid, username, groupnames);
2129
            out.println(acltext);
2130

    
2131
        } catch (Exception e) {
2132
            out.println("<?xml version=\"1.0\"?>");
2133
            out.println("<error>");
2134
            out.println(e.getMessage());
2135
            out.println("</error>");
2136
        } finally {
2137
            // Retrun db connection to pool
2138
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2139
        }
2140
    }
2141

    
2142
    /**
2143
     * Handle the "getprincipals" action. Read all principals from
2144
     * authentication scheme in XML format
2145
     */
2146
    private void handleGetPrincipalsAction(PrintWriter out, String user,
2147
            String password)
2148
    {
2149
        try {
2150
            AuthSession auth = new AuthSession();
2151
            String principals = auth.getPrincipals(user, password);
2152
            out.println(principals);
2153

    
2154
        } catch (Exception e) {
2155
            out.println("<?xml version=\"1.0\"?>");
2156
            out.println("<error>");
2157
            out.println(e.getMessage());
2158
            out.println("</error>");
2159
        }
2160
    }
2161

    
2162
    /**
2163
     * Handle "getdoctypes" action. Read all doctypes from db connection in XML
2164
     * format
2165
     */
2166
    private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
2167
            HttpServletResponse response)
2168
    {
2169
        try {
2170
            DBUtil dbutil = new DBUtil();
2171
            String doctypes = dbutil.readDoctypes();
2172
            out.println(doctypes);
2173
        } catch (Exception e) {
2174
            out.println("<?xml version=\"1.0\"?>");
2175
            out.println("<error>");
2176
            out.println(e.getMessage());
2177
            out.println("</error>");
2178
        }
2179
    }
2180

    
2181
    /**
2182
     * Handle the "getdtdschema" action. Read DTD or Schema file for a given
2183
     * doctype from Metacat catalog system
2184
     */
2185
    private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
2186
            HttpServletResponse response)
2187
    {
2188

    
2189
        String doctype = null;
2190
        String[] doctypeArr = (String[]) params.get("doctype");
2191

    
2192
        // get only the first doctype specified in the list of doctypes
2193
        // it could be done for all doctypes in that list
2194
        if (doctypeArr != null) {
2195
            doctype = ((String[]) params.get("doctype"))[0];
2196
        }
2197

    
2198
        try {
2199
            DBUtil dbutil = new DBUtil();
2200
            String dtdschema = dbutil.readDTDSchema(doctype);
2201
            out.println(dtdschema);
2202

    
2203
        } catch (Exception e) {
2204
            out.println("<?xml version=\"1.0\"?>");
2205
            out.println("<error>");
2206
            out.println(e.getMessage());
2207
            out.println("</error>");
2208
        }
2209

    
2210
    }
2211

    
2212
    /**
2213
     * Handle the "getlastdocid" action. Get the latest docid with rev number
2214
     * from db connection in XML format
2215
     */
2216
    private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
2217
            HttpServletResponse response)
2218
    {
2219

    
2220
        String scope = ((String[]) params.get("scope"))[0];
2221
        if (scope == null) {
2222
            scope = ((String[]) params.get("username"))[0];
2223
        }
2224

    
2225
        try {
2226

    
2227
            DBUtil dbutil = new DBUtil();
2228
            String lastDocid = dbutil.getMaxDocid(scope);
2229
            out.println("<?xml version=\"1.0\"?>");
2230
            out.println("<lastDocid>");
2231
            out.println("  <scope>" + scope + "</scope>");
2232
            out.println("  <docid>" + lastDocid + "</docid>");
2233
            out.println("</lastDocid>");
2234

    
2235
        } catch (Exception e) {
2236
            out.println("<?xml version=\"1.0\"?>");
2237
            out.println("<error>");
2238
            out.println(e.getMessage());
2239
            out.println("</error>");
2240
        }
2241
    }
2242

    
2243
    /**
2244
     * Print a report from the event log based on filter parameters passed in
2245
     * from the web.
2246
     *
2247
     * @param params the parameters from the web request
2248
     * @param request the http request object for getting request details
2249
     * @param response the http response object for writing output
2250
     */
2251
    private void handleGetLogAction(Hashtable params, HttpServletRequest request,
2252
            HttpServletResponse response, String username, String[] groups)
2253
    {
2254
        try {
2255
            response.setContentType("text/xml");
2256
            PrintWriter out = response.getWriter();
2257

    
2258
            // Check that the user is authenticated as an administrator account
2259
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2260
                out.print("<error>");
2261
                out.print("The user \"" + username +
2262
                        "\" is not authorized for this action.");
2263
                out.print("</error>");
2264
                return;
2265
            }
2266

    
2267
            // Get all of the parameters in the correct formats
2268
            String[] ipAddress = (String[])params.get("ipaddress");
2269
            String[] principal = (String[])params.get("principal");
2270
            String[] docid = (String[])params.get("docid");
2271
            String[] event = (String[])params.get("event");
2272
            String[] startArray = (String[]) params.get("start");
2273
            String[] endArray = (String[]) params.get("end");
2274
            String start = null;
2275
            String end = null;
2276
            if (startArray != null) {
2277
                start = startArray[0];
2278
            }
2279
            if (endArray != null) {
2280
                end = endArray[0];
2281
            }
2282
            Timestamp startDate = null;
2283
            Timestamp endDate = null;
2284
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2285
            try {
2286
                if (start != null) {
2287
                    startDate = new Timestamp((format.parse(start)).getTime());
2288
                }
2289
                if (end != null) {
2290
                    endDate = new Timestamp((format.parse(end)).getTime());
2291
                }
2292
            } catch (ParseException e) {
2293
                System.out.println("Failed to created Timestamp from input.");
2294
            }
2295

    
2296
            // Request the report by passing the filter parameters
2297
            out.println(EventLog.getInstance().getReport(ipAddress, principal,
2298
                    docid, event, startDate, endDate));
2299
            out.close();
2300
        } catch (IOException e) {
2301
            MetaCatUtil.debugMessage(
2302
                    "Could not open http response for writing: " + e.getMessage(), 5);
2303
        }
2304
    }
2305

    
2306
    /**
2307
     * Rebuild the index for one or more documents. If the docid parameter is
2308
     * provided, rebuild for just that one document or list of documents. If
2309
     * not, then rebuild the index for all documents in the xml_documents
2310
     * table.
2311
     *
2312
     * @param params the parameters from the web request
2313
     * @param request the http request object for getting request details
2314
     * @param response the http response object for writing output
2315
     * @param username the username of the authenticated user
2316
     */
2317
    private void handleBuildIndexAction(Hashtable params,
2318
            HttpServletRequest request, HttpServletResponse response,
2319
            String username, String[] groups)
2320
    {
2321
        // Get all of the parameters in the correct formats
2322
        String[] docid = (String[])params.get("docid");
2323

    
2324
        // Rebuild the indices for appropriate documents
2325
        try {
2326
            response.setContentType("text/xml");
2327
            PrintWriter out = response.getWriter();
2328

    
2329
            // Check that the user is authenticated as an administrator account
2330
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2331
                out.print("<error>");
2332
                out.print("The user \"" + username +
2333
                        "\" is not authorized for this action.");
2334
                out.print("</error>");
2335
                return;
2336
            }
2337

    
2338
            // Process the documents
2339
            out.println("<success>");
2340
            if (docid == null || docid.length == 0) {
2341
                // Process all of the documents
2342
                try {
2343
                    Vector documents = getDocumentList();
2344
                    Iterator it = documents.iterator();
2345
                    while (it.hasNext()) {
2346
                        String id = (String) it.next();
2347
                        buildDocumentIndex(id, out);
2348
                    }
2349
                } catch (SQLException se) {
2350
                    out.print("<error>");
2351
                    out.print(se.getMessage());
2352
                    out.println("</error>");
2353
                }
2354
            } else {
2355
                // Only process the requested documents
2356
                for (int i = 0; i < docid.length; i++) {
2357
                    buildDocumentIndex(docid[i], out);
2358
                }
2359
            }
2360
            out.println("</success>");
2361
            out.close();
2362
        } catch (IOException e) {
2363
            MetaCatUtil.debugMessage(
2364
                    "Could not open http response for writing: "
2365
                    + e.getMessage(), 5);
2366
        }
2367
    }
2368

    
2369
    /**
2370
     * Build the index for one document by reading the document and
2371
     * calling its buildIndex() method.
2372
     *
2373
     * @param docid the document (with revision) to rebuild
2374
     * @param out the PrintWriter to which output is printed
2375
     */
2376
    private void buildDocumentIndex(String docid, PrintWriter out)
2377
    {
2378
        try {
2379
            DocumentImpl doc = new DocumentImpl(docid, false);
2380
            doc.buildIndex();
2381
            out.print("<docid>" + docid);
2382
            out.println("</docid>");
2383
        } catch (McdbException me) {
2384
            out.print("<error>");
2385
            out.print(me.getMessage());
2386
            out.println("</error>");
2387
        }
2388
    }
2389

    
2390
    /**
2391
     * Handle documents passed to metacat that are encoded using the
2392
     * "multipart/form-data" mime type. This is typically used for uploading
2393
     * data files which may be binary and large.
2394
     */
2395
    private void handleMultipartForm(HttpServletRequest request,
2396
            HttpServletResponse response)
2397
    {
2398
        PrintWriter out = null;
2399
        String action = null;
2400

    
2401
        // Parse the multipart form, and save the parameters in a Hashtable and
2402
        // save the FileParts in a hashtable
2403

    
2404
        Hashtable params = new Hashtable();
2405
        Hashtable fileList = new Hashtable();
2406
        int sizeLimit = (new Integer(MetaCatUtil.getOption("datafilesizelimit")))
2407
                .intValue();
2408
        MetaCatUtil.debugMessage(
2409
                "The limit size of data file is: " + sizeLimit, 50);
2410

    
2411
        try {
2412
            // MBJ: need to put filesize limit in Metacat config
2413
            // (metacat.properties)
2414
            MultipartParser mp = new MultipartParser(request,
2415
                    sizeLimit * 1024 * 1024);
2416
            Part part;
2417
            while ((part = mp.readNextPart()) != null) {
2418
                String name = part.getName();
2419

    
2420
                if (part.isParam()) {
2421
                    // it's a parameter part
2422
                    ParamPart paramPart = (ParamPart) part;
2423
                    String value = paramPart.getStringValue();
2424
                    params.put(name, value);
2425
                    if (name.equals("action")) {
2426
                        action = value;
2427
                    }
2428
                } else if (part.isFile()) {
2429
                    // it's a file part
2430
                    FilePart filePart = (FilePart) part;
2431
                    fileList.put(name, filePart);
2432

    
2433
                    // Stop once the first file part is found, otherwise going
2434
                    // onto the
2435
                    // next part prevents access to the file contents. So...for
2436
                    // upload
2437
                    // to work, the datafile must be the last part
2438
                    break;
2439
                }
2440
            }
2441
        } catch (IOException ioe) {
2442
            try {
2443
                out = response.getWriter();
2444
            } catch (IOException ioe2) {
2445
                System.err
2446
                        .println("Fatal Error: couldn't get response output stream.");
2447
            }
2448
            out.println("<?xml version=\"1.0\"?>");
2449
            out.println("<error>");
2450
            out.println("Error: problem reading multipart data.");
2451
            out.println("</error>");
2452
        }
2453

    
2454
        // Get the session information
2455
        String username = null;
2456
        String password = null;
2457
        String[] groupnames = null;
2458
        String sess_id = null;
2459

    
2460
        // be aware of session expiration on every request
2461
        HttpSession sess = request.getSession(true);
2462
        if (sess.isNew()) {
2463
            // session expired or has not been stored b/w user requests
2464
            username = "public";
2465
            sess.setAttribute("username", username);
2466
        } else {
2467
            username = (String) sess.getAttribute("username");
2468
            password = (String) sess.getAttribute("password");
2469
            groupnames = (String[]) sess.getAttribute("groupnames");
2470
            try {
2471
                sess_id = (String) sess.getId();
2472
            } catch (IllegalStateException ise) {
2473
                System.out
2474
                        .println("error in  handleMultipartForm: this shouldn't "
2475
                                + "happen: the session should be valid: "
2476
                                + ise.getMessage());
2477
            }
2478
        }
2479

    
2480
        // Get the out stream
2481
        try {
2482
            out = response.getWriter();
2483
        } catch (IOException ioe2) {
2484
            MetaCatUtil.debugMessage("Fatal Error: couldn't get response "
2485
                    + "output stream.", 30);
2486
        }
2487

    
2488
        if (action.equals("upload")) {
2489
            if (username != null && !username.equals("public")) {
2490
                handleUploadAction(request, out, params, fileList, username,
2491
                        groupnames);
2492
            } else {
2493

    
2494
                out.println("<?xml version=\"1.0\"?>");
2495
                out.println("<error>");
2496
                out.println("Permission denied for " + action);
2497
                out.println("</error>");
2498
            }
2499
        } else {
2500
            /*
2501
             * try { out = response.getWriter(); } catch (IOException ioe2) {
2502
             * System.err.println("Fatal Error: couldn't get response output
2503
             * stream.");
2504
             */
2505
            out.println("<?xml version=\"1.0\"?>");
2506
            out.println("<error>");
2507
            out.println(
2508
                    "Error: action not registered.  Please report this error.");
2509
            out.println("</error>");
2510
        }
2511
        out.close();
2512
    }
2513

    
2514
    /**
2515
     * Handle the upload action by saving the attached file to disk and
2516
     * registering it in the Metacat db
2517
     */
2518
    private void handleUploadAction(HttpServletRequest request,
2519
            PrintWriter out, Hashtable params, Hashtable fileList,
2520
            String username, String[] groupnames)
2521
    {
2522
        //PrintWriter out = null;
2523
        //Connection conn = null;
2524
        String action = null;
2525
        String docid = null;
2526

    
2527
        /*
2528
         * response.setContentType("text/xml"); try { out =
2529
         * response.getWriter(); } catch (IOException ioe2) {
2530
         * System.err.println("Fatal Error: couldn't get response output
2531
         * stream.");
2532
         */
2533

    
2534
        if (params.containsKey("docid")) {
2535
            docid = (String) params.get("docid");
2536
        }
2537

    
2538
        // Make sure we have a docid and datafile
2539
        if (docid != null && fileList.containsKey("datafile")) {
2540

    
2541
            // Get a reference to the file part of the form
2542
            FilePart filePart = (FilePart) fileList.get("datafile");
2543
            String fileName = filePart.getFileName();
2544
            MetaCatUtil.debugMessage("Uploading filename: " + fileName, 10);
2545

    
2546
            // Check if the right file existed in the uploaded data
2547
            if (fileName != null) {
2548

    
2549
                try {
2550
                    //MetaCatUtil.debugMessage("Upload datafile " + docid
2551
                    // +"...", 10);
2552
                    //If document get lock data file grant
2553
                    if (DocumentImpl.getDataFileLockGrant(docid)) {
2554
                        // register the file in the database (which generates
2555
                        // an exception
2556
                        //if the docid is not acceptable or other untoward
2557
                        // things happen
2558
                        DocumentImpl.registerDocument(fileName, "BIN", docid,
2559
                                username, groupnames);
2560

    
2561
                        // Save the data file to disk using "docid" as the name
2562
                        dataDirectory.mkdirs();
2563
                        File newFile = new File(dataDirectory, docid);
2564
                        long size = filePart.writeTo(newFile);
2565

    
2566
                        EventLog.getInstance().log(request.getRemoteAddr(),
2567
                                username, docid, "upload");
2568
                        // Force replication this data file
2569
                        // To data file, "insert" and update is same
2570
                        // The fourth parameter is null. Because it is
2571
                        // notification server
2572
                        // and this method is in MetaCatServerlet. It is
2573
                        // original command,
2574
                        // not get force replication info from another metacat
2575
                        ForceReplicationHandler frh = new ForceReplicationHandler(
2576
                                docid, "insert", false, null);
2577

    
2578
                        // set content type and other response header fields
2579
                        // first
2580
                        out.println("<?xml version=\"1.0\"?>");
2581
                        out.println("<success>");
2582
                        out.println("<docid>" + docid + "</docid>");
2583
                        out.println("<size>" + size + "</size>");
2584
                        out.println("</success>");
2585
                    }
2586

    
2587
                } catch (Exception e) {
2588
                    out.println("<?xml version=\"1.0\"?>");
2589
                    out.println("<error>");
2590
                    out.println(e.getMessage());
2591
                    out.println("</error>");
2592
                }
2593
            } else {
2594
                // the field did not contain a file
2595
                out.println("<?xml version=\"1.0\"?>");
2596
                out.println("<error>");
2597
                out.println("The uploaded data did not contain a valid file.");
2598
                out.println("</error>");
2599
            }
2600
        } else {
2601
            // Error bcse docid missing or file missing
2602
            out.println("<?xml version=\"1.0\"?>");
2603
            out.println("<error>");
2604
            out.println("The uploaded data did not contain a valid docid "
2605
                    + "or valid file.");
2606
            out.println("</error>");
2607
        }
2608
    }
2609

    
2610
    /*
2611
     * A method to handle set access action
2612
     */
2613
    private void handleSetAccessAction(PrintWriter out, Hashtable params,
2614
            String username)
2615
    {
2616
        String[] docList = null;
2617
        String[] principalList = null;
2618
        String[] permissionList = null;
2619
        String[] permTypeList = null;
2620
        String[] permOrderList = null;
2621
        String permission = null;
2622
        String permType = null;
2623
        String permOrder = null;
2624
        Vector errorList = new Vector();
2625
        String error = null;
2626
        Vector successList = new Vector();
2627
        String success = null;
2628

    
2629
        // Get parameters
2630
        if (params.containsKey("docid")) {
2631
            docList = (String[]) params.get("docid");
2632
        }
2633
        if (params.containsKey("principal")) {
2634
            principalList = (String[]) params.get("principal");
2635
        }
2636
        if (params.containsKey("permission")) {
2637
            permissionList = (String[]) params.get("permission");
2638

    
2639
        }
2640
        if (params.containsKey("permType")) {
2641
            permTypeList = (String[]) params.get("permType");
2642

    
2643
        }
2644
        if (params.containsKey("permOrder")) {
2645
            permOrderList = (String[]) params.get("permOrder");
2646

    
2647
        }
2648

    
2649
        // Make sure the parameter is not null
2650
        if (docList == null || principalList == null || permTypeList == null
2651
                || permissionList == null) {
2652
            error = "Please check your parameter list, it should look like: "
2653
                    + "?action=setaccess&docid=pipeline.1.1&principal=public"
2654
                    + "&permission=read&permType=allow&permOrder=allowFirst";
2655
            errorList.addElement(error);
2656
            outputResponse(successList, errorList, out);
2657
            return;
2658
        }
2659

    
2660
        // Only select first element for permission, type and order
2661
        permission = permissionList[0];
2662
        permType = permTypeList[0];
2663
        if (permOrderList != null) {
2664
            permOrder = permOrderList[0];
2665
        }
2666

    
2667
        // Get package doctype set
2668
        Vector packageSet = MetaCatUtil.getOptionList(MetaCatUtil
2669
                .getOption("packagedoctypeset"));
2670
        //debug
2671
        if (packageSet != null) {
2672
            for (int i = 0; i < packageSet.size(); i++) {
2673
                MetaCatUtil.debugMessage("doctype in package set: "
2674
                        + (String) packageSet.elementAt(i), 34);
2675
            }
2676
        }
2677

    
2678
        // handle every accessionNumber
2679
        for (int i = 0; i < docList.length; i++) {
2680
            String accessionNumber = docList[i];
2681
            String owner = null;
2682
            String publicId = null;
2683
            // Get document owner and public id
2684
            try {
2685
                owner = getFieldValueForDoc(accessionNumber, "user_owner");
2686
                publicId = getFieldValueForDoc(accessionNumber, "doctype");
2687
            } catch (Exception e) {
2688
                MetaCatUtil.debugMessage("Error in handleSetAccessAction: "
2689
                        + e.getMessage(), 30);
2690
                error = "Error in set access control for document - "
2691
                        + accessionNumber + e.getMessage();
2692
                errorList.addElement(error);
2693
                continue;
2694
            }
2695
            //check if user is the owner. Only owner can do owner
2696
            if (username == null || owner == null || !username.equals(owner)) {
2697
                error = "User - " + username
2698
                        + " does not have permission to set "
2699
                        + "access control for docid - " + accessionNumber;
2700
                errorList.addElement(error);
2701
                continue;
2702
            }
2703

    
2704
            // If docid publicid is BIN data file or other beta4, 6 package
2705
            // document
2706
            // we could not do set access control. Because we don't want
2707
            // inconsistent
2708
            // to its access docuemnt
2709
            if (publicId != null && packageSet != null
2710
                    && packageSet.contains(publicId)) {
2711
                error = "Could not set access control to document "
2712
                        + accessionNumber
2713
                        + "because it is in a pakcage and it has a access file for it";
2714
                errorList.addElement(error);
2715
                continue;
2716
            }
2717

    
2718
            // for every principle
2719
            for (int j = 0; j < principalList.length; j++) {
2720
                String principal = principalList[j];
2721
                try {
2722
                    //insert permission
2723
                    AccessControlForSingleFile accessControl = new AccessControlForSingleFile(
2724
                            accessionNumber, principal, permission, permType,
2725
                            permOrder);
2726
                    accessControl.insertPermissions();
2727
                    success = "Set access control to document "
2728
                            + accessionNumber + " successfully";
2729
                    successList.addElement(success);
2730
                } catch (Exception ee) {
2731
                    MetaCatUtil.debugMessage(
2732
                            "Erorr in handleSetAccessAction2: "
2733
                                    + ee.getMessage(), 30);
2734
                    error = "Faild to set access control for document "
2735
                            + accessionNumber + " because " + ee.getMessage();
2736
                    errorList.addElement(error);
2737
                    continue;
2738
                }
2739
            }
2740
        }
2741
        outputResponse(successList, errorList, out);
2742
    }
2743

    
2744
    /*
2745
     * A method try to determin a docid's public id, if couldn't find null will
2746
     * be returned.
2747
     */
2748
    private String getFieldValueForDoc(String accessionNumber, String fieldName)
2749
            throws Exception
2750
    {
2751
        if (accessionNumber == null || accessionNumber.equals("")
2752
                || fieldName == null || fieldName.equals("")) { throw new Exception(
2753
                "Docid or field name was not specified"); }
2754

    
2755
        PreparedStatement pstmt = null;
2756
        ResultSet rs = null;
2757
        String fieldValue = null;
2758
        String docId = null;
2759
        DBConnection conn = null;
2760
        int serialNumber = -1;
2761

    
2762
        // get rid of revision if access number has
2763
        docId = MetaCatUtil.getDocIdFromString(accessionNumber);
2764
        try {
2765
            //check out DBConnection
2766
            conn = DBConnectionPool
2767
                    .getDBConnection("MetaCatServlet.getPublicIdForDoc");
2768
            serialNumber = conn.getCheckOutSerialNumber();
2769
            pstmt = conn.prepareStatement("SELECT " + fieldName
2770
                    + " FROM xml_documents " + "WHERE docid = ? ");
2771

    
2772
            pstmt.setString(1, docId);
2773
            pstmt.execute();
2774
            rs = pstmt.getResultSet();
2775
            boolean hasRow = rs.next();
2776
            int perm = 0;
2777
            if (hasRow) {
2778
                fieldValue = rs.getString(1);
2779
            } else {
2780
                throw new Exception("Could not find document: "
2781
                        + accessionNumber);
2782
            }
2783
        } catch (Exception e) {
2784
            MetaCatUtil.debugMessage(
2785
                    "Exception in MetacatServlet.getPublicIdForDoc: "
2786
                            + e.getMessage(), 30);
2787
            throw e;
2788
        } finally {
2789
            try {
2790
                rs.close();
2791
                pstmt.close();
2792

    
2793
            } finally {
2794
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2795
            }
2796
        }
2797
        return fieldValue;
2798
    }
2799

    
2800
    /*
2801
     * Get the list of documents from the database and return the list in an
2802
     * Vector of identifiers.
2803
     *
2804
     * @ returns the array of identifiers
2805
     */
2806
    private Vector getDocumentList() throws SQLException
2807
    {
2808
        Vector docList = new Vector();
2809
        PreparedStatement pstmt = null;
2810
        ResultSet rs = null;
2811
        DBConnection conn = null;
2812
        int serialNumber = -1;
2813

    
2814
        try {
2815
            //check out DBConnection
2816
            conn = DBConnectionPool
2817
                    .getDBConnection("MetaCatServlet.getDocumentList");
2818
            serialNumber = conn.getCheckOutSerialNumber();
2819
            pstmt = conn.prepareStatement("SELECT docid, rev"
2820
                    + " FROM xml_documents ");
2821
            pstmt.execute();
2822
            rs = pstmt.getResultSet();
2823
            while (rs.next()) {
2824
                String docid = rs.getString(1);
2825
                String rev = rs.getString(2);
2826
                docList.add(docid + "." + rev);
2827
            }
2828
        } catch (SQLException e) {
2829
            MetaCatUtil.debugMessage(
2830
                    "Exception in MetacatServlet.getDocumentList: "
2831
                            + e.getMessage(), 30);
2832
            throw e;
2833
        } finally {
2834
            try {
2835
                rs.close();
2836
                pstmt.close();
2837

    
2838
            } catch (SQLException se) {
2839
                MetaCatUtil.debugMessage(
2840
                    "Exception in MetacatServlet.getDocumentList: "
2841
                            + se.getMessage(), 30);
2842
                throw se;
2843
            } finally {
2844
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2845
            }
2846
        }
2847
        return docList;
2848
    }
2849

    
2850
    /*
2851
     * A method to output setAccess action result
2852
     */
2853
    private void outputResponse(Vector successList, Vector errorList,
2854
            PrintWriter out)
2855
    {
2856
        boolean error = false;
2857
        boolean success = false;
2858
        // Output prolog
2859
        out.println(PROLOG);
2860
        // output success message
2861
        if (successList != null) {
2862
            for (int i = 0; i < successList.size(); i++) {
2863
                out.println(SUCCESS);
2864
                out.println((String) successList.elementAt(i));
2865
                out.println(SUCCESSCLOSE);
2866
                success = true;
2867
            }
2868
        }
2869
        // output error message
2870
        if (errorList != null) {
2871
            for (int i = 0; i < errorList.size(); i++) {
2872
                out.println(ERROR);
2873
                out.println((String) errorList.elementAt(i));
2874
                out.println(ERRORCLOSE);
2875
                error = true;
2876
            }
2877
        }
2878

    
2879
        // if no error and no success info, send a error that nothing happened
2880
        if (!error && !success) {
2881
            out.println(ERROR);
2882
            out.println("Nothing happend for setaccess action");
2883
            out.println(ERRORCLOSE);
2884
        }
2885
    }
2886
}
(42-42/63)