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: sgarg $'
10
 *     '$Date: 2005-10-10 12:27:12 -0700 (Mon, 10 Oct 2005) $'
11
 * '$Revision: 2668 $'
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 org.apache.log4j.Logger;
69
import org.apache.log4j.PropertyConfigurator;
70

    
71
import edu.ucsb.nceas.utilities.Options;
72

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

    
120
    private ServletConfig config = null;
121

    
122
    private ServletContext context = null;
123

    
124
    private String resultStyleURL = null;
125

    
126
    private String xmlcatalogfile = null;
127

    
128
    private String saxparser = null;
129

    
130
    private String datafilepath = null;
131

    
132
    private File dataDirectory = null;
133

    
134
    private String servletpath = null;
135

    
136
    private String htmlpath = null;
137

    
138
    private PropertyResourceBundle options = null;
139

    
140
    private MetaCatUtil util = null;
141

    
142
    private DBConnectionPool connPool = null;
143

    
144
    private static Hashtable sessionHash = new Hashtable();
145

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

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

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

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

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

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

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

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

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

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

    
166
    private static final String CONFIG_NAME = "metacat.properties";
167
     	 
168
    private static Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
169
    
170
    /**
171
     * Initialize the servlet by creating appropriate database connections
172
     */
173
    public void init(ServletConfig config) throws ServletException
174
    {
175
        try {
176
            super.init(config);
177
            this.config = config;
178
            this.context = config.getServletContext();
179

    
180
            // Initialize the properties file for our options
181
            String dirPath = context.getRealPath(CONFIG_DIR);
182
            File propertyFile = new File(dirPath, CONFIG_NAME);
183

    
184
            String LOG_CONFIG_NAME = dirPath + "/log4j.properties";
185
            PropertyConfigurator.configureAndWatch(LOG_CONFIG_NAME);
186
            
187
            Options options = null;
188
            try {
189
                options = Options.initialize(propertyFile);
190
                MetaCatUtil.printMessage("Options configured: "
191
                        + options.getOption("configured"));
192
            } catch (IOException ioe) {
193
                logMetacat.error("Error in loading options: "
194
                        + ioe.getMessage());
195
            }
196

    
197
            util = new MetaCatUtil();
198

    
199
            //initial DBConnection pool
200
            connPool = DBConnectionPool.getInstance();
201

    
202
            // Get the configuration file information
203
            resultStyleURL = MetaCatUtil.getOption("resultStyleURL");
204
            xmlcatalogfile = MetaCatUtil.getOption("xmlcatalogfile");
205
            saxparser = MetaCatUtil.getOption("saxparser");
206
            datafilepath = MetaCatUtil.getOption("datafilepath");
207
            dataDirectory = new File(datafilepath);
208
            servletpath = MetaCatUtil.getOption("servletpath");
209
            htmlpath = MetaCatUtil.getOption("htmlpath");
210

    
211
            // Index the paths specified in the metacat.properties
212
            checkIndexPaths();
213

    
214
            MetaCatUtil.printMessage("Metacat (" + Version.getVersion()
215
                               + ") initialized.");
216

    
217
        } catch (ServletException ex) {
218
            throw ex;
219
        } catch (SQLException e) {
220
            logMetacat.error("Error in MetacatServlet.init: "
221
                    + e.getMessage());
222
        }
223
    }
224

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

    
235
    /** Handle "GET" method requests from HTTP clients */
236
    public void doGet(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
    /** Handle "POST" method requests from HTTP clients */
245
    public void doPost(HttpServletRequest request, HttpServletResponse response)
246
            throws ServletException, IOException
247
    {
248

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

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

    
383

    
384
    /**
385
     * Control servlet response depending on the action parameter specified
386
     */
387
    private void handleGetOrPost(HttpServletRequest request,
388
            HttpServletResponse response) throws ServletException, IOException
389
    {
390

    
391
        if (util == null) {
392
            util = new MetaCatUtil();
393
        }
394
        /*
395
         * logMetacat.info("Connection pool size: "
396
         * +connPool.getSizeOfDBConnectionPool(),10);
397
         * logMetacat.info("Free DBConnection number: "
398
         */
399
        //If all DBConnection in the pool are free and DBConnection pool
400
        //size is greater than initial value, shrink the connection pool
401
        //size to initial value
402
        DBConnectionPool.shrinkDBConnectionPoolSize();
403

    
404
        //Debug message to print out the method which have a busy DBConnection
405
        connPool.printMethodNameHavingBusyDBConnection();
406

    
407
        String ctype = request.getContentType();
408
        if (ctype != null && ctype.startsWith("multipart/form-data")) {
409
            handleMultipartForm(request, response);
410
        } else {
411

    
412
            String name = null;
413
            String[] value = null;
414
            String[] docid = new String[3];
415
            Hashtable params = new Hashtable();
416
            Enumeration paramlist = request.getParameterNames();
417

    
418
            while (paramlist.hasMoreElements()) {
419

    
420
                name = (String) paramlist.nextElement();
421
                value = request.getParameterValues(name);
422

    
423
                // Decode the docid and mouse click information
424
                if (name.endsWith(".y")) {
425
                    docid[0] = name.substring(0, name.length() - 2);
426
                    params.put("docid", docid);
427
                    name = "ypos";
428
                }
429
                if (name.endsWith(".x")) {
430
                    name = "xpos";
431
                }
432

    
433
                params.put(name, value);
434
            }
435

    
436
            //handle param is emptpy
437
            if (params.isEmpty() || params == null) { return; }
438

    
439
            //if the user clicked on the input images, decode which image
440
            //was clicked then set the action.
441
            if(params.get("action") == null){
442
                PrintWriter out = response.getWriter();
443
                response.setContentType("text/xml");
444
                out.println("<?xml version=\"1.0\"?>");
445
                out.println("<error>");
446
                out.println("Action not specified");
447
                out.println("</error>");
448
                out.close();
449
                return;
450
            }
451

    
452
            String action = ((String[]) params.get("action"))[0];
453
            logMetacat.warn("Action is: " + action);
454

    
455
            // This block handles session management for the servlet
456
            // by looking up the current session information for all actions
457
            // other than "login" and "logout"
458
            String username = null;
459
            String password = null;
460
            String[] groupnames = null;
461
            String sess_id = null;
462

    
463
            // handle login action
464
            if (action.equals("login")) {
465
                PrintWriter out = response.getWriter();
466
                handleLoginAction(out, params, request, response);
467
                out.close();
468

    
469
                // handle logout action
470
            } else if (action.equals("logout")) {
471
                PrintWriter out = response.getWriter();
472
                handleLogoutAction(out, params, request, response);
473
                out.close();
474

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

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

    
537
                    username = (String) sess.getAttribute("username");
538
                    logMetacat.info("The user name from session is: "
539
                            + username);
540
                    password = (String) sess.getAttribute("password");
541
                    groupnames = (String[]) sess.getAttribute("groupnames");
542
                }
543

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

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

    
706
            //util.closeConnections();
707
            // Close the stream to the client
708
            //out.close();
709
        }
710
    }
711

    
712
    // LOGIN & LOGOUT SECTION
713
    /**
714
     * Handle the login request. Create a new session object. Do user
715
     * authentication through the session.
716
     */
717
    private void handleLoginAction(PrintWriter out, Hashtable params,
718
            HttpServletRequest request, HttpServletResponse response)
719
    {
720

    
721
        AuthSession sess = null;
722

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

    
732
        if(params.get("password") == null){
733
            response.setContentType("text/xml");
734
            out.println("<?xml version=\"1.0\"?>");
735
            out.println("<error>");
736
            out.println("Password not specified");
737
            out.println("</error>");
738
            return;
739
        }
740

    
741
        String un = ((String[]) params.get("username"))[0];
742
        logMetacat.warn("user " + un + " is trying to login");
743
        String pw = ((String[]) params.get("password"))[0];
744

    
745
        String qformat = "xml";
746
        if(params.get("qformat") != null){
747
            qformat = ((String[]) params.get("qformat"))[0];
748
        }
749

    
750
        try {
751
            sess = new AuthSession();
752
        } catch (Exception e) {
753
            System.out.println("error in MetacatServlet.handleLoginAction: "
754
                    + e.getMessage());
755
            out.println(e.getMessage());
756
            return;
757
        }
758
        boolean isValid = sess.authenticate(request, un, pw);
759

    
760
        //if it is authernticate is true, store the session
761
        if (isValid) {
762
            HttpSession session = sess.getSessions();
763
            String id = session.getId();
764
            logMetacat.info("Store session id " + id
765
                    + "which has username" + session.getAttribute("username")
766
                    + " into hash in login method");
767
            sessionHash.put(id, session);
768
        }
769

    
770
        // format and transform the output
771
        if (qformat.equals("xml")) {
772
            response.setContentType("text/xml");
773
            out.println(sess.getMessage());
774
        } else {
775
            try {
776
                DBTransform trans = new DBTransform();
777
                response.setContentType("text/html");
778
                trans.transformXMLDocument(sess.getMessage(),
779
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
780
                        out, null);
781
            } catch (Exception e) {
782

    
783
                logMetacat.error(
784
                        "Error in MetaCatServlet.handleLoginAction: "
785
                                + e.getMessage());
786
            }
787
        }
788
    }
789

    
790
    /**
791
     * Handle the logout request. Close the connection.
792
     */
793
    private void handleLogoutAction(PrintWriter out, Hashtable params,
794
            HttpServletRequest request, HttpServletResponse response)
795
    {
796

    
797
        String qformat = "xml";
798
        if(params.get("qformat") != null){
799
            qformat = ((String[]) params.get("qformat"))[0];
800
        }
801

    
802
        // close the connection
803
        HttpSession sess = request.getSession(false);
804
        logMetacat.info("After get session in logout request");
805
        if (sess != null) {
806
            logMetacat.info("The session id " + sess.getId()
807
                    + " will be invalidate in logout action");
808
            logMetacat.warn("The session contains user "
809
                    + sess.getAttribute("username")
810
                    + " will be invalidate in logout action");
811
            sess.invalidate();
812
        }
813

    
814
        // produce output
815
        StringBuffer output = new StringBuffer();
816
        output.append("<?xml version=\"1.0\"?>");
817
        output.append("<logout>");
818
        output.append("User logged out");
819
        output.append("</logout>");
820

    
821
        //format and transform the output
822
        if (qformat.equals("xml")) {
823
            response.setContentType("text/xml");
824
            out.println(output.toString());
825
        } else {
826
            try {
827
                DBTransform trans = new DBTransform();
828
                response.setContentType("text/html");
829
                trans.transformXMLDocument(output.toString(),
830
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
831
                        out, null);
832
            } catch (Exception e) {
833
                logMetacat.error(
834
                        "Error in MetaCatServlet.handleLogoutAction"
835
                                + e.getMessage());
836
            }
837
        }
838
    }
839

    
840
    // END OF LOGIN & LOGOUT SECTION
841

    
842
    // SQUERY & QUERY SECTION
843
    /**
844
     * Retreive the squery xml, execute it and display it
845
     *
846
     * @param out the output stream to the client
847
     * @param params the Hashtable of parameters that should be included in the
848
     *            squery.
849
     * @param response the response object linked to the client
850
     * @param conn the database connection
851
     */
852
    private void handleSQuery(PrintWriter out, Hashtable params,
853
            HttpServletResponse response, String user, String[] groups,
854
            String sessionid)
855
    {
856
        double startTime = System.currentTimeMillis() / 1000;
857
        DBQuery queryobj = new DBQuery(saxparser);
858
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
859
        double outPutTime = System.currentTimeMillis() / 1000;
860
        logMetacat.warn("Total search time for action 'squery': "
861
                + (outPutTime - startTime));
862

    
863
    }
864

    
865
    /**
866
     * Create the xml query, execute it and display the results.
867
     *
868
     * @param out the output stream to the client
869
     * @param params the Hashtable of parameters that should be included in the
870
     *            squery.
871
     * @param response the response object linked to the client
872
     */
873
    private void handleQuery(PrintWriter out, Hashtable params,
874
            HttpServletResponse response, String user, String[] groups,
875
            String sessionid)
876
    {
877
        //create the query and run it
878
        String xmlquery = DBQuery.createSQuery(params);
879
        String[] queryArray = new String[1];
880
        queryArray[0] = xmlquery;
881
        params.put("query", queryArray);
882
        double startTime = System.currentTimeMillis() / 1000;
883
        DBQuery queryobj = new DBQuery(saxparser);
884
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
885
        double outPutTime = System.currentTimeMillis() / 1000;
886
        logMetacat.warn("Total search time for action 'query': "
887
                + (outPutTime - startTime));
888

    
889
        //handleSQuery(out, params, response,user, groups, sessionid);
890
    }
891

    
892
    // END OF SQUERY & QUERY SECTION
893

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

    
913
        String[] docs = new String[10];
914
        String docId = "";
915

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

    
952
        } catch (Exception e) {
953
            try {
954
                response.setContentType("text/xml"); //MIME type
955
                // Send error message back
956
                if (out != null) {
957
                    PrintWriter pw = new PrintWriter(out);
958
                    pw.println("<?xml version=\"1.0\"?>");
959
                    pw.println("<error>");
960
                    pw.println(e.getMessage());
961
                    pw.println("</error>");
962
                    // Close printwriter
963
                    pw.close();
964
                    // Close output stream
965
                    out.close();
966
                }
967
                // Close zip output stream
968
                if (zOut != null) {
969
                    zOut.close();
970
                }
971
            } catch (IOException ioe) {
972
                logMetacat.error("Problem with the servlet output "
973
                        + "in MetacatServlet.handleExportAction: "
974
                        + ioe.getMessage());
975
            }
976

    
977
            logMetacat.error(
978
                    "Error in MetacatServlet.handleExportAction: "
979
                            + e.getMessage());
980
            e.printStackTrace(System.out);
981

    
982
        }
983

    
984
    }
