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: tao $'
10
 *     '$Date: 2005-09-09 10:42:17 -0700 (Fri, 09 Sep 2005) $'
11
 * '$Revision: 2582 $'
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 static 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
            MetaCatUtil.debugMessage("Docid not specified",10);
1627
            return;
1628
        }
1629
        
1630
        if(!MetaCatUtil.canInsertOrUpdate(user, groups)){
1631
        	out.println("<?xml version=\"1.0\"?>");
1632
            out.println("<error>");
1633
            out.println("User '" + user + "' not allowed to insert and update");
1634
            out.println("</error>");
1635
            MetaCatUtil.debugMessage("User '" + user + "' not allowed to insert and update",10);
1636
            return;
1637
        }
1638

    
1639
        try {
1640
            // Get the document indicated
1641
            String[] doctext = (String[]) params.get("doctext");
1642
            String pub = null;
1643
            if (params.containsKey("public")) {
1644
                pub = ((String[]) params.get("public"))[0];
1645
            }
1646

    
1647
            StringReader dtd = null;
1648
            if (params.containsKey("dtdtext")) {
1649
                String[] dtdtext = (String[]) params.get("dtdtext");
1650
                try {
1651
                    if (!dtdtext[0].equals("")) {
1652
                        dtd = new StringReader(dtdtext[0]);
1653
                    }
1654
                } catch (NullPointerException npe) {
1655
                }
1656
            }
1657

    
1658
            if(doctext == null){
1659
                out.println("<?xml version=\"1.0\"?>");
1660
                out.println("<error>");
1661
                out.println("Document text not submitted");
1662
                out.println("</error>");
1663
                return;
1664
            }
1665

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

    
1705
                String[] action = (String[]) params.get("action");
1706
                String[] docid = (String[]) params.get("docid");
1707
                String newdocid = null;
1708

    
1709
                String doAction = null;
1710
                if (action[0].equals("insert")) {
1711
                    doAction = "INSERT";
1712
                } else if (action[0].equals("update")) {
1713
                    doAction = "UPDATE";
1714
                }
1715

    
1716
                try {
1717
                    // get a connection from the pool
1718
                    dbConn = DBConnectionPool
1719
                            .getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1720
                    serialNumber = dbConn.getCheckOutSerialNumber();
1721

    
1722
                    // write the document to the database
1723
                    try {
1724
                        String accNumber = docid[0];
1725
                        MetaCatUtil.debugMessage("" + doAction + " "
1726
                                + accNumber + "...", 10);
1727
                        if (accNumber.equals("")) {
1728
                            accNumber = null;
1729
                        }
1730
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1731
                                doAction, accNumber, user, groups);
1732
                        EventLog.getInstance().log(request.getRemoteAddr(),
1733
                                user, accNumber, action[0]);
1734
                    } catch (NullPointerException npe) {
1735
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1736
                                doAction, null, user, groups);
1737
                        EventLog.getInstance().log(request.getRemoteAddr(),
1738
                                user, "", action[0]);
1739
                    }
1740
                }
1741
                finally {
1742
                    // Return db connection
1743
                    DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1744
                }
1745

    
1746
                // set content type and other response header fields first
1747
                //response.setContentType("text/xml");
1748
                out.println("<?xml version=\"1.0\"?>");
1749
                out.println("<success>");
1750
                out.println("<docid>" + newdocid + "</docid>");
1751
                out.println("</success>");
1752

    
1753
            } catch (NullPointerException npe) {
1754
                //response.setContentType("text/xml");
1755
                out.println("<?xml version=\"1.0\"?>");
1756
                out.println("<error>");
1757
                out.println(npe.getMessage());
1758
                out.println("</error>");
1759
            }
1760
        } catch (Exception e) {
1761
            //response.setContentType("text/xml");
1762
            out.println("<?xml version=\"1.0\"?>");
1763
            out.println("<error>");
1764
            out.println(e.getMessage());
1765
            out.println("</error>");
1766
        }
1767
    }
1768

    
1769
    /**
1770
     * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... > in
1771
     * order to decide whether to use validation parser
1772
     */
1773
    private static boolean needDTDValidation(StringReader xmlreader)
1774
            throws IOException