985

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

    
1005
        try {
1006
            // read the params
1007
            if (params.containsKey("inlinedataid")) {
1008
                docs = (String[]) params.get("inlinedataid");
1009
            }
1010
            // Get the docid
1011
            inlineDataId = docs[0];
1012
            // Make sure the client specify docid
1013
            if (inlineDataId == null || inlineDataId.equals("")) {
1014
                throw new Exception("You didn't specify requested inlinedataid"); }
1015

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

    
1043
                }//if
1044
              }//try
1045
              catch (Exception e)
1046
              {
1047
                throw e;
1048
              }//catch
1049
            }//else
1050

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

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

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

    
1114
        try {
1115
            //check out DBConnection
1116
            conn = DBConnectionPool
1117
                    .getDBConnection("AccessControlList.isAllowFirst");
1118
            serialNumber = conn.getCheckOutSerialNumber();
1119

    
1120
            pStmt = conn.prepareStatement(sql);
1121
            //bind value
1122
            pStmt.setString(1, docId);//docid
1123
            pStmt.setString(2, inLineDataId);//inlinedataid
1124
            pStmt.setString(3, docId);
1125
            // excute query
1126
            pStmt.execute();
1127
            ResultSet rs = pStmt.getResultSet();
1128
            hasRow = rs.next();
1129
            // get result
1130
            if (hasRow) {
1131
                nodeId = rs.getLong(1);
1132
            }//if
1133

    
1134
        } catch (SQLException e) {
1135
            throw e;
1136
        } finally {
1137
            try {
1138
                pStmt.close();
1139
            } finally {
1140
                DBConnectionPool.returnDBConnection(conn, serialNumber);
1141
            }
1142
        }
1143
        logMetacat.info("The nodeid for inlinedataid " + inLineDataId
1144
                + " is: " + nodeId);
1145
        return nodeId;
1146
    }
1147

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

    
1169
        try {
1170
            String[] docs = new String[0];
1171
            String docid = "";
1172
            String qformat = "";
1173
            String abstrpath = null;
1174

    
1175
            // read the params
1176
            if (params.containsKey("docid")) {
1177
                docs = (String[]) params.get("docid");
1178
            }
1179
            if (params.containsKey("qformat")) {
1180
                qformat = ((String[]) params.get("qformat"))[0];
1181
            }
1182
            // the param for only metadata (eml)
1183
            // we don't support read a eml document without inline data now.
1184
            /*if (params.containsKey("inlinedata")) {
1185

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

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

    
1217
                        // case docid="http://.../filename"
1218
                    } else {
1219
                        docid = docs[i];
1220
                        if (zip) {
1221
                            addDocToZip(request, docid, zout, user, groups);
1222
                        } else {
1223
                            readFromURLConnection(response, docid);
1224
                        }
1225
                    }
1226

    
1227
                } catch (MalformedURLException mue) {
1228
                    docid = docs[i];
1229
                    if (zip) {
1230
                        addDocToZip(request, docid, zout, user, groups);
1231
                    } else {
1232
                        readFromMetacat(request, response, docid, qformat,
1233
                                abstrpath, user, groups, zip, zout,
1234
                                withInlineData, params);
1235
                    }
1236
                }
1237
            }
1238

    
1239
            if (zip) {
1240
                zout.finish(); //terminate the zip file
1241
                zout.close(); //close the zip stream
1242
            }
1243

    
1244
        } catch (McdbDocNotFoundException notFoundE) {
1245
            // To handle doc not found exception
1246
            // the docid which didn't be found
1247
            String notFoundDocId = notFoundE.getUnfoundDocId();
1248
            String notFoundRevision = notFoundE.getUnfoundRevision();
1249
            logMetacat.warn("Missed id: " + notFoundDocId);
1250
            logMetacat.warn("Missed rev: " + notFoundRevision);
1251
            try {
1252
                // read docid from remote server
1253
                readFromRemoteMetaCat(response, notFoundDocId,
1254
                        notFoundRevision, user, passWord, out, zip, zout);
1255
                // Close zout outputstream
1256
                if (zout != null) {
1257
                    zout.close();
1258
                }
1259
                // close output stream
1260
                if (out != null) {
1261
                    out.close();
1262
                }
1263

    
1264
            } catch (Exception exc) {
1265
                logMetacat.error(
1266
                        "Erorr in MetacatServlet.hanldReadAction: "
1267
                                + exc.getMessage());
1268
                try {
1269
                    if (out != null) {
1270
                        response.setContentType("text/xml");
1271
                        // Send back error message by printWriter
1272
                        pw = new PrintWriter(out);
1273
                        pw.println("<?xml version=\"1.0\"?>");
1274
                        pw.println("<error>");
1275
                        pw.println(notFoundE.getMessage());
1276
                        pw.println("</error>");
1277
                        pw.close();
1278
                        out.close();
1279

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

    
1306
                if (out != null) {
1307
                    response.setContentType("text/xml"); //MIME type
1308
                    pw = new PrintWriter(out);
1309
                    pw.println("<?xml version=\"1.0\"?>");
1310
                    pw.println("<error>");
1311
                    pw.println(e.getMessage());
1312
                    pw.println("</error>");
1313
                    pw.close();
1314
                    out.close();
1315
                } else {
1316
                    response.setContentType("text/xml"); //MIME type
1317
                    // Send back error message if out = null
1318
                    if (pw == null) {
1319
                        pw = response.getWriter();
1320
                    }
1321
                    pw.println("<?xml version=\"1.0\"?>");
1322
                    pw.println("<error>");
1323
                    pw.println(e.getMessage());
1324
                    pw.println("</error>");
1325
                    pw.close();
1326

    
1327
                }
1328
                // Close zip output stream
1329
                if (zout != null) {
1330
                    zout.close();
1331
                }
1332

    
1333
            } catch (IOException ioe) {
1334
                logMetacat.error("Problem with the servlet output "
1335
                        + "in MetacatServlet.handleReadAction: "
1336
                        + ioe.getMessage());
1337
                ioe.printStackTrace(System.out);
1338

    
1339
            }
1340

    
1341
            logMetacat.error(
1342
                    "Error in MetacatServlet.handleReadAction: "
1343
                            + e.getMessage());
1344
            //e.printStackTrace(System.out);
1345
        }
1346
    }
1347

    
1348
    /** read metadata or data from Metacat
1349
     */
1350
    private void readFromMetacat(HttpServletRequest request,
1351
            HttpServletResponse response, String docid, String qformat,
1352
            String abstrpath, String user, String[] groups, boolean zip,
1353
            ZipOutputStream zout, boolean withInlineData, Hashtable params)
1354
            throws ClassNotFoundException, IOException, SQLException,
1355
            McdbException, Exception
1356
    {
1357

    
1358
        try {
1359
            
1360
            // here is hack for handle docid=john.10(in order to tell mike.jim.10.1
1361
            // mike.jim.10, we require to provide entire docid with rev). But
1362
            // some old client they only provide docid without rev, so we need
1363
            // to handle this suituation. First we will check how many
1364
            // seperator here, if only one, we will append the rev in xml_documents
1365
            // to the id.
1366
            docid = appendRev(docid);
1367
         
1368
            DocumentImpl doc = new DocumentImpl(docid);
1369

    
1370
            //check the permission for read
1371
            if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1372
                Exception e = new Exception("User " + user
1373
                        + " does not have permission"
1374
                        + " to read the document with the docid " + docid);
1375

    
1376
                throw e;
1377
            }
1378

    
1379
            if (doc.getRootNodeID() == 0) {
1380
                // this is data file
1381
                String filepath = MetaCatUtil.getOption("datafilepath");
1382
                if (!filepath.endsWith("/")) {
1383
                    filepath += "/";
1384
                }
1385
                String filename = filepath + docid;
1386
                FileInputStream fin = null;
1387
                fin = new FileInputStream(filename);
1388

    
1389
                //MIME type
1390
                String contentType = getServletContext().getMimeType(filename);
1391
                if (contentType == null) {
1392
                    ContentTypeProvider provider = new ContentTypeProvider(
1393
                            docid);
1394
                    contentType = provider.getContentType();
1395
                    logMetacat.warn("Final contenttype is: "
1396
                            + contentType);
1397
                }
1398

    
1399
                response.setContentType(contentType);
1400
                // if we decide to use "application/octet-stream" for all data
1401
                // returns
1402
                // response.setContentType("application/octet-stream");
1403

    
1404
                try {
1405

    
1406
                    ServletOutputStream out = response.getOutputStream();
1407
                    byte[] buf = new byte[4 * 1024]; // 4K buffer
1408
                    int b = fin.read(buf);
1409
                    while (b != -1) {
1410
                        out.write(buf, 0, b);
1411
                        b = fin.read(buf);
1412
                    }
1413
                } finally {
1414
                    if (fin != null) fin.close();
1415
                }
1416

    
1417
            } else {
1418
                // this is metadata doc
1419
                if (qformat.equals("xml") || qformat.equals("")) {
1420
                    // if equals "", that means no qformat is specified. hence
1421
                    // by default the document should be returned in xml format
1422
                    // set content type first
1423
                    response.setContentType("text/xml"); //MIME type
1424
                    PrintWriter out = response.getWriter();
1425
                    doc.toXml(out, user, groups, withInlineData);
1426
                } else {
1427
                    response.setContentType("text/html"); //MIME type
1428
                    PrintWriter out = response.getWriter();
1429

    
1430
                    // Look up the document type
1431
                    String doctype = doc.getDoctype();
1432
                    // Transform the document to the new doctype
1433
                    DBTransform dbt = new DBTransform();
1434
                    dbt.transformXMLDocument(doc.toString(user, groups,
1435
                            withInlineData), doctype, "-//W3C//HTML//EN",
1436
                            qformat, out, params);
1437
                }
1438

    
1439
            }
1440
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1441
                    docid, "read");
1442
        } catch (Exception except) {
1443
            throw except;
1444
        }
1445
    }
1446

    
1447
    /**
1448
     * read data from URLConnection
1449
     */
1450
    private void readFromURLConnection(HttpServletResponse response,
1451
            String docid) throws IOException, MalformedURLException
1452
    {
1453
        ServletOutputStream out = response.getOutputStream();
1454
        String contentType = getServletContext().getMimeType(docid); //MIME
1455
                                                                     // type
1456
        if (contentType == null) {
1457
            if (docid.endsWith(".xml")) {
1458
                contentType = "text/xml";
1459
            } else if (docid.endsWith(".css")) {
1460
                contentType = "text/css";
1461
            } else if (docid.endsWith(".dtd")) {
1462
                contentType = "text/plain";
1463
            } else if (docid.endsWith(".xsd")) {
1464
                contentType = "text/xml";
1465
            } else if (docid.endsWith("/")) {
1466
                contentType = "text/html";
1467
            } else {
1468
                File f = new File(docid);
1469
                if (f.isDirectory()) {
1470
                    contentType = "text/html";
1471
                } else {
1472
                    contentType = "application/octet-stream";
1473
                }
1474
            }
1475
        }
1476
        response.setContentType(contentType);
1477
        // if we decide to use "application/octet-stream" for all data returns
1478
        // response.setContentType("application/octet-stream");
1479

    
1480
        // this is http url
1481
        URL url = new URL(docid);
1482
        BufferedInputStream bis = null;
1483
        try {
1484
            bis = new BufferedInputStream(url.openStream());
1485
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1486
            int b = bis.read(buf);
1487
            while (b != -1) {
1488
                out.write(buf, 0, b);
1489
                b = bis.read(buf);
1490
            }
1491
        } finally {
1492
            if (bis != null) bis.close();
1493
        }
1494

    
1495
    }
1496

    
1497
    /**
1498
     * read file/doc and write to ZipOutputStream
1499
     *
1500
     * @param docid
1501
     * @param zout
1502
     * @param user
1503
     * @param groups
1504
     * @throws ClassNotFoundException
1505
     * @throws IOException
1506
     * @throws SQLException
1507
     * @throws McdbException
1508
     * @throws Exception
1509
     */
1510
    private void addDocToZip(HttpServletRequest request, String docid,
1511
            ZipOutputStream zout, String user, String[] groups) throws
1512
            ClassNotFoundException, IOException, SQLException, McdbException,
1513
            Exception
1514
    {
1515
        byte[] bytestring = null;
1516
        ZipEntry zentry = null;
1517

    
1518
        try {
1519
            URL url = new URL(docid);
1520

    
1521
            // this http url; read from URLConnection; add to zip
1522
            zentry = new ZipEntry(docid);
1523
            zout.putNextEntry(zentry);
1524
            BufferedInputStream bis = null;
1525
            try {
1526
                bis = new BufferedInputStream(url.openStream());
1527
                byte[] buf = new byte[4 * 1024]; // 4K buffer
1528
                int b = bis.read(buf);
1529
                while (b != -1) {
1530
                    zout.write(buf, 0, b);
1531
                    b = bis.read(buf);
1532
                }
1533
            } finally {
1534
                if (bis != null) bis.close();
1535
            }
1536
            zout.closeEntry();
1537

    
1538
        } catch (MalformedURLException mue) {
1539

    
1540
            // this is metacat doc (data file or metadata doc)
1541
            try {
1542
                DocumentImpl doc = new DocumentImpl(docid);
1543

    
1544
                //check the permission for read
1545
                if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1546
                    Exception e = new Exception("User " + user
1547
                            + " does not have "
1548
                            + "permission to read the document with the docid "
1549
                            + docid);
1550
                    throw e;
1551
                }
1552

    
1553
                if (doc.getRootNodeID() == 0) {
1554
                    // this is data file; add file to zip
1555
                    String filepath = MetaCatUtil.getOption("datafilepath");
1556
                    if (!filepath.endsWith("/")) {
1557
                        filepath += "/";
1558
                    }
1559
                    String filename = filepath + docid;
1560
                    FileInputStream fin = null;
1561
                    fin = new FileInputStream(filename);
1562
                    try {
1563

    
1564
                        zentry = new ZipEntry(docid);
1565
                        zout.putNextEntry(zentry);
1566
                        byte[] buf = new byte[4 * 1024]; // 4K buffer
1567
                        int b = fin.read(buf);
1568
                        while (b != -1) {
1569
                            zout.write(buf, 0, b);
1570
                            b = fin.read(buf);
1571
                        }
1572
                    } finally {
1573
                        if (fin != null) fin.close();
1574
                    }
1575
                    zout.closeEntry();
1576

    
1577
                } else {
1578
                    // this is metadata doc; add doc to zip
1579
                    bytestring = doc.toString().getBytes();
1580
                    zentry = new ZipEntry(docid + ".xml");
1581
                    zentry.setSize(bytestring.length);
1582
                    zout.putNextEntry(zentry);
1583
                    zout.write(bytestring, 0, bytestring.length);
1584
                    zout.closeEntry();
1585
                }
1586
                EventLog.getInstance().log(request.getRemoteAddr(), user,
1587
                        docid, "read");
1588
            } catch (Exception except) {
1589
                throw except;
1590
            }
1591
        }
1592
    }
1593

    
1594
    /**
1595
     * If metacat couldn't find a data file or document locally, it will read
1596
     * this docid from its home server. This is for the replication feature
1597
     */
1598
    private void readFromRemoteMetaCat(HttpServletResponse response,
1599
            String docid, String rev, String user, String password,
1600
            ServletOutputStream out, boolean zip, ZipOutputStream zout)
1601
            throws Exception