1775
    {
1776

    
1777
        StringBuffer cbuff = new StringBuffer();
1778
        java.util.Stack st = new java.util.Stack();
1779
        boolean validate = false;
1780
        int c;
1781
        int inx;
1782

    
1783
        // read from the stream until find the keywords
1784
        while ((st.empty() || st.size() < 4) && ((c = xmlreader.read()) != -1)) {
1785
            cbuff.append((char) c);
1786

    
1787
            // "<!DOCTYPE" keyword is found; put it in the stack
1788
            if ((inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1) {
1789
                cbuff = new StringBuffer();
1790
                st.push("<!DOCTYPE");
1791
            }
1792
            // "PUBLIC" keyword is found; put it in the stack
1793
            if ((inx = cbuff.toString().indexOf("PUBLIC")) != -1) {
1794
                cbuff = new StringBuffer();
1795
                st.push("PUBLIC");
1796
            }
1797
            // "SYSTEM" keyword is found; put it in the stack
1798
            if ((inx = cbuff.toString().indexOf("SYSTEM")) != -1) {
1799
                cbuff = new StringBuffer();
1800
                st.push("SYSTEM");
1801
            }
1802
            // ">" character is found; put it in the stack
1803
            // ">" is found twice: fisrt from <?xml ...?>
1804
            // and second from <!DOCTYPE ... >
1805
            if ((inx = cbuff.toString().indexOf(">")) != -1) {
1806
                cbuff = new StringBuffer();
1807
                st.push(">");
1808
            }
1809
        }
1810

    
1811
        // close the stream
1812
        xmlreader.reset();
1813

    
1814
        // check the stack whether it contains the keywords:
1815
        // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1816
        if (st.size() == 4) {
1817
            if (((String) st.pop()).equals(">")
1818
                    && (((String) st.peek()).equals("PUBLIC") | ((String) st
1819
                            .pop()).equals("SYSTEM"))
1820
                    && ((String) st.pop()).equals("<!DOCTYPE")) {
1821
                validate = true;
1822
            }
1823
        }
1824

    
1825
        MetaCatUtil.debugMessage("Validation for dtd is " + validate, 10);
1826
        return validate;
1827
    }
1828

    
1829
    // END OF INSERT/UPDATE SECTION
1830

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

    
1851
        MetaCatUtil.debugMessage("Validation for schema is "
1852
                + needSchemaValidate, 10);
1853
        return needSchemaValidate;
1854

    
1855
    }
1856

    
1857
    /* check if the xml string contains key words to specify schema loocation */
1858
    private String findNamespace(StringReader xml) throws IOException
1859
    {
1860
        String namespace = null;
1861

    
1862
        String eml2_0_0NameSpace = DocumentImpl.EML2_0_0NAMESPACE;
1863
        String eml2_0_1NameSpace = DocumentImpl.EML2_0_1NAMESPACE;
1864
        String eml2_1_0NameSpace = DocumentImpl.EML2_1_0NAMESPACE;
1865

    
1866
        if (xml == null) {
1867
            MetaCatUtil.debugMessage("Validation for schema is "
1868
                    + namespace, 10);
1869
            return namespace;
1870
        }
1871
        String targetLine = getSchemaLine(xml);
1872

    
1873
        if (targetLine != null) {
1874

    
1875
            int startIndex = targetLine.indexOf(SCHEMALOCATIONKEYWORD);
1876
            int start = 1;
1877
            int end = 1;
1878
            String schemaLocation = null;
1879
            int count = 0;
1880
            if (startIndex != -1) {
1881
                for (int i = startIndex; i < targetLine.length(); i++) {
1882
                    if (targetLine.charAt(i) == '"') {
1883
                        count++;
1884
                    }
1885
                    if (targetLine.charAt(i) == '"' && count == 1) {
1886
                        start = i;
1887
                    }
1888
                    if (targetLine.charAt(i) == '"' && count == 2) {
1889
                        end = i;
1890
                        break;
1891
                    }
1892
                }
1893
            }
1894
            schemaLocation = targetLine.substring(start + 1, end);
1895
            MetaCatUtil.debugMessage("schemaLocation in xml is: "
1896
                    + schemaLocation, 30);
1897
            if (schemaLocation.indexOf(eml2_0_0NameSpace) != -1) {
1898
                namespace = eml2_0_0NameSpace;
1899
            } else if (schemaLocation.indexOf(eml2_0_1NameSpace) != -1) {
1900
                namespace = eml2_0_1NameSpace;
1901
            } else if (schemaLocation.indexOf(eml2_1_0NameSpace) != -1) {
1902
                namespace = eml2_1_0NameSpace;
1903
            }
1904
        }
1905

    
1906
        MetaCatUtil.debugMessage("Validation for eml is " + namespace,
1907
                10);
1908

    
1909
        return namespace;
1910

    
1911
    }
1912

    
1913
    private String getSchemaLine(StringReader xml) throws IOException
1914
    {
1915
        // find the line
1916
        String secondLine = null;
1917
        int count = 0;
1918
        int endIndex = 0;
1919
        int startIndex = 0;
1920
        final int TARGETNUM = 2;
1921
        StringBuffer buffer = new StringBuffer();
1922
        boolean comment = false;
1923
        char thirdPreviousCharacter = '?';
1924
        char secondPreviousCharacter = '?';
1925
        char previousCharacter = '?';
1926
        char currentCharacter = '?';
1927
        int tmp = xml.read();
1928
        while (tmp != -1) {
1929
            currentCharacter = (char)tmp;
1930
            //in a comment
1931
            if (currentCharacter == '-' && previousCharacter == '-'
1932
                    && secondPreviousCharacter == '!'
1933
                    && thirdPreviousCharacter == '<') {
1934
                comment = true;
1935
            }
1936
            //out of comment
1937
            if (comment && currentCharacter == '>' && previousCharacter == '-'
1938
                    && secondPreviousCharacter == '-') {
1939
                comment = false;
1940
            }
1941

    
1942
            //this is not comment
1943
            if (currentCharacter != '!' && previousCharacter == '<' && !comment) {
1944
                count++;
1945
            }
1946
            // get target line
1947
            if (count == TARGETNUM && currentCharacter != '>') {
1948
                buffer.append(currentCharacter);
1949
            }
1950
            if (count == TARGETNUM && currentCharacter == '>') {
1951
                break;
1952
            }
1953
            thirdPreviousCharacter = secondPreviousCharacter;
1954
            secondPreviousCharacter = previousCharacter;
1955
            previousCharacter = currentCharacter;
1956
            tmp = xml.read();
1957
        }
1958
        secondLine = buffer.toString();
1959
        MetaCatUtil
1960
                .debugMessage("the second line string is: " + secondLine, 25);
1961
        xml.reset();
1962
        return secondLine;
1963
    }