1602
    {
1603
        // Create a object of RemoteDocument, "" is for zipEntryPath
1604
        RemoteDocument remoteDoc = new RemoteDocument(docid, rev, user,
1605
                password, "");
1606
        String docType = remoteDoc.getDocType();
1607
        // Only read data file
1608
        if (docType.equals("BIN")) {
1609
            // If it is zip format
1610
            if (zip) {
1611
                remoteDoc.readDocumentFromRemoteServerByZip(zout);
1612
            } else {
1613
                if (out == null) {
1614
                    out = response.getOutputStream();
1615
                }
1616
                response.setContentType("application/octet-stream");
1617
                remoteDoc.readDocumentFromRemoteServer(out);
1618
            }
1619
        } else {
1620
            throw new Exception("Docid: " + docid + "." + rev
1621
                    + " couldn't find");
1622
        }
1623
    }
1624

    
1625
    /**
1626
     * Handle the database putdocument request and write an XML document to the
1627
     * database connection
1628
     */
1629
    private void handleInsertOrUpdateAction(HttpServletRequest request,
1630
            HttpServletResponse response, PrintWriter out, Hashtable params,
1631
            String user, String[] groups)
1632
    {
1633
        DBConnection dbConn = null;
1634
        int serialNumber = -1;
1635

    
1636
        if(params.get("docid") == null){
1637
            out.println("<?xml version=\"1.0\"?>");
1638
            out.println("<error>");
1639
            out.println("Docid not specified");
1640
            out.println("</error>");
1641
            logMetacat.error("Docid not specified");
1642
            return;
1643
        }
1644
        
1645
        if(!MetaCatUtil.canInsertOrUpdate(user, groups)){
1646
        	out.println("<?xml version=\"1.0\"?>");
1647
            out.println("<error>");
1648
            out.println("User '" + user + "' not allowed to insert and update");
1649
            out.println("</error>");
1650
            logMetacat.error("User '" + user + "' not allowed to insert and update");
1651
            return;
1652
        }
1653

    
1654
        try {
1655
            // Get the document indicated
1656
            String[] doctext = (String[]) params.get("doctext");
1657
            String pub = null;
1658
            if (params.containsKey("public")) {
1659
                pub = ((String[]) params.get("public"))[0];
1660
            }
1661

    
1662
            StringReader dtd = null;
1663
            if (params.containsKey("dtdtext")) {
1664
                String[] dtdtext = (String[]) params.get("dtdtext");
1665
                try {
1666
                    if (!dtdtext[0].equals("")) {
1667
                        dtd = new StringReader(dtdtext[0]);
1668
                    }
1669
                } catch (NullPointerException npe) {
1670
                }
1671
            }
1672

    
1673
            if(doctext == null){
1674
                out.println("<?xml version=\"1.0\"?>");
1675
                out.println("<error>");
1676
                out.println("Document text not submitted");
1677
                out.println("</error>");
1678
                return;
1679
            }
1680

    
1681
            StringReader xml = new StringReader(doctext[0]);
1682
            boolean validate = false;
1683
            DocumentImplWrapper documentWrapper = null;
1684
            try {
1685
                // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ...
1686
                // >
1687
                // in order to decide whether to use validation parser
1688
                validate = needDTDValidation(xml);
1689
                if (validate) {
1690
                    // set a dtd base validation parser
1691
                    String rule = DocumentImpl.DTD;
1692
                    documentWrapper = new DocumentImplWrapper(rule, validate);
1693
                } else if (needSchemaValidation(xml)) {
1694
                    // for eml2
1695
                    String namespace = findNamespace(xml);
1696
                    if (namespace.compareTo(DocumentImpl.EML2_0_0NAMESPACE) == 0
1697
                                || namespace.compareTo(
1698
                                DocumentImpl.EML2_0_1NAMESPACE) == 0) {
1699
                        // set eml2 base validation parser
1700
                        String rule = DocumentImpl.EML200;
1701
                        // using emlparser to check id validation
1702
                        EMLParser parser = new EMLParser(doctext[0]);
1703
                        documentWrapper = new DocumentImplWrapper(rule, true);
1704
                    } else if (namespace.compareTo(
1705
                                DocumentImpl.EML2_1_0NAMESPACE) == 0) {
1706
                        // set eml2 base validation parser
1707
                        String rule = DocumentImpl.EML210;
1708
                        // using emlparser to check id validation
1709
                        EMLParser parser = new EMLParser(doctext[0]);
1710
                        documentWrapper = new DocumentImplWrapper(rule, true);
1711
                    } else {
1712
                        // set schema base validation parser
1713
                        String rule = DocumentImpl.SCHEMA;
1714
                        documentWrapper = new DocumentImplWrapper(rule, true);
1715
                    }
1716
                } else {
1717
                    documentWrapper = new DocumentImplWrapper("", false);
1718
                }
1719

    
1720
                String[] action = (String[]) params.get("action");
1721
                String[] docid = (String[]) params.get("docid");
1722
                String newdocid = null;
1723

    
1724
                String doAction = null;
1725
                if (action[0].equals("insert")) {
1726
                    doAction = "INSERT";
1727
                } else if (action[0].equals("update")) {
1728
                    doAction = "UPDATE";
1729
                }
1730

    
1731
                try {
1732
                    // get a connection from the pool
1733
                    dbConn = DBConnectionPool
1734
                            .getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1735
                    serialNumber = dbConn.getCheckOutSerialNumber();
1736

    
1737
                    // write the document to the database
1738
                    try {
1739
                        String accNumber = docid[0];
1740
                        logMetacat.warn("" + doAction + " "
1741
                                + accNumber + "...");
1742
                        if (accNumber.equals("")) {
1743
                            accNumber = null;
1744
                        }
1745
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1746
                                doAction, accNumber, user, groups);
1747
                        EventLog.getInstance().log(request.getRemoteAddr(),
1748
                                user, accNumber, action[0]);
1749
                    } catch (NullPointerException npe) {
1750
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1751
                                doAction, null, user, groups);
1752
                        EventLog.getInstance().log(request.getRemoteAddr(),
1753
                                user, "", action[0]);
1754
                    }
1755
                }
1756
                finally {
1757
                    // Return db connection
1758
                    DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1759
                }
1760

    
1761
                // set content type and other response header fields first
1762
                //response.setContentType("text/xml");
1763
                out.println("<?xml version=\"1.0\"?>");
1764
                out.println("<success>");
1765
                out.println("<docid>" + newdocid + "</docid>");
1766
                out.println("</success>");
1767

    
1768
            } catch (NullPointerException npe) {
1769
                //response.setContentType("text/xml");
1770
                out.println("<?xml version=\"1.0\"?>");
1771
                out.println("<error>");
1772
                out.println(npe.getMessage());
1773
                out.println("</error>");
1774
            }
1775
        } catch (Exception e) {
1776
            //response.setContentType("text/xml");
1777
            out.println("<?xml version=\"1.0\"?>");
1778
            out.println("<error>");
1779
            out.println(e.getMessage());
1780
            out.println("</error>");
1781
        }
1782
    }
1783

    
1784
    /**
1785
     * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... > in
1786
     * order to decide whether to use validation parser
1787
     */
1788
    private static boolean needDTDValidation(StringReader xmlreader)
1789
            throws IOException
1790
    {
1791

    
1792
        StringBuffer cbuff = new StringBuffer();
1793
        java.util.Stack st = new java.util.Stack();
1794
        boolean validate = false;
1795
        int c;
1796
        int inx;
1797

    
1798
        // read from the stream until find the keywords
1799
        while ((st.empty() || st.size() < 4) && ((c = xmlreader.read()) != -1)) {
1800
            cbuff.append((char) c);
1801

    
1802
            // "<!DOCTYPE" keyword is found; put it in the stack
1803
            if ((inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1) {
1804
                cbuff = new StringBuffer();
1805
                st.push("<!DOCTYPE");
1806
            }
1807
            // "PUBLIC" keyword is found; put it in the stack
1808
            if ((inx = cbuff.toString().indexOf("PUBLIC")) != -1) {
1809
                cbuff = new StringBuffer();
1810
                st.push("PUBLIC");
1811
            }
1812
            // "SYSTEM" keyword is found; put it in the stack
1813
            if ((inx = cbuff.toString().indexOf("SYSTEM")) != -1) {
1814
                cbuff = new StringBuffer();
1815
                st.push("SYSTEM");
1816
            }
1817
            // ">" character is found; put it in the stack
1818
            // ">" is found twice: fisrt from <?xml ...?>
1819
            // and second from <!DOCTYPE ... >
1820
            if ((inx = cbuff.toString().indexOf(">")) != -1) {
1821
                cbuff = new StringBuffer();
1822
                st.push(">");
1823
            }
1824
        }
1825

    
1826
        // close the stream
1827
        xmlreader.reset();
1828

    
1829
        // check the stack whether it contains the keywords:
1830
        // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1831
        if (st.size() == 4) {
1832
            if (((String) st.pop()).equals(">")
1833
                    && (((String) st.peek()).equals("PUBLIC") | ((String) st
1834
                            .pop()).equals("SYSTEM"))
1835
                    && ((String) st.pop()).equals("<!DOCTYPE")) {
1836
                validate = true;
1837
            }
1838
        }
1839

    
1840
        logMetacat.warn("Validation for dtd is " + validate);
1841
        return validate;
1842
    }
1843

    
1844
    // END OF INSERT/UPDATE SECTION
1845

    
1846
    /* check if the xml string contains key words to specify schema loocation */
1847
    private boolean needSchemaValidation(StringReader xml) throws IOException
1848
    {
1849
        boolean needSchemaValidate = false;
1850
        if (xml == null) {
1851
            logMetacat.warn("Validation for schema is "
1852
                    + needSchemaValidate);
1853
            return needSchemaValidate;
1854
        }
1855
        logMetacat.info("before get target line");
1856
        String targetLine = getSchemaLine(xml);
1857
        logMetacat.info("after get target line");
1858
        // to see if the second line contain some keywords
1859
        if (targetLine != null
1860
                && (targetLine.indexOf(SCHEMALOCATIONKEYWORD) != -1 || targetLine
1861
                        .indexOf(NONAMESPACELOCATION) != -1)) {
1862
            // if contains schema location key word, should be validate
1863
            needSchemaValidate = true;
1864
        }
1865

    
1866
        logMetacat.warn("Validation for schema is "
1867
                + needSchemaValidate);
1868
        return needSchemaValidate;
1869

    
1870
    }
1871

    
1872
    /* check if the xml string contains key words to specify schema loocation */
1873
    private String findNamespace(StringReader xml) throws IOException
1874
    {
1875
        String namespace = null;
1876

    
1877
        String eml2_0_0NameSpace = DocumentImpl.EML2_0_0NAMESPACE;
1878
        String eml2_0_1NameSpace = DocumentImpl.EML2_0_1NAMESPACE;
1879
        String eml2_1_0NameSpace = DocumentImpl.EML2_1_0NAMESPACE;
1880

    
1881
        if (xml == null) {
1882
            logMetacat.warn("Validation for schema is "
1883
                    + namespace);
1884
            return namespace;
1885
        }
1886
        String targetLine = getSchemaLine(xml);
1887

    
1888
        if (targetLine != null) {
1889

    
1890
            int startIndex = targetLine.indexOf(SCHEMALOCATIONKEYWORD);
1891
            int start = 1;
1892
            int end = 1;
1893
            String schemaLocation = null;
1894
            int count = 0;
1895
            if (startIndex != -1) {
1896
                for (int i = startIndex; i < targetLine.length(); i++) {
1897
                    if (targetLine.charAt(i) == '"') {
1898
                        count++;
1899
                    }
1900
                    if (targetLine.charAt(i) == '"' && count == 1) {
1901
                        start = i;
1902
                    }
1903
                    if (targetLine.charAt(i) == '"' && count == 2) {
1904
                        end = i;
1905
                        break;
1906
                    }
1907
                }
1908
            }
1909
            schemaLocation = targetLine.substring(start + 1, end);
1910
            logMetacat.info("schemaLocation in xml is: "
1911
                    + schemaLocation);
1912
            if (schemaLocation.indexOf(eml2_0_0NameSpace) != -1) {
1913
                namespace = eml2_0_0NameSpace;
1914
            } else if (schemaLocation.indexOf(eml2_0_1NameSpace) != -1) {
1915
                namespace = eml2_0_1NameSpace;
1916
            } else if (schemaLocation.indexOf(eml2_1_0NameSpace) != -1) {
1917
                namespace = eml2_1_0NameSpace;
1918
            }
1919
        }
1920

    
1921
        logMetacat.warn("Validation for eml is " + namespace);
1922

    
1923
        return namespace;
1924

    
1925
    }
1926

    
1927
    private String getSchemaLine(StringReader xml) throws IOException
1928
    {
1929
        // find the line
1930
        String secondLine = null;
1931
        int count = 0;
1932
        int endIndex = 0;
1933
        int startIndex = 0;
1934
        final int TARGETNUM = 2;
1935
        StringBuffer buffer = new StringBuffer();
1936
        boolean comment = false;
1937
        char thirdPreviousCharacter = '?';
1938
        char secondPreviousCharacter = '?';
1939
        char previousCharacter = '?';
1940
        char currentCharacter = '?';
1941
        int tmp = xml.read();
1942
        while (tmp != -1) {
1943
            currentCharacter = (char)tmp;
1944
            //in a comment
1945
            if (currentCharacter == '-' && previousCharacter == '-'
1946
                    && secondPreviousCharacter == '!'
1947
                    && thirdPreviousCharacter == '<') {
1948
                comment = true;
1949
            }
1950
            //out of comment
1951
            if (comment && currentCharacter == '>' && previousCharacter == '-'
1952
                    && secondPreviousCharacter == '-') {
1953
                comment = false;
1954
            }
1955

    
1956
            //this is not comment
1957
            if (currentCharacter != '!' && previousCharacter == '<' && !comment) {
1958
                count++;
1959
            }
1960
            // get target line
1961
            if (count == TARGETNUM && currentCharacter != '>') {
1962
                buffer.append(currentCharacter);
1963
            }
1964
            if (count == TARGETNUM && currentCharacter == '>') {
1965
                break;
1966
            }
1967
            thirdPreviousCharacter = secondPreviousCharacter;
1968
            secondPreviousCharacter = previousCharacter;
1969
            previousCharacter = currentCharacter;
1970
            tmp = xml.read();
1971
        }
1972
        secondLine = buffer.toString();
1973
        logMetacat.info("the second line string is: " + secondLine);
1974
        
1975
        xml.reset();
1976
        return secondLine;
1977
    }
1978

    
1979
    /**
1980
     * Handle the database delete request and delete an XML document from the
1981
     * database connection
1982
     */
1983
    private void handleDeleteAction(PrintWriter out, Hashtable params,
1984
            HttpServletRequest request, HttpServletResponse response,
1985
            String user, String[] groups)
1986
    {
1987

    
1988
        String[] docid = (String[]) params.get("docid");
1989

    
1990
        if(docid == null){
1991
          response.setContentType("text/xml");
1992
          out.println("<?xml version=\"1.0\"?>");
1993
          out.println("<error>");
1994
          out.println("Docid not specified.");
1995
          out.println("</error>");
1996
          logMetacat.error("Docid not specified for the document to be deleted.");
1997
        } else {
1998

    
1999
            // delete the document from the database
2000
            try {
2001

    
2002
                try {
2003
                    // null means notify server is null
2004
                    DocumentImpl.delete(docid[0], user, groups, null);
2005
                    EventLog.getInstance().log(request.getRemoteAddr(),
2006
                                               user, docid[0], "delete");
2007
                    response.setContentType("text/xml");
2008
                    out.println("<?xml version=\"1.0\"?>");
2009
                    out.println("<success>");
2010
                    out.println("Document deleted.");
2011
                    out.println("</success>");
2012
                    logMetacat.warn("Document deleted.");
2013
                }
2014
                catch (AccessionNumberException ane) {
2015
                    response.setContentType("text/xml");
2016
                    out.println("<?xml version=\"1.0\"?>");
2017
                    out.println("<error>");
2018
                    //out.println("Error deleting document!!!");
2019
                    out.println(ane.getMessage());
2020
                    out.println("</error>");
2021
                    logMetacat.error("Document could not be deleted: " 
2022
                    		+ ane.getMessage());
2023
                }
2024
            }
2025
            catch (Exception e) {
2026
                response.setContentType("text/xml");
2027
                out.println("<?xml version=\"1.0\"?>");
2028
                out.println("<error>");
2029
                out.println(e.getMessage());
2030
                out.println("</error>");
2031
                logMetacat.error("Document could not be deleted: " 
2032
                		+ e.getMessage());
2033
            }
2034
        }
2035
    }
2036

    
2037
    /**
2038
     * Handle the validation request and return the results to the requestor
2039
     */
2040
    private void handleValidateAction(PrintWriter out, Hashtable params)
2041
    {
2042

    
2043
        // Get the document indicated
2044
        String valtext = null;
2045
        DBConnection dbConn = null;
2046
        int serialNumber = -1;
2047

    
2048
        try {
2049
            valtext = ((String[]) params.get("valtext"))[0];
2050
        } catch (Exception nullpe) {
2051

    
2052
            String docid = null;
2053
            try {
2054
                // Find the document id number
2055
                docid = ((String[]) params.get("docid"))[0];
2056

    
2057
                // Get the document indicated from the db
2058
                DocumentImpl xmldoc = new DocumentImpl(docid);
2059
                valtext = xmldoc.toString();
2060

    
2061
            } catch (NullPointerException npe) {
2062

    
2063
                out.println("<error>Error getting document ID: " + docid
2064
                        + "</error>");
2065
                //if ( conn != null ) { util.returnConnection(conn); }
2066
                return;
2067
            } catch (Exception e) {
2068

    
2069
                out.println(e.getMessage());
2070
            }
2071
        }
2072

    
2073
        try {
2074
            // get a connection from the pool
2075
            dbConn = DBConnectionPool
2076
                    .getDBConnection("MetaCatServlet.handleValidateAction");
2077
            serialNumber = dbConn.getCheckOutSerialNumber();
2078
            DBValidate valobj = new DBValidate(saxparser, dbConn);
2079
            boolean valid = valobj.validateString(valtext);
2080

    
2081
            // set content type and other response header fields first
2082

    
2083
            out.println(valobj.returnErrors());
2084

    
2085
        } catch (NullPointerException npe2) {
2086
            // set content type and other response header fields first
2087

    
2088
            out.println("<error>Error validating document.</error>");
2089
        } catch (Exception e) {
2090

    
2091
            out.println(e.getMessage());
2092
        } finally {
2093
            // Return db connection
2094
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2095
        }
2096
    }
2097

    
2098
    /**
2099
     * Handle "getrevsionanddoctype" action Given a docid, return it's current
2100
     * revision and doctype from data base The output is String look like
2101
     * "rev;doctype"
2102
     */
2103
    private void handleGetRevisionAndDocTypeAction(PrintWriter out,
2104
            Hashtable params)
2105
    {
2106
        // To store doc parameter
2107
        String[] docs = new String[10];
2108
        // Store a single doc id
2109
        String givenDocId = null;
2110
        // Get docid from parameters
2111
        if (params.containsKey("docid")) {
2112
            docs = (String[]) params.get("docid");
2113
        }
2114
        // Get first docid form string array
2115
        givenDocId = docs[0];
2116

    
2117
        try {
2118
            // Make sure there is a docid
2119
            if (givenDocId == null || givenDocId.equals("")) { throw new Exception(
2120
                    "User didn't specify docid!"); }//if
2121

    
2122
            // Create a DBUtil object
2123
            DBUtil dbutil = new DBUtil();
2124
            // Get a rev and doctype
2125
            String revAndDocType = dbutil
2126
                    .getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
2127
            out.println(revAndDocType);
2128

    
2129
        } catch (Exception e) {
2130
            // Handle exception
2131
            out.println("<?xml version=\"1.0\"?>");
2132
            out.println("<error>");
2133
            out.println(e.getMessage());
2134
            out.println("</error>");
2135
        }
2136

    
2137
    }
2138

    
2139
    /**
2140
     * Handle "getaccesscontrol" action. Read Access Control List from db
2141
     * connection in XML format
2142
     */
2143
    private void handleGetAccessControlAction(PrintWriter out,
2144
            Hashtable params, HttpServletResponse response, String username,
2145
            String[] groupnames)
2146
    {
2147
        DBConnection dbConn = null;
2148
        int serialNumber = -1;
2149
        String docid = ((String[]) params.get("docid"))[0];
2150

    
2151
        try {
2152

    
2153
            // get connection from the pool
2154
            dbConn = DBConnectionPool
2155
                    .getDBConnection("MetaCatServlet.handleGetAccessControlAction");
2156
            serialNumber = dbConn.getCheckOutSerialNumber();
2157
            AccessControlList aclobj = new AccessControlList(dbConn);
2158
            String acltext = aclobj.getACL(docid, username, groupnames);
2159
            out.println(acltext);
2160

    
2161
        } catch (Exception e) {
2162
            out.println("<?xml version=\"1.0\"?>");
2163
            out.println("<error>");
2164
            out.println(e.getMessage());
2165
            out.println("</error>");
2166
        } finally {
2167
            // Retrun db connection to pool
2168
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2169
        }
2170
    }
2171

    
2172
    /**
2173
     * Handle the "getprincipals" action. Read all principals from
2174
     * authentication scheme in XML format
2175
     */
2176
    private void handleGetPrincipalsAction(PrintWriter out, String user,
2177
            String password)
2178
    {
2179
        try {
2180
            AuthSession auth = new AuthSession();
2181
            String principals = auth.getPrincipals(user, password);
2182
            out.println(principals);
2183

    
2184
        } catch (Exception e) {
2185
            out.println("<?xml version=\"1.0\"?>");
2186
            out.println("<error>");
2187
            out.println(e.getMessage());
2188
            out.println("</error>");
2189
        }
2190
    }
2191

    
2192
    /**
2193
     * Handle "getdoctypes" action. Read all doctypes from db connection in XML
2194
     * format
2195
     */
2196
    private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
2197
            HttpServletResponse response)