1964

    
1965
    /**
1966
     * Handle the database delete request and delete an XML document from the
1967
     * database connection
1968
     */
1969
    private void handleDeleteAction(PrintWriter out, Hashtable params,
1970
            HttpServletRequest request, HttpServletResponse response,
1971
            String user, String[] groups)
1972
    {
1973

    
1974
        String[] docid = (String[]) params.get("docid");
1975

    
1976
        if(docid == null){
1977
          response.setContentType("text/xml");
1978
          out.println("<?xml version=\"1.0\"?>");
1979
          out.println("<error>");
1980
          out.println("Docid not specified.");
1981
          out.println("</error>");
1982
        } else {
1983

    
1984
            // delete the document from the database
1985
            try {
1986

    
1987
                try {
1988
                    // null means notify server is null
1989
                    DocumentImpl.delete(docid[0], user, groups, null);
1990
                    EventLog.getInstance().log(request.getRemoteAddr(),
1991
                                               user, docid[0], "delete");
1992
                    response.setContentType("text/xml");
1993
                    out.println("<?xml version=\"1.0\"?>");
1994
                    out.println("<success>");
1995
                    out.println("Document deleted.");
1996
                    out.println("</success>");
1997
                }
1998
                catch (AccessionNumberException ane) {
1999
                    response.setContentType("text/xml");
2000
                    out.println("<?xml version=\"1.0\"?>");
2001
                    out.println("<error>");
2002
                    //out.println("Error deleting document!!!");
2003
                    out.println(ane.getMessage());
2004
                    out.println("</error>");
2005
                }
2006
            }
2007
            catch (Exception e) {
2008
                response.setContentType("text/xml");
2009
                out.println("<?xml version=\"1.0\"?>");
2010
                out.println("<error>");
2011
                out.println(e.getMessage());
2012
                out.println("</error>");
2013
            }
2014
        }
2015
    }
2016

    
2017
    /**
2018
     * Handle the validation request and return the results to the requestor
2019
     */
2020
    private void handleValidateAction(PrintWriter out, Hashtable params)
2021
    {
2022

    
2023
        // Get the document indicated
2024
        String valtext = null;
2025
        DBConnection dbConn = null;
2026
        int serialNumber = -1;
2027

    
2028
        try {
2029
            valtext = ((String[]) params.get("valtext"))[0];
2030
        } catch (Exception nullpe) {
2031

    
2032
            String docid = null;
2033
            try {
2034
                // Find the document id number
2035
                docid = ((String[]) params.get("docid"))[0];
2036

    
2037
                // Get the document indicated from the db
2038
                DocumentImpl xmldoc = new DocumentImpl(docid);
2039
                valtext = xmldoc.toString();
2040

    
2041
            } catch (NullPointerException npe) {
2042

    
2043
                out.println("<error>Error getting document ID: " + docid
2044
                        + "</error>");
2045
                //if ( conn != null ) { util.returnConnection(conn); }
2046
                return;
2047
            } catch (Exception e) {
2048

    
2049
                out.println(e.getMessage());
2050
            }
2051
        }
2052

    
2053
        try {
2054
            // get a connection from the pool
2055
            dbConn = DBConnectionPool
2056
                    .getDBConnection("MetaCatServlet.handleValidateAction");
2057
            serialNumber = dbConn.getCheckOutSerialNumber();
2058
            DBValidate valobj = new DBValidate(saxparser, dbConn);
2059
            boolean valid = valobj.validateString(valtext);
2060

    
2061
            // set content type and other response header fields first
2062

    
2063
            out.println(valobj.returnErrors());
2064

    
2065
        } catch (NullPointerException npe2) {
2066
            // set content type and other response header fields first
2067

    
2068
            out.println("<error>Error validating document.</error>");
2069
        } catch (Exception e) {
2070

    
2071
            out.println(e.getMessage());
2072
        } finally {
2073
            // Return db connection
2074
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2075
        }
2076
    }
2077

    
2078
    /**
2079
     * Handle "getrevsionanddoctype" action Given a docid, return it's current
2080
     * revision and doctype from data base The output is String look like
2081
     * "rev;doctype"
2082
     */
2083
    private void handleGetRevisionAndDocTypeAction(PrintWriter out,
2084
            Hashtable params)