2198
    {
2199
        try {
2200
            DBUtil dbutil = new DBUtil();
2201
            String doctypes = dbutil.readDoctypes();
2202
            out.println(doctypes);
2203
        } catch (Exception e) {
2204
            out.println("<?xml version=\"1.0\"?>");
2205
            out.println("<error>");
2206
            out.println(e.getMessage());
2207
            out.println("</error>");
2208
        }
2209
    }
2210

    
2211
    /**
2212
     * Handle the "getdtdschema" action. Read DTD or Schema file for a given
2213
     * doctype from Metacat catalog system
2214
     */
2215
    private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
2216
            HttpServletResponse response)
2217
    {
2218

    
2219
        String doctype = null;
2220
        String[] doctypeArr = (String[]) params.get("doctype");
2221

    
2222
        // get only the first doctype specified in the list of doctypes
2223
        // it could be done for all doctypes in that list
2224
        if (doctypeArr != null) {
2225
            doctype = ((String[]) params.get("doctype"))[0];
2226
        }
2227

    
2228
        try {
2229
            DBUtil dbutil = new DBUtil();
2230
            String dtdschema = dbutil.readDTDSchema(doctype);
2231
            out.println(dtdschema);
2232

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

    
2240
    }
2241

    
2242
    /**
2243
     * Handle the "getlastdocid" action. Get the latest docid with rev number
2244
     * from db connection in XML format
2245
     */
2246
    private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
2247
            HttpServletResponse response)
2248
    {
2249

    
2250
        String scope = ((String[]) params.get("scope"))[0];
2251
        if (scope == null) {
2252
            scope = ((String[]) params.get("username"))[0];
2253
        }
2254

    
2255
        try {
2256

    
2257
            DBUtil dbutil = new DBUtil();
2258
            String lastDocid = dbutil.getMaxDocid(scope);
2259
            out.println("<?xml version=\"1.0\"?>");
2260
            out.println("<lastDocid>");
2261
            out.println("  <scope>" + scope + "</scope>");
2262
            out.println("  <docid>" + lastDocid + "</docid>");
2263
            out.println("</lastDocid>");
2264

    
2265
        } catch (Exception e) {
2266
            out.println("<?xml version=\"1.0\"?>");
2267
            out.println("<error>");
2268
            out.println(e.getMessage());
2269
            out.println("</error>");
2270
        }
2271
    }
2272

    
2273
    /**
2274
     * Print a report from the event log based on filter parameters passed in
2275
     * from the web.
2276
     *
2277
     * @param params the parameters from the web request
2278
     * @param request the http request object for getting request details
2279
     * @param response the http response object for writing output
2280
     */
2281
    private void handleGetLogAction(Hashtable params, HttpServletRequest request,
2282
            HttpServletResponse response, String username, String[] groups)
2283
    {
2284
        try {
2285
            response.setContentType("text/xml");
2286
            PrintWriter out = response.getWriter();
2287

    
2288
            // Check that the user is authenticated as an administrator account
2289
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2290
                out.print("<error>");
2291
                out.print("The user \"" + username +
2292
                        "\" is not authorized for this action.");
2293
                out.print("</error>");
2294
                return;
2295
            }
2296

    
2297
            // Get all of the parameters in the correct formats
2298
            String[] ipAddress = (String[])params.get("ipaddress");
2299
            String[] principal = (String[])params.get("principal");
2300
            String[] docid = (String[])params.get("docid");
2301
            String[] event = (String[])params.get("event");
2302
            String[] startArray = (String[]) params.get("start");
2303
            String[] endArray = (String[]) params.get("end");
2304
            String start = null;
2305
            String end = null;
2306
            if (startArray != null) {
2307
                start = startArray[0];
2308
            }
2309
            if (endArray != null) {
2310
                end = endArray[0];
2311
            }
2312
            Timestamp startDate = null;
2313
            Timestamp endDate = null;
2314
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2315
            try {
2316
                if (start != null) {
2317
                    startDate = new Timestamp((format.parse(start)).getTime());
2318
                }
2319
                if (end != null) {
2320
                    endDate = new Timestamp((format.parse(end)).getTime());
2321
                }
2322
            } catch (ParseException e) {
2323
                System.out.println("Failed to created Timestamp from input.");
2324
            }
2325

    
2326
            // Request the report by passing the filter parameters
2327
            out.println(EventLog.getInstance().getReport(ipAddress, principal,
2328
                    docid, event, startDate, endDate));
2329
            out.close();
2330
        } catch (IOException e) {
2331
            logMetacat.error(
2332
                    "Could not open http response for writing: " + e.getMessage());
2333
        }
2334
    }
2335

    
2336
    /**
2337
     * Rebuild the index for one or more documents. If the docid parameter is
2338
     * provided, rebuild for just that one document or list of documents. If
2339
     * not, then rebuild the index for all documents in the xml_documents
2340
     * table.
2341
     *
2342
     * @param params the parameters from the web request
2343
     * @param request the http request object for getting request details
2344
     * @param response the http response object for writing output
2345
     * @param username the username of the authenticated user
2346
     */
2347
    private void handleBuildIndexAction(Hashtable params,
2348
            HttpServletRequest request, HttpServletResponse response,
2349
            String username, String[] groups)
2350
    {
2351
        // Get all of the parameters in the correct formats
2352
        String[] docid = (String[])params.get("docid");
2353

    
2354
        // Rebuild the indices for appropriate documents
2355
        try {
2356
            response.setContentType("text/xml");
2357
            PrintWriter out = response.getWriter();
2358

    
2359
            // Check that the user is authenticated as an administrator account
2360
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2361
                out.print("<error>");
2362
                out.print("The user \"" + username +
2363
                        "\" is not authorized for this action.");
2364
                out.print("</error>");
2365
                return;
2366
            }
2367

    
2368
            // Process the documents
2369
            out.println("<success>");
2370
            if (docid == null || docid.length == 0) {
2371
                // Process all of the documents
2372
                try {
2373
                    Vector documents = getDocumentList();
2374
                    Iterator it = documents.iterator();
2375
                    while (it.hasNext()) {
2376
                        String id = (String) it.next();
2377
                        buildDocumentIndex(id, out);
2378
                    }
2379
                } catch (SQLException se) {
2380
                    out.print("<error>");
2381
                    out.print(se.getMessage());
2382
                    out.println("</error>");
2383
                }
2384
            } else {
2385
                // Only process the requested documents
2386
                for (int i = 0; i < docid.length; i++) {
2387
                    buildDocumentIndex(docid[i], out);
2388
                }
2389
            }
2390
            out.println("</success>");
2391
            out.close();
2392
        } catch (IOException e) {
2393
            logMetacat.error(
2394
                    "Could not open http response for writing: "
2395
                    + e.getMessage());
2396
        }
2397
    }
2398

    
2399
    /**
2400
     * Build the index for one document by reading the document and
2401
     * calling its buildIndex() method.
2402
     *
2403
     * @param docid the document (with revision) to rebuild
2404
     * @param out the PrintWriter to which output is printed
2405
     */
2406
    private void buildDocumentIndex(String docid, PrintWriter out)