2085
    {
2086
        // To store doc parameter
2087
        String[] docs = new String[10];
2088
        // Store a single doc id
2089
        String givenDocId = null;
2090
        // Get docid from parameters
2091
        if (params.containsKey("docid")) {
2092
            docs = (String[]) params.get("docid");
2093
        }
2094
        // Get first docid form string array
2095
        givenDocId = docs[0];
2096

    
2097
        try {
2098
            // Make sure there is a docid
2099
            if (givenDocId == null || givenDocId.equals("")) { throw new Exception(
2100
                    "User didn't specify docid!"); }//if
2101

    
2102
            // Create a DBUtil object
2103
            DBUtil dbutil = new DBUtil();
2104
            // Get a rev and doctype
2105
            String revAndDocType = dbutil
2106
                    .getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
2107
            out.println(revAndDocType);
2108

    
2109
        } catch (Exception e) {
2110
            // Handle exception
2111
            out.println("<?xml version=\"1.0\"?>");
2112
            out.println("<error>");
2113
            out.println(e.getMessage());
2114
            out.println("</error>");
2115
        }
2116

    
2117
    }
2118

    
2119
    /**
2120
     * Handle "getaccesscontrol" action. Read Access Control List from db
2121
     * connection in XML format
2122
     */
2123
    private void handleGetAccessControlAction(PrintWriter out,
2124
            Hashtable params, HttpServletResponse response, String username,
2125
            String[] groupnames)
2126
    {
2127
        DBConnection dbConn = null;
2128
        int serialNumber = -1;
2129
        String docid = ((String[]) params.get("docid"))[0];
2130

    
2131
        try {
2132

    
2133
            // get connection from the pool
2134
            dbConn = DBConnectionPool
2135
                    .getDBConnection("MetaCatServlet.handleGetAccessControlAction");
2136
            serialNumber = dbConn.getCheckOutSerialNumber();
2137
            AccessControlList aclobj = new AccessControlList(dbConn);
2138
            String acltext = aclobj.getACL(docid, username, groupnames);
2139
            out.println(acltext);
2140

    
2141
        } catch (Exception e) {
2142
            out.println("<?xml version=\"1.0\"?>");
2143
            out.println("<error>");
2144
            out.println(e.getMessage());
2145
            out.println("</error>");
2146
        } finally {
2147
            // Retrun db connection to pool
2148
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2149
        }
2150
    }
2151

    
2152
    /**
2153
     * Handle the "getprincipals" action. Read all principals from
2154
     * authentication scheme in XML format
2155
     */
2156
    private void handleGetPrincipalsAction(PrintWriter out, String user,
2157
            String password)
2158
    {
2159
        try {
2160
            AuthSession auth = new AuthSession();
2161
            String principals = auth.getPrincipals(user, password);
2162
            out.println(principals);
2163

    
2164
        } catch (Exception e) {
2165
            out.println("<?xml version=\"1.0\"?>");
2166
            out.println("<error>");
2167
            out.println(e.getMessage());
2168
            out.println("</error>");
2169
        }
2170
    }
2171

    
2172
    /**
2173
     * Handle "getdoctypes" action. Read all doctypes from db connection in XML
2174
     * format
2175
     */
2176
    private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
2177
            HttpServletResponse response)
2178
    {
2179
        try {
2180
            DBUtil dbutil = new DBUtil();
2181
            String doctypes = dbutil.readDoctypes();
2182
            out.println(doctypes);
2183
        } catch (Exception e) {
2184
            out.println("<?xml version=\"1.0\"?>");
2185
            out.println("<error>");
2186
            out.println(e.getMessage());
2187
            out.println("</error>");
2188
        }
2189
    }
2190

    
2191
    /**
2192
     * Handle the "getdtdschema" action. Read DTD or Schema file for a given
2193
     * doctype from Metacat catalog system
2194
     */
2195
    private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
2196
            HttpServletResponse response)
2197
    {
2198

    
2199
        String doctype = null;
2200
        String[] doctypeArr = (String[]) params.get("doctype");
2201

    
2202
        // get only the first doctype specified in the list of doctypes
2203
        // it could be done for all doctypes in that list
2204
        if (doctypeArr != null) {
2205
            doctype = ((String[]) params.get("doctype"))[0];
2206
        }
2207

    
2208
        try {
2209
            DBUtil dbutil = new DBUtil();
2210
            String dtdschema = dbutil.readDTDSchema(doctype);
2211
            out.println(dtdschema);
2212

    
2213
        } catch (Exception e) {
2214
            out.println("<?xml version=\"1.0\"?>");
2215
            out.println("<error>");
2216
            out.println(e.getMessage());
2217
            out.println("</error>");
2218
        }
2219

    
2220
    }
2221

    
2222
    /**
2223
     * Handle the "getlastdocid" action. Get the latest docid with rev number
2224
     * from db connection in XML format
2225
     */
2226
    private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
2227
            HttpServletResponse response)
2228
    {
2229

    
2230
        String scope = ((String[]) params.get("scope"))[0];
2231
        if (scope == null) {
2232
            scope = ((String[]) params.get("username"))[0];
2233
        }
2234

    
2235
        try {
2236

    
2237
            DBUtil dbutil = new DBUtil();
2238
            String lastDocid = dbutil.getMaxDocid(scope);
2239
            out.println("<?xml version=\"1.0\"?>");
2240
            out.println("<lastDocid>");
2241
            out.println("  <scope>" + scope + "</scope>");
2242
            out.println("  <docid>" + lastDocid + "</docid>");
2243
            out.println("</lastDocid>");
2244

    
2245
        } catch (Exception e) {
2246
            out.println("<?xml version=\"1.0\"?>");
2247
            out.println("<error>");
2248
            out.println(e.getMessage());
2249
            out.println("</error>");
2250
        }
2251
    }