2407
    {
2408
        try {
2409
            DocumentImpl doc = new DocumentImpl(docid, false);
2410
            doc.buildIndex();
2411
            out.print("<docid>" + docid);
2412
            out.println("</docid>");
2413
        } catch (McdbException me) {
2414
            out.print("<error>");
2415
            out.print(me.getMessage());
2416
            out.println("</error>");
2417
        }
2418
    }
2419

    
2420
    /**
2421
     * Handle documents passed to metacat that are encoded using the
2422
     * "multipart/form-data" mime type. This is typically used for uploading
2423
     * data files which may be binary and large.
2424
     */
2425
    private void handleMultipartForm(HttpServletRequest request,
2426
            HttpServletResponse response)
2427
    {
2428
        PrintWriter out = null;
2429
        String action = null;
2430

    
2431
        // Parse the multipart form, and save the parameters in a Hashtable and
2432
        // save the FileParts in a hashtable
2433

    
2434
        Hashtable params = new Hashtable();
2435
        Hashtable fileList = new Hashtable();
2436
        int sizeLimit = (new Integer(MetaCatUtil.getOption("datafilesizelimit")))
2437
                .intValue();
2438
        logMetacat.info(
2439
                "The limit size of data file is: " + sizeLimit);
2440

    
2441
        try {
2442
            // MBJ: need to put filesize limit in Metacat config
2443
            // (metacat.properties)
2444
            MultipartParser mp = new MultipartParser(request,
2445
                    sizeLimit * 1024 * 1024);
2446
            Part part;
2447
            while ((part = mp.readNextPart()) != null) {
2448
                String name = part.getName();
2449

    
2450
                if (part.isParam()) {
2451
                    // it's a parameter part
2452
                    ParamPart paramPart = (ParamPart) part;
2453
                    String value = paramPart.getStringValue();
2454
                    params.put(name, value);
2455
                    if (name.equals("action")) {
2456
                        action = value;
2457
                    }
2458
                } else if (part.isFile()) {
2459
                    // it's a file part
2460
                    FilePart filePart = (FilePart) part;
2461
                    fileList.put(name, filePart);
2462

    
2463
                    // Stop once the first file part is found, otherwise going
2464
                    // onto the
2465
                    // next part prevents access to the file contents. So...for
2466
                    // upload
2467
                    // to work, the datafile must be the last part
2468
                    break;
2469
                }
2470
            }
2471
        } catch (IOException ioe) {
2472
            try {
2473
                out = response.getWriter();
2474
            } catch (IOException ioe2) {
2475
                logMetacat.fatal("Fatal Error: couldn't get response output stream.");
2476
            }
2477
            out.println("<?xml version=\"1.0\"?>");
2478
            out.println("<error>");
2479
            out.println("Error: problem reading multipart data.");
2480
            out.println("</error>");
2481
        }
2482

    
2483
        // Get the session information
2484
        String username = null;
2485
        String password = null;
2486
        String[] groupnames = null;
2487
        String sess_id = null;
2488

    
2489
        // be aware of session expiration on every request
2490
        HttpSession sess = request.getSession(true);
2491
        if (sess.isNew()) {
2492
            // session expired or has not been stored b/w user requests
2493
            username = "public";
2494
            sess.setAttribute("username", username);
2495
        } else {
2496
            username = (String) sess.getAttribute("username");
2497
            password = (String) sess.getAttribute("password");
2498
            groupnames = (String[]) sess.getAttribute("groupnames");
2499
            try {
2500
                sess_id = (String) sess.getId();
2501
            } catch (IllegalStateException ise) {
2502
                System.out
2503
                        .println("error in  handleMultipartForm: this shouldn't "
2504
                                + "happen: the session should be valid: "
2505
                                + ise.getMessage());
2506
            }
2507
        }
2508

    
2509
        // Get the out stream
2510
        try {
2511
            out = response.getWriter();
2512
        } catch (IOException ioe2) {
2513
            logMetacat.error("Fatal Error: couldn't get response "
2514
                    + "output stream.");
2515
        }
2516

    
2517
        if (action.equals("upload")) {
2518
            if (username != null && !username.equals("public")) {
2519
                handleUploadAction(request, out, params, fileList, username,
2520
                        groupnames);
2521
            } else {
2522

    
2523
                out.println("<?xml version=\"1.0\"?>");
2524
                out.println("<error>");
2525
                out.println("Permission denied for " + action);
2526
                out.println("</error>");
2527
            }
2528
        } else {
2529
            /*
2530
             * try { out = response.getWriter(); } catch (IOException ioe2) {
2531
             * System.err.println("Fatal Error: couldn't get response output
2532
             * stream.");
2533
             */
2534
            out.println("<?xml version=\"1.0\"?>");
2535
            out.println("<error>");
2536
            out.println(
2537
                    "Error: action not registered.  Please report this error.");
2538
            out.println("</error>");
2539
        }
2540
        out.close();
2541
    }
2542

    
2543
    /**
2544
     * Handle the upload action by saving the attached file to disk and
2545
     * registering it in the Metacat db
2546
     */
2547
    private void handleUploadAction(HttpServletRequest request,
2548
            PrintWriter out, Hashtable params, Hashtable fileList,
2549
            String username, String[] groupnames)
2550
    {
2551
        //PrintWriter out = null;
2552
        //Connection conn = null;
2553
        String action = null;
2554
        String docid = null;
2555

    
2556
        /*
2557
         * response.setContentType("text/xml"); try { out =
2558
         * response.getWriter(); } catch (IOException ioe2) {
2559
         * System.err.println("Fatal Error: couldn't get response output
2560
         * stream.");
2561
         */
2562

    
2563
        if (params.containsKey("docid")) {
2564
            docid = (String) params.get("docid");
2565
        }
2566

    
2567
        // Make sure we have a docid and datafile
2568
        if (docid != null && fileList.containsKey("datafile")) {
2569

    
2570
            // Get a reference to the file part of the form
2571
            FilePart filePart = (FilePart) fileList.get("datafile");
2572
            String fileName = filePart.getFileName();
2573
            logMetacat.warn("Uploading filename: " + fileName);
2574

    
2575
            // Check if the right file existed in the uploaded data
2576
            if (fileName != null) {
2577

    
2578
                try {
2579
                    //logMetacat.info("Upload datafile " + docid
2580
                    // +"...", 10);
2581
                    //If document get lock data file grant
2582
                    if (DocumentImpl.getDataFileLockGrant(docid)) {
2583
                        // register the file in the database (which generates
2584
                        // an exception
2585
                        //if the docid is not acceptable or other untoward
2586
                        // things happen
2587
                        DocumentImpl.registerDocument(fileName, "BIN", docid,
2588
                                username, groupnames);
2589

    
2590
                        // Save the data file to disk using "docid" as the name
2591
                        dataDirectory.mkdirs();
2592
                        File newFile = new File(dataDirectory, docid);
2593
                        long size = filePart.writeTo(newFile);
2594

    
2595
                        EventLog.getInstance().log(request.getRemoteAddr(),
2596
                                username, docid, "upload");
2597
                        // Force replication this data file
2598
                        // To data file, "insert" and update is same
2599
                        // The fourth parameter is null. Because it is
2600
                        // notification server
2601
                        // and this method is in MetaCatServerlet. It is
2602
                        // original command,
2603
                        // not get force replication info from another metacat
2604
                        ForceReplicationHandler frh = new ForceReplicationHandler(
2605
                                docid, "insert", false, null);
2606

    
2607
                        // set content type and other response header fields
2608
                        // first
2609
                        out.println("<?xml version=\"1.0\"?>");
2610
                        out.println("<success>");
2611
                        out.println("<docid>" + docid + "</docid>");
2612
                        out.println("<size>" + size + "</size>");
2613
                        out.println("</success>");
2614
                    }
2615

    
2616
                } catch (Exception e) {
2617
                    out.println("<?xml version=\"1.0\"?>");
2618
                    out.println("<error>");
2619
                    out.println(e.getMessage());
2620
                    out.println("</error>");
2621
                }
2622
            } else {
2623
                // the field did not contain a file
2624
                out.println("<?xml version=\"1.0\"?>");
2625
                out.println("<error>");
2626
                out.println("The uploaded data did not contain a valid file.");
2627
                out.println("</error>");
2628
            }
2629
        } else {
2630
            // Error bcse docid missing or file missing
2631
            out.println("<?xml version=\"1.0\"?>");
2632
            out.println("<error>");
2633
            out.println("The uploaded data did not contain a valid docid "
2634
                    + "or valid file.");
2635
            out.println("</error>");
2636
        }
2637
    }
2638

    
2639
    /*
2640
     * A method to handle set access action
2641
     */
2642
    private void handleSetAccessAction(PrintWriter out, Hashtable params,
2643
            String username)