2252

    
2253
    /**
2254
     * Print a report from the event log based on filter parameters passed in
2255
     * from the web.
2256
     *
2257
     * @param params the parameters from the web request
2258
     * @param request the http request object for getting request details
2259
     * @param response the http response object for writing output
2260
     */
2261
    private void handleGetLogAction(Hashtable params, HttpServletRequest request,
2262
            HttpServletResponse response, String username, String[] groups)
2263
    {
2264
        try {
2265
            response.setContentType("text/xml");
2266
            PrintWriter out = response.getWriter();
2267

    
2268
            // Check that the user is authenticated as an administrator account
2269
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2270
                out.print("<error>");
2271
                out.print("The user \"" + username +
2272
                        "\" is not authorized for this action.");
2273
                out.print("</error>");
2274
                return;
2275
            }
2276

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

    
2306
            // Request the report by passing the filter parameters
2307
            out.println(EventLog.getInstance().getReport(ipAddress, principal,
2308
                    docid, event, startDate, endDate));
2309
            out.close();
2310
        } catch (IOException e) {
2311
            MetaCatUtil.debugMessage(
2312
                    "Could not open http response for writing: " + e.getMessage(), 5);
2313
        }
2314
    }
2315

    
2316
    /**
2317
     * Rebuild the index for one or more documents. If the docid parameter is
2318
     * provided, rebuild for just that one document or list of documents. If
2319
     * not, then rebuild the index for all documents in the xml_documents
2320
     * table.
2321
     *
2322
     * @param params the parameters from the web request
2323
     * @param request the http request object for getting request details
2324
     * @param response the http response object for writing output
2325
     * @param username the username of the authenticated user
2326
     */
2327
    private void handleBuildIndexAction(Hashtable params,
2328
            HttpServletRequest request, HttpServletResponse response,
2329
            String username, String[] groups)
2330
    {
2331
        // Get all of the parameters in the correct formats
2332
        String[] docid = (String[])params.get("docid");
2333

    
2334
        // Rebuild the indices for appropriate documents
2335
        try {
2336
            response.setContentType("text/xml");
2337
            PrintWriter out = response.getWriter();
2338

    
2339
            // Check that the user is authenticated as an administrator account
2340
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2341
                out.print("<error>");
2342
                out.print("The user \"" + username +
2343
                        "\" is not authorized for this action.");
2344
                out.print("</error>");
2345
                return;
2346
            }
2347

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

    
2379
    /**
2380
     * Build the index for one document by reading the document and
2381
     * calling its buildIndex() method.
2382
     *
2383
     * @param docid the document (with revision) to rebuild
2384
     * @param out the PrintWriter to which output is printed
2385
     */
2386
    private void buildDocumentIndex(String docid, PrintWriter out)
2387
    {
2388
        try {
2389
            DocumentImpl doc = new DocumentImpl(docid, false);
2390
            doc.buildIndex();
2391
            out.print("<docid>" + docid);
2392
            out.println("</docid>");
2393
        } catch (McdbException me) {
2394
            out.print("<error>");
2395
            out.print(me.getMessage());
2396
            out.println("</error>");
2397
        }
2398
    }
2399

    
2400
    /**
2401
     * Handle documents passed to metacat that are encoded using the
2402
     * "multipart/form-data" mime type. This is typically used for uploading
2403
     * data files which may be binary and large.
2404
     */
2405
    private void handleMultipartForm(HttpServletRequest request,
2406
            HttpServletResponse response)
2407
    {
2408
        PrintWriter out = null;
2409
        String action = null;
2410

    
2411
        // Parse the multipart form, and save the parameters in a Hashtable and
2412
        // save the FileParts in a hashtable
2413

    
2414
        Hashtable params = new Hashtable();
2415
        Hashtable fileList = new Hashtable();
2416
        int sizeLimit = (new Integer(MetaCatUtil.getOption("datafilesizelimit")))
2417
                .intValue();
2418
        MetaCatUtil.debugMessage(
2419
                "The limit size of data file is: " + sizeLimit, 50);
2420

    
2421
        try {
2422
            // MBJ: need to put filesize limit in Metacat config
2423
            // (metacat.properties)
2424
            MultipartParser mp = new MultipartParser(request,
2425
                    sizeLimit * 1024 * 1024);
2426
            Part part;
2427
            while ((part = mp.readNextPart()) != null) {
2428
                String name = part.getName();
2429

    
2430
                if (part.isParam()) {
2431
                    // it's a parameter part
2432
                    ParamPart paramPart = (ParamPart) part;
2433
                    String value = paramPart.getStringValue();
2434
                    params.put(name, value);
2435
                    if (name.equals("action")) {
2436
                        action = value;
2437
                    }
2438
                } else if (part.isFile()) {
2439
                    // it's a file part
2440
                    FilePart filePart = (FilePart) part;
2441
                    fileList.put(name, filePart);
2442

    
2443
                    // Stop once the first file part is found, otherwise going
2444
                    // onto the
2445
                    // next part prevents access to the file contents. So...for
2446
                    // upload
2447
                    // to work, the datafile must be the last part
2448
                    break;
2449
                }
2450
            }
2451
        } catch (IOException ioe) {
2452
            try {
2453
                out = response.getWriter();
2454
            } catch (IOException ioe2) {
2455
                System.err
2456
                        .println("Fatal Error: couldn't get response output stream.");
2457
            }
2458
            out.println("<?xml version=\"1.0\"?>");
2459
            out.println("<error>");
2460
            out.println("Error: problem reading multipart data.");
2461
            out.println("</error>");
2462
        }
2463

    
2464
        // Get the session information
2465
        String username = null;
2466
        String password = null;
2467
        String[] groupnames = null;
2468
        String sess_id = null;
2469

    
2470
        // be aware of session expiration on every request
2471
        HttpSession sess = request.getSession(true);
2472
        if (sess.isNew()) {
2473
            // session expired or has not been stored b/w user requests
2474
            username = "public";
2475
            sess.setAttribute("username", username);
2476
        } else {
2477
            username = (String) sess.getAttribute("username");
2478
            password = (String) sess.getAttribute("password");
2479
            groupnames = (String[]) sess.getAttribute("groupnames");
2480
            try {
2481
                sess_id = (String) sess.getId();
2482
            } catch (IllegalStateException ise) {
2483
                System.out
2484
                        .println("error in  handleMultipartForm: this shouldn't "
2485
                                + "happen: the session should be valid: "
2486
                                + ise.getMessage());
2487
            }
2488
        }
2489

    
2490
        // Get the out stream
2491
        try {
2492
            out = response.getWriter();
2493
        } catch (IOException ioe2) {
2494
            MetaCatUtil.debugMessage("Fatal Error: couldn't get response "
2495
                    + "output stream.", 30);
2496
        }
2497

    
2498
        if (action.equals("upload")) {
2499
            if (username != null && !username.equals("public")) {
2500
                handleUploadAction(request, out, params, fileList, username,
2501
                        groupnames);
2502
            } else {
2503

    
2504
                out.println("<?xml version=\"1.0\"?>");
2505
                out.println("<error>");
2506
                out.println("Permission denied for " + action);
2507
                out.println("</error>");
2508
            }
2509
        } else {
2510
            /*
2511
             * try { out = response.getWriter(); } catch (IOException ioe2) {
2512
             * System.err.println("Fatal Error: couldn't get response output
2513
             * stream.");
2514
             */
2515
            out.println("<?xml version=\"1.0\"?>");
2516
            out.println("<error>");
2517
            out.println(
2518
                    "Error: action not registered.  Please report this error.");
2519
            out.println("</error>");
2520
        }
2521
        out.close();
2522
    }
2523

    
2524
    /**
2525
     * Handle the upload action by saving the attached file to disk and
2526
     * registering it in the Metacat db
2527
     */
2528
    private void handleUploadAction(HttpServletRequest request,
2529
            PrintWriter out, Hashtable params, Hashtable fileList,
2530
            String username, String[] groupnames)
2531
    {
2532
        //PrintWriter out = null;
2533
        //Connection conn = null;
2534
        String action = null;
2535
        String docid = null;
2536

    
2537
        /*
2538
         * response.setContentType("text/xml"); try { out =
2539
         * response.getWriter(); } catch (IOException ioe2) {
2540
         * System.err.println("Fatal Error: couldn't get response output
2541
         * stream.");
2542
         */
2543

    
2544
        if (params.containsKey("docid")) {
2545
            docid = (String) params.get("docid");
2546
        }
2547

    
2548
        // Make sure we have a docid and datafile
2549
        if (docid != null && fileList.containsKey("datafile")) {
2550

    
2551
            // Get a reference to the file part of the form
2552
            FilePart filePart = (FilePart) fileList.get("datafile");
2553
            String fileName = filePart.getFileName();
2554
            MetaCatUtil.debugMessage("Uploading filename: " + fileName, 10);
2555

    
2556
            // Check if the right file existed in the uploaded data
2557
            if (fileName != null) {
2558

    
2559
                try {
2560
                    //MetaCatUtil.debugMessage("Upload datafile " + docid
2561
                    // +"...", 10);
2562
                    //If document get lock data file grant
2563
                    if (DocumentImpl.getDataFileLockGrant(docid)) {
2564
                        // register the file in the database (which generates
2565
                        // an exception
2566
                        //if the docid is not acceptable or other untoward
2567
                        // things happen
2568
                        DocumentImpl.registerDocument(fileName, "BIN", docid,
2569
                                username, groupnames);
2570

    
2571
                        // Save the data file to disk using "docid" as the name
2572
                        dataDirectory.mkdirs();
2573
                        File newFile = new File(dataDirectory, docid);
2574
                        long size = filePart.writeTo(newFile);
2575

    
2576
                        EventLog.getInstance().log(request.getRemoteAddr(),
2577
                                username, docid, "upload");
2578
                        // Force replication this data file
2579
                        // To data file, "insert" and update is same
2580
                        // The fourth parameter is null. Because it is
2581
                        // notification server
2582
                        // and this method is in MetaCatServerlet. It is
2583
                        // original command,
2584
                        // not get force replication info from another metacat
2585
                        ForceReplicationHandler frh = new ForceReplicationHandler(
2586
                                docid, "insert", false, null);
2587

    
2588
                        // set content type and other response header fields
2589
                        // first
2590
                        out.println("<?xml version=\"1.0\"?>");
2591
                        out.println("<success>");
2592
                        out.println("<docid>" + docid + "</docid>");
2593
                        out.println("<size>" + size + "</size>");
2594
                        out.println("</success>");
2595
                    }
2596

    
2597
                } catch (Exception e) {
2598
                    out.println("<?xml version=\"1.0\"?>");
2599
                    out.println("<error>");
2600
                    out.println(e.getMessage());
2601
                    out.println("</error>");
2602
                }
2603
            } else {
2604
                // the field did not contain a file
2605
                out.println("<?xml version=\"1.0\"?>");
2606
                out.println("<error>");
2607
                out.println("The uploaded data did not contain a valid file.");
2608
                out.println("</error>");
2609
            }
2610
        } else {
2611
            // Error bcse docid missing or file missing
2612
            out.println("<?xml version=\"1.0\"?>");
2613
            out.println("<error>");
2614
            out.println("The uploaded data did not contain a valid docid "
2615
                    + "or valid file.");
2616
            out.println("</error>");
2617
        }
2618
    }
2619

    
2620
    /*
2621
     * A method to handle set access action
2622
     */
2623
    private void handleSetAccessAction(PrintWriter out, Hashtable params,
2624
            String username)
2625
    {
2626
        String[] docList = null;
2627
        String[] principalList = null;
2628
        String[] permissionList = null;
2629
        String[] permTypeList = null;
2630
        String[] permOrderList = null;
2631
        String permission = null;
2632
        String permType = null;
2633
        String permOrder = null;
2634
        Vector errorList = new Vector();
2635
        String error = null;
2636
        Vector successList = new Vector();
2637
        String success = null;
2638

    
2639
        // Get parameters
2640
        if (params.containsKey("docid")) {
2641
            docList = (String[]) params.get("docid");
2642
        }
2643
        if (params.containsKey("principal")) {
2644
            principalList = (String[]) params.get("principal");
2645
        }
2646
        if (params.containsKey("permission")) {
2647
            permissionList = (String[]) params.get("permission");
2648

    
2649
        }
2650
        if (params.containsKey("permType")) {
2651
            permTypeList = (String[]) params.get("permType");
2652

    
2653
        }
2654
        if (params.containsKey("permOrder")) {
2655
            permOrderList = (String[]) params.get("permOrder");
2656

    
2657
        }
2658

    
2659
        // Make sure the parameter is not null
2660
        if (docList == null || principalList == null || permTypeList == null
2661
                || permissionList == null) {
2662
            error = "Please check your parameter list, it should look like: "
2663
                    + "?action=setaccess&docid=pipeline.1.1&principal=public"
2664
                    + "&permission=read&permType=allow&permOrder=allowFirst";
2665
            errorList.addElement(error);
2666
            outputResponse(successList, errorList, out);
2667
            return;
2668
        }
2669

    
2670
        // Only select first element for permission, type and order
2671
        permission = permissionList[0];
2672
        permType = permTypeList[0];
2673
        if (permOrderList != null) {
2674
            permOrder = permOrderList[0];
2675
        }
2676

    
2677
        // Get package doctype set
2678
        Vector packageSet = MetaCatUtil.getOptionList(MetaCatUtil
2679
                .getOption("packagedoctypeset"));
2680
        //debug
2681
        if (packageSet != null) {
2682
            for (int i = 0; i < packageSet.size(); i++) {
2683
                MetaCatUtil.debugMessage("doctype in package set: "
2684
                        + (String) packageSet.elementAt(i), 34);
2685
            }
2686
        }
2687

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

    
2714
            // If docid publicid is BIN data file or other beta4, 6 package
2715
            // document
2716
            // we could not do set access control. Because we don't want
2717
            // inconsistent
2718
            // to its access docuemnt
2719
            if (publicId != null && packageSet != null
2720
                    && packageSet.contains(publicId)) {
2721
                error = "Could not set access control to document "
2722
                        + accessionNumber
2723
                        + "because it is in a pakcage and it has a access file for it";
2724
                errorList.addElement(error);
2725
                continue;
2726
            }
2727

    
2728
            // for every principle
2729
            for (int j = 0; j < principalList.length; j++) {
2730
                String principal = principalList[j];
2731
                try {
2732
                    //insert permission
2733
                    AccessControlForSingleFile accessControl = new AccessControlForSingleFile(
2734
                            accessionNumber, principal, permission, permType,
2735
                            permOrder);
2736
                    accessControl.insertPermissions();
2737
                    success = "Set access control to document "
2738
                            + accessionNumber + " successfully";
2739
                    successList.addElement(success);
2740
                } catch (Exception ee) {
2741
                    MetaCatUtil.debugMessage(
2742
                            "Erorr in handleSetAccessAction2: "
2743
                                    + ee.getMessage(), 30);
2744
                    error = "Faild to set access control for document "
2745
                            + accessionNumber + " because " + ee.getMessage();
2746
                    errorList.addElement(error);
2747
                    continue;
2748
                }
2749
            }
2750
        }
2751
        outputResponse(successList, errorList, out);
2752
    }