2644
    {
2645
        String[] docList = null;
2646
        String[] principalList = null;
2647
        String[] permissionList = null;
2648
        String[] permTypeList = null;
2649
        String[] permOrderList = null;
2650
        String permission = null;
2651
        String permType = null;
2652
        String permOrder = null;
2653
        Vector errorList = new Vector();
2654
        String error = null;
2655
        Vector successList = new Vector();
2656
        String success = null;
2657

    
2658
        // Get parameters
2659
        if (params.containsKey("docid")) {
2660
            docList = (String[]) params.get("docid");
2661
        }
2662
        if (params.containsKey("principal")) {
2663
            principalList = (String[]) params.get("principal");
2664
        }
2665
        if (params.containsKey("permission")) {
2666
            permissionList = (String[]) params.get("permission");
2667

    
2668
        }
2669
        if (params.containsKey("permType")) {
2670
            permTypeList = (String[]) params.get("permType");
2671

    
2672
        }
2673
        if (params.containsKey("permOrder")) {
2674
            permOrderList = (String[]) params.get("permOrder");
2675

    
2676
        }
2677

    
2678
        // Make sure the parameter is not null
2679
        if (docList == null || principalList == null || permTypeList == null
2680
                || permissionList == null) {
2681
            error = "Please check your parameter list, it should look like: "
2682
                    + "?action=setaccess&docid=pipeline.1.1&principal=public"
2683
                    + "&permission=read&permType=allow&permOrder=allowFirst";
2684
            errorList.addElement(error);
2685
            outputResponse(successList, errorList, out);
2686
            return;
2687
        }
2688

    
2689
        // Only select first element for permission, type and order
2690
        permission = permissionList[0];
2691
        permType = permTypeList[0];
2692
        if (permOrderList != null) {
2693
            permOrder = permOrderList[0];
2694
        }
2695

    
2696
        // Get package doctype set
2697
        Vector packageSet = MetaCatUtil.getOptionList(MetaCatUtil
2698
                .getOption("packagedoctypeset"));
2699
        //debug
2700
        if (packageSet != null) {
2701
            for (int i = 0; i < packageSet.size(); i++) {
2702
                logMetacat.info("doctype in package set: "
2703
                        + (String) packageSet.elementAt(i));
2704
            }
2705
        }
2706

    
2707
        // handle every accessionNumber
2708
        for (int i = 0; i < docList.length; i++) {
2709
            String accessionNumber = docList[i];
2710
            String owner = null;
2711
            String publicId = null;
2712
            // Get document owner and public id
2713
            try {
2714
                owner = getFieldValueForDoc(accessionNumber, "user_owner");
2715
                publicId = getFieldValueForDoc(accessionNumber, "doctype");
2716
            } catch (Exception e) {
2717
                logMetacat.error("Error in handleSetAccessAction: "
2718
                        + e.getMessage());
2719
                error = "Error in set access control for document - "
2720
                        + accessionNumber + e.getMessage();
2721
                errorList.addElement(error);
2722
                continue;
2723
            }
2724
            //check if user is the owner. Only owner can do owner
2725
            if (username == null || owner == null || !username.equals(owner)) {
2726
                error = "User - " + username
2727
                        + " does not have permission to set "
2728
                        + "access control for docid - " + accessionNumber;
2729
                errorList.addElement(error);
2730
                continue;
2731
            }
2732

    
2733
            // If docid publicid is BIN data file or other beta4, 6 package
2734
            // document
2735
            // we could not do set access control. Because we don't want
2736
            // inconsistent
2737
            // to its access docuemnt
2738
            if (publicId != null && packageSet != null
2739
                    && packageSet.contains(publicId)) {
2740
                error = "Could not set access control to document "
2741
                        + accessionNumber
2742
                        + "because it is in a pakcage and it has a access file for it";
2743
                errorList.addElement(error);
2744
                continue;
2745
            }
2746

    
2747
            // for every principle
2748
            for (int j = 0; j < principalList.length; j++) {
2749
                String principal = principalList[j];
2750
                try {
2751
                    //insert permission
2752
                    AccessControlForSingleFile accessControl = new AccessControlForSingleFile(
2753
                            accessionNumber, principal, permission, permType,
2754
                            permOrder);
2755
                    accessControl.insertPermissions();
2756
                    success = "Set access control to document "
2757
                            + accessionNumber + " successfully";
2758
                    successList.addElement(success);
2759
                } catch (Exception ee) {
2760
                    logMetacat.error(
2761
                            "Erorr in handleSetAccessAction2: "
2762
                                    + ee.getMessage());
2763
                    error = "Faild to set access control for document "
2764
                            + accessionNumber + " because " + ee.getMessage();
2765
                    errorList.addElement(error);
2766
                    continue;
2767
                }
2768
            }
2769
        }
2770
        outputResponse(successList, errorList, out);
2771
    }
2772

    
2773
    /*
2774
     * A method try to determin a docid's public id, if couldn't find null will
2775
     * be returned.
2776
     */
2777
    private String getFieldValueForDoc(String accessionNumber, String fieldName)
2778
            throws Exception
2779
    {
2780
        if (accessionNumber == null || accessionNumber.equals("")
2781
                || fieldName == null || fieldName.equals("")) { throw new Exception(
2782
                "Docid or field name was not specified"); }
2783

    
2784
        PreparedStatement pstmt = null;
2785
        ResultSet rs = null;
2786
        String fieldValue = null;
2787
        String docId = null;
2788
        DBConnection conn = null;
2789
        int serialNumber = -1;
2790

    
2791
        // get rid of revision if access number has
2792
        docId = MetaCatUtil.getDocIdFromString(accessionNumber);
2793
        try {
2794
            //check out DBConnection
2795
            conn = DBConnectionPool
2796
                    .getDBConnection("MetaCatServlet.getPublicIdForDoc");
2797
            serialNumber = conn.getCheckOutSerialNumber();
2798
            pstmt = conn.prepareStatement("SELECT " + fieldName
2799
                    + " FROM xml_documents " + "WHERE docid = ? ");
2800

    
2801
            pstmt.setString(1, docId);
2802
            pstmt.execute();
2803
            rs = pstmt.getResultSet();
2804
            boolean hasRow = rs.next();
2805
            int perm = 0;
2806
            if (hasRow) {
2807
                fieldValue = rs.getString(1);
2808
            } else {
2809
                throw new Exception("Could not find document: "
2810
                        + accessionNumber);
2811
            }
2812
        } catch (Exception e) {
2813
            logMetacat.error(
2814
                    "Exception in MetacatServlet.getPublicIdForDoc: "
2815
                            + e.getMessage());
2816
            throw e;
2817
        } finally {
2818
            try {
2819
                rs.close();
2820
                pstmt.close();
2821

    
2822
            } finally {
2823
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2824
            }
2825
        }
2826
        return fieldValue;
2827
    }
2828

    
2829
    /*
2830
     * Get the list of documents from the database and return the list in an
2831
     * Vector of identifiers.
2832
     *
2833
     * @ returns the array of identifiers
2834
     */
2835
    private Vector getDocumentList() throws SQLException
2836
    {
2837
        Vector docList = new Vector();
2838
        PreparedStatement pstmt = null;
2839
        ResultSet rs = null;
2840
        DBConnection conn = null;
2841
        int serialNumber = -1;
2842

    
2843
        try {
2844
            //check out DBConnection
2845
            conn = DBConnectionPool
2846
                    .getDBConnection("MetaCatServlet.getDocumentList");
2847
            serialNumber = conn.getCheckOutSerialNumber();
2848
            pstmt = conn.prepareStatement("SELECT docid, rev"
2849
                    + " FROM xml_documents ");
2850
            pstmt.execute();
2851
            rs = pstmt.getResultSet();
2852
            while (rs.next()) {
2853
                String docid = rs.getString(1);
2854
                String rev = rs.getString(2);
2855
                docList.add(docid + "." + rev);
2856
            }
2857
        } catch (SQLException e) {
2858
            logMetacat.error(
2859
                    "Exception in MetacatServlet.getDocumentList: "
2860
                            + e.getMessage());
2861
            throw e;
2862
        } finally {
2863
            try {
2864
                rs.close();
2865
                pstmt.close();
2866

    
2867
            } catch (SQLException se) {
2868
                logMetacat.error(
2869
                    "Exception in MetacatServlet.getDocumentList: "
2870
                            + se.getMessage());
2871
                throw se;
2872
            } finally {
2873
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2874
            }
2875
        }
2876
        return docList;
2877
    }
2878

    
2879
    /*
2880
     * A method to output setAccess action result
2881
     */
2882
    private void outputResponse(Vector successList, Vector errorList,
2883
            PrintWriter out)
2884
    {
2885
        boolean error = false;
2886
        boolean success = false;
2887
        // Output prolog
2888
        out.println(PROLOG);
2889
        // output success message
2890
        if (successList != null) {
2891
            for (int i = 0; i < successList.size(); i++) {
2892
                out.println(SUCCESS);
2893
                out.println((String) successList.elementAt(i));
2894
                out.println(SUCCESSCLOSE);
2895
                success = true;
2896
            }
2897
        }
2898
        // output error message
2899
        if (errorList != null) {
2900
            for (int i = 0; i < errorList.size(); i++) {
2901
                out.println(ERROR);
2902
                out.println((String) errorList.elementAt(i));
2903
                out.println(ERRORCLOSE);
2904
                error = true;
2905
            }
2906
        }
2907

    
2908
        // if no error and no success info, send a error that nothing happened
2909
        if (!error && !success) {
2910
            out.println(ERROR);
2911
            out.println("Nothing happend for setaccess action");
2912
            out.println(ERRORCLOSE);
2913
        }
2914
    }
2915
    
2916
    /**
2917
     * Method to get session table which store the session info
2918
     * @return
2919
     */
2920
    public static Hashtable getSessionHash()
2921
    {
2922
        return sessionHash;
2923
    }
2924
    
2925
    /*
2926
     * If the given docid only have one seperter, we need 
2927
     * append rev for it. The rev come from xml_documents
2928
     */
2929
    private static String appendRev(String docid) throws Exception
2930
    {
2931
        String newAccNum = null;
2932
        String separator = MetaCatUtil.getOption("accNumSeparator");
2933
        int firstIndex = docid.indexOf(separator);
2934
        int lastIndex = docid.lastIndexOf(separator);
2935
        if (firstIndex == lastIndex)
2936
        {
2937
            
2938
           //only one seperater
2939
            int rev = DBUtil.getLatestRevisionInDocumentTable(docid);
2940
            if (rev == -1)
2941
            {
2942
                throw new Exception("Couldn't find the document "+docid);
2943
            }
2944
            else
2945
            {
2946
                newAccNum = docid+ separator+ rev;
2947
            }
2948
        }
2949
        else
2950
        {
2951
            // in other suituation we don't change the docid
2952
            newAccNum = docid;
2953
        }
2954
        logMetacat.warn("The docid will be read is "+newAccNum);
2955
        return newAccNum;
2956
    }
2957
}
(42-42/63)