2753

    
2754
    /*
2755
     * A method try to determin a docid's public id, if couldn't find null will
2756
     * be returned.
2757
     */
2758
    private String getFieldValueForDoc(String accessionNumber, String fieldName)
2759
            throws Exception
2760
    {
2761
        if (accessionNumber == null || accessionNumber.equals("")
2762
                || fieldName == null || fieldName.equals("")) { throw new Exception(
2763
                "Docid or field name was not specified"); }
2764

    
2765
        PreparedStatement pstmt = null;
2766
        ResultSet rs = null;
2767
        String fieldValue = null;
2768
        String docId = null;
2769
        DBConnection conn = null;
2770
        int serialNumber = -1;
2771

    
2772
        // get rid of revision if access number has
2773
        docId = MetaCatUtil.getDocIdFromString(accessionNumber);
2774
        try {
2775
            //check out DBConnection
2776
            conn = DBConnectionPool
2777
                    .getDBConnection("MetaCatServlet.getPublicIdForDoc");
2778
            serialNumber = conn.getCheckOutSerialNumber();
2779
            pstmt = conn.prepareStatement("SELECT " + fieldName
2780
                    + " FROM xml_documents " + "WHERE docid = ? ");
2781

    
2782
            pstmt.setString(1, docId);
2783
            pstmt.execute();
2784
            rs = pstmt.getResultSet();
2785
            boolean hasRow = rs.next();
2786
            int perm = 0;
2787
            if (hasRow) {
2788
                fieldValue = rs.getString(1);
2789
            } else {
2790
                throw new Exception("Could not find document: "
2791
                        + accessionNumber);
2792
            }
2793
        } catch (Exception e) {
2794
            MetaCatUtil.debugMessage(
2795
                    "Exception in MetacatServlet.getPublicIdForDoc: "
2796
                            + e.getMessage(), 30);
2797
            throw e;
2798
        } finally {
2799
            try {
2800
                rs.close();
2801
                pstmt.close();
2802

    
2803
            } finally {
2804
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2805
            }
2806
        }
2807
        return fieldValue;
2808
    }
2809

    
2810
    /*
2811
     * Get the list of documents from the database and return the list in an
2812
     * Vector of identifiers.
2813
     *
2814
     * @ returns the array of identifiers
2815
     */
2816
    private Vector getDocumentList() throws SQLException
2817
    {
2818
        Vector docList = new Vector();
2819
        PreparedStatement pstmt = null;
2820
        ResultSet rs = null;
2821
        DBConnection conn = null;
2822
        int serialNumber = -1;
2823

    
2824
        try {
2825
            //check out DBConnection
2826
            conn = DBConnectionPool
2827
                    .getDBConnection("MetaCatServlet.getDocumentList");
2828
            serialNumber = conn.getCheckOutSerialNumber();
2829
            pstmt = conn.prepareStatement("SELECT docid, rev"
2830
                    + " FROM xml_documents ");
2831
            pstmt.execute();
2832
            rs = pstmt.getResultSet();
2833
            while (rs.next()) {
2834
                String docid = rs.getString(1);
2835
                String rev = rs.getString(2);
2836
                docList.add(docid + "." + rev);
2837
            }
2838
        } catch (SQLException e) {
2839
            MetaCatUtil.debugMessage(
2840
                    "Exception in MetacatServlet.getDocumentList: "
2841
                            + e.getMessage(), 30);
2842
            throw e;
2843
        } finally {
2844
            try {
2845
                rs.close();
2846
                pstmt.close();
2847

    
2848
            } catch (SQLException se) {
2849
                MetaCatUtil.debugMessage(
2850
                    "Exception in MetacatServlet.getDocumentList: "
2851
                            + se.getMessage(), 30);
2852
                throw se;
2853
            } finally {
2854
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2855
            }
2856
        }
2857
        return docList;
2858
    }
2859

    
2860
    /*
2861
     * A method to output setAccess action result
2862
     */
2863
    private void outputResponse(Vector successList, Vector errorList,
2864
            PrintWriter out)
2865
    {
2866
        boolean error = false;
2867
        boolean success = false;
2868
        // Output prolog
2869
        out.println(PROLOG);
2870
        // output success message
2871
        if (successList != null) {
2872
            for (int i = 0; i < successList.size(); i++) {
2873
                out.println(SUCCESS);
2874
                out.println((String) successList.elementAt(i));
2875
                out.println(SUCCESSCLOSE);
2876
                success = true;
2877
            }
2878
        }
2879
        // output error message
2880
        if (errorList != null) {
2881
            for (int i = 0; i < errorList.size(); i++) {
2882
                out.println(ERROR);
2883
                out.println((String) errorList.elementAt(i));
2884
                out.println(ERRORCLOSE);
2885
                error = true;
2886
            }
2887
        }
2888

    
2889
        // if no error and no success info, send a error that nothing happened
2890
        if (!error && !success) {
2891
            out.println(ERROR);
2892
            out.println("Nothing happend for setaccess action");
2893
            out.println(ERRORCLOSE);
2894
        }
2895
    }
2896
    
2897
    /**
2898
     * Method to get session table which store the session info
2899
     * @return
2900
     */
2901
    public static Hashtable getSessionHash()
2902
    {
2903
        return sessionHash;
2904
    }
2905
}
(42-42/63)