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-07-25 11:49:12 -0700 (Mon, 25 Jul 2005) $'
11
 * '$Revision: 2521 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27

    
28
package edu.ucsb.nceas.metacat;
29

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

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

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

    
64
import org.ecoinformatics.eml.EMLParser;
65

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

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

    
118
    private ServletConfig config = null;
119

    
120
    private ServletContext context = null;
121

    
122
    private String resultStyleURL = null;
123

    
124
    private String xmlcatalogfile = null;
125

    
126
    private String saxparser = null;
127

    
128
    private String datafilepath = null;
129

    
130
    private File dataDirectory = null;
131

    
132
    private String servletpath = null;
133

    
134
    private String htmlpath = null;
135

    
136
    private String[] administrators = null;
137

    
138
    private PropertyResourceBundle options = null;
139

    
140
    private MetaCatUtil util = null;
141

    
142
    private DBConnectionPool connPool = null;
143

    
144
    private Hashtable sessionHash = new Hashtable();
145

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

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

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

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

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

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

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

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

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

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

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

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

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

    
191
            util = new MetaCatUtil();
192

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

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

    
213
            // Index the paths specified in the metacat.properties
214
            checkIndexPaths();
215

    
216
            System.out.println("Metacat (" + Version.getVersion()
217
                               + ") initialized.");
218

    
219
        } catch (ServletException ex) {
220
            throw ex;
221
        } catch (SQLException e) {
222
            MetaCatUtil.debugMessage("Error in MetacatServlet.init: "
223
                    + e.getMessage(), 20);
224
        }
225
    }
226

    
227

    
228
    /**
229
     * Index the paths specified in the metacat.properties
230
     */
231
    void checkIndexPaths(){
232
        MetaCatUtil.pathsForIndexing
233
            = MetaCatUtil.getOptionList(MetaCatUtil.getOption("indexed_paths"));
234

    
235
        if (MetaCatUtil.pathsForIndexing != null) {
236

    
237
            MetaCatUtil.debugMessage("Indexing paths....", 20);
238

    
239
            DBConnection conn = null;
240
            int serialNumber = -1;
241
            PreparedStatement pstmt = null;
242
            PreparedStatement pstmt1 = null;
243
            ResultSet rs = null;
244

    
245
            for (int i = 0; i < MetaCatUtil.pathsForIndexing.size(); i++) {
246
                MetaCatUtil.formattedDebugMessage("Checking if '"
247
                           + (String) MetaCatUtil.pathsForIndexing.elementAt(i)
248
                           + "' is indexed.... ",30, false, true);
249

    
250
                try {
251
                    //check out DBConnection
252
                    conn = DBConnectionPool.
253
                        getDBConnection("MetaCatServlet.checkIndexPaths");
254
                    serialNumber = conn.getCheckOutSerialNumber();
255

    
256
                    pstmt = conn.prepareStatement(
257
                        "SELECT * FROM xml_path_index " + "WHERE path = ?");
258
                    pstmt.setString(1, (String) MetaCatUtil.pathsForIndexing
259
                                    .elementAt(i));
260

    
261
                    pstmt.execute();
262
                    rs = pstmt.getResultSet();
263

    
264
                    if (!rs.next()) {
265
                        MetaCatUtil.formattedDebugMessage("not indexed yet.", 30,
266
                                                       true, false);
267
                        rs.close();
268
                        pstmt.close();
269
                        conn.increaseUsageCount(1);
270

    
271
                        MetaCatUtil.debugMessage(
272
                              "Inserting following path in xml_path_index: "
273
                              + (String)MetaCatUtil.pathsForIndexing
274
                                                   .elementAt(i), 60);
275

    
276
                        pstmt = conn.prepareStatement("SELECT DISTINCT n.docid, "
277
                              + "n.nodedata, n.nodedatanumerical, n.parentnodeid"
278
                              + " FROM xml_nodes n, xml_index i WHERE"
279
                              + " i.path = ? and n.parentnodeid=i.nodeid and"
280
                              + " n.nodetype LIKE 'TEXT'");
281
                        pstmt.setString(1, (String) MetaCatUtil.
282
                                        pathsForIndexing.elementAt(i));
283
                        pstmt.execute();
284
                        rs = pstmt.getResultSet();
285

    
286
                        int count = 0;
287
                        MetaCatUtil.debugMessage(
288
                                       "Executed the select statement for: "
289
                                       + (String) MetaCatUtil.pathsForIndexing
290
                                         .elementAt(i), 60);
291

    
292
                        try {
293
                            while (rs.next()) {
294

    
295
                                String docid = rs.getString(1);
296
                                String nodedata = rs.getString(2);
297
                                float nodedatanumerical = rs.getFloat(3);
298
                                int parentnodeid = rs.getInt(4);
299

    
300
                                if (!nodedata.trim().equals("")) {
301
                                    pstmt1 = conn.prepareStatement(
302
                                        "INSERT INTO xml_path_index"
303
                                        + " (docid, path, nodedata, "
304
                                        + "nodedatanumerical, parentnodeid)"
305
                                        + " VALUES (?, ?, ?, ?, ?)");
306

    
307
                                    pstmt1.setString(1, docid);
308
                                    pstmt1.setString(2, (String) MetaCatUtil.
309
                                                pathsForIndexing.elementAt(i));
310
                                    pstmt1.setString(3, nodedata);
311
                                    pstmt1.setFloat(4, nodedatanumerical);
312
                                    pstmt1.setFloat(5, parentnodeid);
313

    
314
                                    pstmt1.execute();
315
                                    pstmt1.close();
316

    
317
                                    count++;
318

    
319
                                }
320
                            }
321
                        }
322
                        catch (Exception e) {
323
                            System.out.println("Exception:" + e.getMessage());
324
                            e.printStackTrace();
325
                        }
326

    
327
                        rs.close();
328
                        pstmt.close();
329
                        conn.increaseUsageCount(1);
330

    
331
                        MetaCatUtil.debugMessage("Indexed " + count
332
                                + " records from xml_nodes for '"
333
                                + (String) MetaCatUtil.pathsForIndexing.elementAt(i)
334
                                + "'", 20);
335

    
336
                    } else {
337
                        MetaCatUtil.formattedDebugMessage("already indexed.", 30,
338
                                                       true, false);
339
                    }
340

    
341
                    rs.close();
342
                    pstmt.close();
343
                    conn.increaseUsageCount(1);
344

    
345
                } catch (Exception e) {
346
                    MetaCatUtil.debugMessage("error in DocumentImpl.delete: "
347
                                             + e.getMessage(), 30);
348
                }finally {
349
                    //check in DBonnection
350
                    DBConnectionPool.returnDBConnection(conn, serialNumber);
351
                }
352

    
353

    
354
            }
355

    
356
            MetaCatUtil.debugMessage("Path Indexing Completed", 20);
357
        }
358
    }
359
    /**
360
     * Close all db connections from the pool
361
     */
362
    public void destroy()
363
    {
364
        // Close all db connection
365
        System.out.println("Destroying MetacatServlet");
366
        DBConnectionPool.release();
367
    }
368

    
369
    /** Handle "GET" method requests from HTTP clients */
370
    public void doGet(HttpServletRequest request, HttpServletResponse response)
371
            throws ServletException, IOException
372
    {
373

    
374
        // Process the data and send back the response
375
        handleGetOrPost(request, response);
376
    }
377

    
378
    /** Handle "POST" method requests from HTTP clients */
379
    public void doPost(HttpServletRequest request, HttpServletResponse response)
380
            throws ServletException, IOException
381
    {
382

    
383
        // Process the data and send back the response
384
        handleGetOrPost(request, response);
385
    }
386

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

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

    
407
        //Debug message to print out the method which have a busy DBConnection
408
        connPool.printMethodNameHavingBusyDBConnection();
409

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

    
415
            String name = null;
416
            String[] value = null;
417
            String[] docid = new String[3];
418
            Hashtable params = new Hashtable();
419
            Enumeration paramlist = request.getParameterNames();
420

    
421
            while (paramlist.hasMoreElements()) {
422

    
423
                name = (String) paramlist.nextElement();
424
                value = request.getParameterValues(name);
425

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

    
436
                params.put(name, value);
437
            }
438

    
439
            //handle param is emptpy
440
            if (params.isEmpty() || params == null) { return; }
441

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

    
455
            String action = ((String[]) params.get("action"))[0];
456
            MetaCatUtil.debugMessage("Line 230: Action is: " + action, 1);
457

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

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

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

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

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

    
540
                    username = (String) sess.getAttribute("username");
541
                    MetaCatUtil.debugMessage("The user name from session is: "
542
                            + username, 20);
543
                    password = (String) sess.getAttribute("password");
544
                    groupnames = (String[]) sess.getAttribute("groupnames");
545
                }
546

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

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

    
709
            //util.closeConnections();
710
            // Close the stream to the client
711
            //out.close();
712
        }
713
    }
714

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

    
724
        AuthSession sess = null;
725

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

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

    
744
        String un = ((String[]) params.get("username"))[0];
745
        MetaCatUtil.debugMessage("user " + un + " try to login", 20);
746
        String pw = ((String[]) params.get("password"))[0];
747

    
748
        String qformat = "xml";
749
        if(params.get("qformat") != null){
750
            qformat = ((String[]) params.get("qformat"))[0];
751
        }
752

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

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

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

    
786
                MetaCatUtil.debugMessage(
787
                        "Error in MetaCatServlet.handleLoginAction: "
788
                                + e.getMessage(), 30);
789
            }
790
        }
791
    }
792

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

    
800
        String qformat = "xml";
801
        if(params.get("qformat") != null){
802
            qformat = ((String[]) params.get("qformat"))[0];
803
        }
804

    
805
        // close the connection
806
        HttpSession sess = request.getSession(false);
807
        MetaCatUtil.debugMessage("After get session in logout request", 40);
808
        if (sess != null) {
809
            MetaCatUtil.debugMessage("The session id " + sess.getId()
810
                    + " will be invalidate in logout action", 30);
811
            MetaCatUtil.debugMessage("The session contains user "
812
                    + sess.getAttribute("username")
813
                    + " will be invalidate in logout action", 30);
814
            sess.invalidate();
815
        }
816

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

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

    
843
    // END OF LOGIN & LOGOUT SECTION
844

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

    
866
    }
867

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

    
892
        //handleSQuery(out, params, response,user, groups, sessionid);
893
    }
894

    
895
    // END OF SQUERY & QUERY SECTION
896

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

    
917
        String[] docs = new String[10];
918
        String docId = "";
919

    
920
        try {
921
            // read the params
922
            if (params.containsKey("docid")) {
923
                docs = (String[]) params.get("docid");
924
            }
925
            // Create a DBuery to handle export
926
            queryObj = new DBQuery(saxparser);
927
            // Get the docid
928
            docId = docs[0];
929
            // Make sure the client specify docid
930
            if (docId == null || docId.equals("")) {
931
                response.setContentType("text/xml"); //MIME type
932
                // Get a printwriter
933
                PrintWriter pw = response.getWriter();
934
                // Send back message
935
                pw.println("<?xml version=\"1.0\"?>");
936
                pw.println("<error>");
937
                pw.println("You didn't specify requested docid");
938
                pw.println("</error>");
939
                // Close printwriter
940
                pw.close();
941
                return;
942
            }
943
            // Get output stream
944
            out = response.getOutputStream();
945
            response.setContentType("application/zip"); //MIME type
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
                MetaCatUtil.debugMessage("Problem with the servlet output "
973
                        + "in MetacatServlet.handleExportAction: "
974
                        + ioe.getMessage(), 30);
975
            }
976

    
977
            MetaCatUtil.debugMessage(
978
                    "Error in MetacatServlet.handleExportAction: "
979
                            + e.getMessage(), 30);
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
                MetaCatUtil.debugMessage("Problem with the servlet output "
1088
                        + "in MetacatServlet.handleExportAction: "
1089
                        + ioe.getMessage(), 30);
1090
            }
1091
            MetaCatUtil.debugMessage(
1092
                    "Error in MetacatServlet.handleReadInlineDataAction: "
1093
                            + e.getMessage(), 30);
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
        MetaCatUtil.debugMessage("The nodeid for inlinedataid " + inLineDataId
1144
                + " is: " + nodeId, 35);
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
            MetaCatUtil.debugMessage("Missed id: " + notFoundDocId, 30);
1250
            MetaCatUtil.debugMessage("Missed rev: " + notFoundRevision, 30);
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
                MetaCatUtil.debugMessage(
1266
                        "Erorr in MetacatServlet.hanldReadAction: "
1267
                                + exc.getMessage(), 30);
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
                    MetaCatUtil.debugMessage("Problem with the servlet output "
1299
                            + "in MetacatServlet.handleReadAction: "
1300
                            + ie.getMessage(), 30);
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
                MetaCatUtil.debugMessage("Problem with the servlet output "
1335
                        + "in MetacatServlet.handleReadAction: "
1336
                        + ioe.getMessage(), 30);
1337
                ioe.printStackTrace(System.out);
1338

    
1339
            }
1340

    
1341
            MetaCatUtil.debugMessage(
1342
                    "Error in MetacatServlet.handleReadAction: "
1343
                            + e.getMessage(), 30);
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
            DocumentImpl doc = new DocumentImpl(docid);
1361

    
1362
            //check the permission for read
1363
            if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1364
                Exception e = new Exception("User " + user
1365
                        + " does not have permission"
1366
                        + " to read the document with the docid " + docid);
1367

    
1368
                throw e;
1369
            }
1370

    
1371
            if (doc.getRootNodeID() == 0) {
1372
                // this is data file
1373
                String filepath = MetaCatUtil.getOption("datafilepath");
1374
                if (!filepath.endsWith("/")) {
1375
                    filepath += "/";
1376
                }
1377
                String filename = filepath + docid;
1378
                FileInputStream fin = null;
1379
                fin = new FileInputStream(filename);
1380

    
1381
                //MIME type
1382
                String contentType = getServletContext().getMimeType(filename);
1383
                if (contentType == null) {
1384
                    ContentTypeProvider provider = new ContentTypeProvider(
1385
                            docid);
1386
                    contentType = provider.getContentType();
1387
                    MetaCatUtil.debugMessage("Final contenttype is: "
1388
                            + contentType, 30);
1389
                }
1390

    
1391
                response.setContentType(contentType);
1392
                // if we decide to use "application/octet-stream" for all data
1393
                // returns
1394
                // response.setContentType("application/octet-stream");
1395

    
1396
                try {
1397

    
1398
                    ServletOutputStream out = response.getOutputStream();
1399
                    byte[] buf = new byte[4 * 1024]; // 4K buffer
1400
                    int b = fin.read(buf);
1401
                    while (b != -1) {
1402
                        out.write(buf, 0, b);
1403
                        b = fin.read(buf);
1404
                    }
1405
                } finally {
1406
                    if (fin != null) fin.close();
1407
                }
1408

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

    
1422
                    // Look up the document type
1423
                    String doctype = doc.getDoctype();
1424
                    // Transform the document to the new doctype
1425
                    DBTransform dbt = new DBTransform();
1426
                    dbt.transformXMLDocument(doc.toString(user, groups,
1427
                            withInlineData), doctype, "-//W3C//HTML//EN",
1428
                            qformat, out, params);
1429
                }
1430

    
1431
            }
1432
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1433
                    docid, "read");
1434
        } catch (Exception except) {
1435
            throw except;
1436
        }
1437
    }
1438

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

    
1472
        // this is http url
1473
        URL url = new URL(docid);
1474
        BufferedInputStream bis = null;
1475
        try {
1476
            bis = new BufferedInputStream(url.openStream());
1477
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1478
            int b = bis.read(buf);
1479
            while (b != -1) {
1480
                out.write(buf, 0, b);
1481
                b = bis.read(buf);
1482
            }
1483
        } finally {
1484
            if (bis != null) bis.close();
1485
        }
1486

    
1487
    }
1488

    
1489
    /**
1490
     * read file/doc and write to ZipOutputStream
1491
     *
1492
     * @param docid
1493
     * @param zout
1494
     * @param user
1495
     * @param groups
1496
     * @throws ClassNotFoundException
1497
     * @throws IOException
1498
     * @throws SQLException
1499
     * @throws McdbException
1500
     * @throws Exception
1501
     */
1502
    private void addDocToZip(HttpServletRequest request, String docid,
1503
            ZipOutputStream zout, String user, String[] groups) throws
1504
            ClassNotFoundException, IOException, SQLException, McdbException,
1505
            Exception
1506
    {
1507
        byte[] bytestring = null;
1508
        ZipEntry zentry = null;
1509

    
1510
        try {
1511
            URL url = new URL(docid);
1512

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

    
1530
        } catch (MalformedURLException mue) {
1531

    
1532
            // this is metacat doc (data file or metadata doc)
1533
            try {
1534
                DocumentImpl doc = new DocumentImpl(docid);
1535

    
1536
                //check the permission for read
1537
                if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1538
                    Exception e = new Exception("User " + user
1539
                            + " does not have "
1540
                            + "permission to read the document with the docid "
1541
                            + docid);
1542
                    throw e;
1543
                }
1544

    
1545
                if (doc.getRootNodeID() == 0) {
1546
                    // this is data file; add file to zip
1547
                    String filepath = MetaCatUtil.getOption("datafilepath");
1548
                    if (!filepath.endsWith("/")) {
1549
                        filepath += "/";
1550
                    }
1551
                    String filename = filepath + docid;
1552
                    FileInputStream fin = null;
1553
                    fin = new FileInputStream(filename);
1554
                    try {
1555

    
1556
                        zentry = new ZipEntry(docid);
1557
                        zout.putNextEntry(zentry);
1558
                        byte[] buf = new byte[4 * 1024]; // 4K buffer
1559
                        int b = fin.read(buf);
1560
                        while (b != -1) {
1561
                            zout.write(buf, 0, b);
1562
                            b = fin.read(buf);
1563
                        }
1564
                    } finally {
1565
                        if (fin != null) fin.close();
1566
                    }
1567
                    zout.closeEntry();
1568

    
1569
                } else {
1570
                    // this is metadata doc; add doc to zip
1571
                    bytestring = doc.toString().getBytes();
1572
                    zentry = new ZipEntry(docid + ".xml");
1573
                    zentry.setSize(bytestring.length);
1574
                    zout.putNextEntry(zentry);
1575
                    zout.write(bytestring, 0, bytestring.length);
1576
                    zout.closeEntry();
1577
                }
1578
                EventLog.getInstance().log(request.getRemoteAddr(), user,
1579
                        docid, "read");
1580
            } catch (Exception except) {
1581
                throw except;
1582
            }
1583
        }
1584
    }
1585

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

    
1617
    /**
1618
     * Handle the database putdocument request and write an XML document to the
1619
     * database connection
1620
     */
1621
    private void handleInsertOrUpdateAction(HttpServletRequest request,
1622
            HttpServletResponse response, PrintWriter out, Hashtable params,
1623
            String user, String[] groups)
1624
    {
1625
        DBConnection dbConn = null;
1626
        int serialNumber = -1;
1627

    
1628
        if(params.get("docid") == null){
1629
            out.println("<?xml version=\"1.0\"?>");
1630
            out.println("<error>");
1631
            out.println("Docid not specified");
1632
            out.println("</error>");
1633
            return;
1634
        }
1635

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

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

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

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

    
1702
                String[] action = (String[]) params.get("action");
1703
                String[] docid = (String[]) params.get("docid");
1704
                String newdocid = null;
1705

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

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

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

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

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

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

    
1774
        StringBuffer cbuff = new StringBuffer();
1775
        java.util.Stack st = new java.util.Stack();
1776
        boolean validate = false;
1777
        int c;
1778
        int inx;
1779

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

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

    
1808
        // close the stream
1809
        xmlreader.reset();
1810

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

    
1822
        MetaCatUtil.debugMessage("Validation for dtd is " + validate, 10);
1823
        return validate;
1824
    }
1825

    
1826
    // END OF INSERT/UPDATE SECTION
1827

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

    
1848
        MetaCatUtil.debugMessage("Validation for schema is "
1849
                + needSchemaValidate, 10);
1850
        return needSchemaValidate;
1851

    
1852
    }
1853

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

    
1859
        String eml2_0_0NameSpace = DocumentImpl.EML2_0_0NAMESPACE;
1860
        String eml2_0_1NameSpace = DocumentImpl.EML2_0_1NAMESPACE;
1861
        String eml2_1_0NameSpace = DocumentImpl.EML2_1_0NAMESPACE;
1862

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

    
1870
        if (targetLine != null) {
1871

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

    
1903
        MetaCatUtil.debugMessage("Validation for eml is " + namespace,
1904
                10);
1905

    
1906
        return namespace;
1907

    
1908
    }
1909

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

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

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

    
1971
        String[] docid = (String[]) params.get("docid");
1972

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

    
1981
            // delete the document from the database
1982
            try {
1983

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

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

    
2020
        // Get the document indicated
2021
        String valtext = null;
2022
        DBConnection dbConn = null;
2023
        int serialNumber = -1;
2024

    
2025
        try {
2026
            valtext = ((String[]) params.get("valtext"))[0];
2027
        } catch (Exception nullpe) {
2028

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

    
2034
                // Get the document indicated from the db
2035
                DocumentImpl xmldoc = new DocumentImpl(docid);
2036
                valtext = xmldoc.toString();
2037

    
2038
            } catch (NullPointerException npe) {
2039

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

    
2046
                out.println(e.getMessage());
2047
            }
2048
        }
2049

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

    
2058
            // set content type and other response header fields first
2059

    
2060
            out.println(valobj.returnErrors());
2061

    
2062
        } catch (NullPointerException npe2) {
2063
            // set content type and other response header fields first
2064

    
2065
            out.println("<error>Error validating document.</error>");
2066
        } catch (Exception e) {
2067

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

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

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

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

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

    
2114
    }
2115

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

    
2128
        try {
2129

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

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

    
2149
    /**
2150
     * Handle the "getprincipals" action. Read all principals from
2151
     * authentication scheme in XML format
2152
     */
2153
    private void handleGetPrincipalsAction(PrintWriter out, String user,
2154
            String password)
2155
    {
2156
        try {
2157
            AuthSession auth = new AuthSession();
2158
            String principals = auth.getPrincipals(user, password);
2159
            out.println(principals);
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
        }
2167
    }
2168

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

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

    
2196
        String doctype = null;
2197
        String[] doctypeArr = (String[]) params.get("doctype");
2198

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

    
2205
        try {
2206
            DBUtil dbutil = new DBUtil();
2207
            String dtdschema = dbutil.readDTDSchema(doctype);
2208
            out.println(dtdschema);
2209

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

    
2217
    }
2218

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

    
2227
        String scope = ((String[]) params.get("scope"))[0];
2228
        if (scope == null) {
2229
            scope = ((String[]) params.get("username"))[0];
2230
        }
2231

    
2232
        try {
2233

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

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

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

    
2265
            // Check that the user is authenticated as an administrator account
2266
            boolean adminIsAuthenticated = false;
2267
            for (int i = 0; i < administrators.length; i++) {
2268
                if (username.equals(administrators[i])) {
2269
                        adminIsAuthenticated = true;
2270
                }
2271
            }
2272
            if (!adminIsAuthenticated) {
2273
                out.print("<error>");
2274
                out.print("The user \"" + username +
2275
                        "\" is not authorized for this action.");
2276
                out.print("</error>");
2277
                return;
2278
            }
2279

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

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

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

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

    
2342
            // Check that the user is authenticated as an administrator account
2343
            boolean adminIsAuthenticated = false;
2344
            for (int i = 0; i < administrators.length; i++) {
2345
                if (username.equals(administrators[i])) {
2346
                        adminIsAuthenticated = true;
2347
                }
2348
            }
2349
            if (!adminIsAuthenticated) {
2350
                out.print("<error>");
2351
                out.print("The user \"" + username +
2352
                        "\" is not authorized for this action.");
2353
                out.print("</error>");
2354
                return;
2355
            }
2356

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

    
2388
    /**
2389
     * Build the index for one document by reading the document and
2390
     * calling its buildIndex() method.
2391
     *
2392
     * @param docid the document (with revision) to rebuild
2393
     * @param out the PrintWriter to which output is printed
2394
     */
2395
    private void buildDocumentIndex(String docid, PrintWriter out)
2396
    {
2397
        try {
2398
            DocumentImpl doc = new DocumentImpl(docid, false);
2399
            doc.buildIndex();
2400
            out.print("<docid>" + docid);
2401
            out.println("</docid>");
2402
        } catch (McdbException me) {
2403
            out.print("<error>");
2404
            out.print(me.getMessage());
2405
            out.println("</error>");
2406
        }
2407
    }
2408

    
2409
    /**
2410
     * Handle documents passed to metacat that are encoded using the
2411
     * "multipart/form-data" mime type. This is typically used for uploading
2412
     * data files which may be binary and large.
2413
     */
2414
    private void handleMultipartForm(HttpServletRequest request,
2415
            HttpServletResponse response)
2416
    {
2417
        PrintWriter out = null;
2418
        String action = null;
2419

    
2420
        // Parse the multipart form, and save the parameters in a Hashtable and
2421
        // save the FileParts in a hashtable
2422

    
2423
        Hashtable params = new Hashtable();
2424
        Hashtable fileList = new Hashtable();
2425
        int sizeLimit = (new Integer(MetaCatUtil.getOption("datafilesizelimit")))
2426
                .intValue();
2427
        MetaCatUtil.debugMessage(
2428
                "The limit size of data file is: " + sizeLimit, 50);
2429

    
2430
        try {
2431
            // MBJ: need to put filesize limit in Metacat config
2432
            // (metacat.properties)
2433
            MultipartParser mp = new MultipartParser(request,
2434
                    sizeLimit * 1024 * 1024);
2435
            Part part;
2436
            while ((part = mp.readNextPart()) != null) {
2437
                String name = part.getName();
2438

    
2439
                if (part.isParam()) {
2440
                    // it's a parameter part
2441
                    ParamPart paramPart = (ParamPart) part;
2442
                    String value = paramPart.getStringValue();
2443
                    params.put(name, value);
2444
                    if (name.equals("action")) {
2445
                        action = value;
2446
                    }
2447
                } else if (part.isFile()) {
2448
                    // it's a file part
2449
                    FilePart filePart = (FilePart) part;
2450
                    fileList.put(name, filePart);
2451

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

    
2473
        // Get the session information
2474
        String username = null;
2475
        String password = null;
2476
        String[] groupnames = null;
2477
        String sess_id = null;
2478

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

    
2499
        // Get the out stream
2500
        try {
2501
            out = response.getWriter();
2502
        } catch (IOException ioe2) {
2503
            MetaCatUtil.debugMessage("Fatal Error: couldn't get response "
2504
                    + "output stream.", 30);
2505
        }
2506

    
2507
        if (action.equals("upload")) {
2508
            if (username != null && !username.equals("public")) {
2509
                handleUploadAction(request, out, params, fileList, username,
2510
                        groupnames);
2511
            } else {
2512

    
2513
                out.println("<?xml version=\"1.0\"?>");
2514
                out.println("<error>");
2515
                out.println("Permission denied for " + action);
2516
                out.println("</error>");
2517
            }
2518
        } else {
2519
            /*
2520
             * try { out = response.getWriter(); } catch (IOException ioe2) {
2521
             * System.err.println("Fatal Error: couldn't get response output
2522
             * stream.");
2523
             */
2524
            out.println("<?xml version=\"1.0\"?>");
2525
            out.println("<error>");
2526
            out.println(
2527
                    "Error: action not registered.  Please report this error.");
2528
            out.println("</error>");
2529
        }
2530
        out.close();
2531
    }
2532

    
2533
    /**
2534
     * Handle the upload action by saving the attached file to disk and
2535
     * registering it in the Metacat db
2536
     */
2537
    private void handleUploadAction(HttpServletRequest request,
2538
            PrintWriter out, Hashtable params, Hashtable fileList,
2539
            String username, String[] groupnames)
2540
    {
2541
        //PrintWriter out = null;
2542
        //Connection conn = null;
2543
        String action = null;
2544
        String docid = null;
2545

    
2546
        /*
2547
         * response.setContentType("text/xml"); try { out =
2548
         * response.getWriter(); } catch (IOException ioe2) {
2549
         * System.err.println("Fatal Error: couldn't get response output
2550
         * stream.");
2551
         */
2552

    
2553
        if (params.containsKey("docid")) {
2554
            docid = (String) params.get("docid");
2555
        }
2556

    
2557
        // Make sure we have a docid and datafile
2558
        if (docid != null && fileList.containsKey("datafile")) {
2559

    
2560
            // Get a reference to the file part of the form
2561
            FilePart filePart = (FilePart) fileList.get("datafile");
2562
            String fileName = filePart.getFileName();
2563
            MetaCatUtil.debugMessage("Uploading filename: " + fileName, 10);
2564

    
2565
            // Check if the right file existed in the uploaded data
2566
            if (fileName != null) {
2567

    
2568
                try {
2569
                    //MetaCatUtil.debugMessage("Upload datafile " + docid
2570
                    // +"...", 10);
2571
                    //If document get lock data file grant
2572
                    if (DocumentImpl.getDataFileLockGrant(docid)) {
2573
                        // register the file in the database (which generates
2574
                        // an exception
2575
                        //if the docid is not acceptable or other untoward
2576
                        // things happen
2577
                        DocumentImpl.registerDocument(fileName, "BIN", docid,
2578
                                username, groupnames);
2579

    
2580
                        // Save the data file to disk using "docid" as the name
2581
                        dataDirectory.mkdirs();
2582
                        File newFile = new File(dataDirectory, docid);
2583
                        long size = filePart.writeTo(newFile);
2584

    
2585
                        EventLog.getInstance().log(request.getRemoteAddr(),
2586
                                username, docid, "upload");
2587
                        // Force replication this data file
2588
                        // To data file, "insert" and update is same
2589
                        // The fourth parameter is null. Because it is
2590
                        // notification server
2591
                        // and this method is in MetaCatServerlet. It is
2592
                        // original command,
2593
                        // not get force replication info from another metacat
2594
                        ForceReplicationHandler frh = new ForceReplicationHandler(
2595
                                docid, "insert", false, null);
2596

    
2597
                        // set content type and other response header fields
2598
                        // first
2599
                        out.println("<?xml version=\"1.0\"?>");
2600
                        out.println("<success>");
2601
                        out.println("<docid>" + docid + "</docid>");
2602
                        out.println("<size>" + size + "</size>");
2603
                        out.println("</success>");
2604
                    }
2605

    
2606
                } catch (Exception e) {
2607
                    out.println("<?xml version=\"1.0\"?>");
2608
                    out.println("<error>");
2609
                    out.println(e.getMessage());
2610
                    out.println("</error>");
2611
                }
2612
            } else {
2613
                // the field did not contain a file
2614
                out.println("<?xml version=\"1.0\"?>");
2615
                out.println("<error>");
2616
                out.println("The uploaded data did not contain a valid file.");
2617
                out.println("</error>");
2618
            }
2619
        } else {
2620
            // Error bcse docid missing or file missing
2621
            out.println("<?xml version=\"1.0\"?>");
2622
            out.println("<error>");
2623
            out.println("The uploaded data did not contain a valid docid "
2624
                    + "or valid file.");
2625
            out.println("</error>");
2626
        }
2627
    }
2628

    
2629
    /*
2630
     * A method to handle set access action
2631
     */
2632
    private void handleSetAccessAction(PrintWriter out, Hashtable params,
2633
            String username)
2634
    {
2635
        String[] docList = null;
2636
        String[] principalList = null;
2637
        String[] permissionList = null;
2638
        String[] permTypeList = null;
2639
        String[] permOrderList = null;
2640
        String permission = null;
2641
        String permType = null;
2642
        String permOrder = null;
2643
        Vector errorList = new Vector();
2644
        String error = null;
2645
        Vector successList = new Vector();
2646
        String success = null;
2647

    
2648
        // Get parameters
2649
        if (params.containsKey("docid")) {
2650
            docList = (String[]) params.get("docid");
2651
        }
2652
        if (params.containsKey("principal")) {
2653
            principalList = (String[]) params.get("principal");
2654
        }
2655
        if (params.containsKey("permission")) {
2656
            permissionList = (String[]) params.get("permission");
2657

    
2658
        }
2659
        if (params.containsKey("permType")) {
2660
            permTypeList = (String[]) params.get("permType");
2661

    
2662
        }
2663
        if (params.containsKey("permOrder")) {
2664
            permOrderList = (String[]) params.get("permOrder");
2665

    
2666
        }
2667

    
2668
        // Make sure the parameter is not null
2669
        if (docList == null || principalList == null || permTypeList == null
2670
                || permissionList == null) {
2671
            error = "Please check your parameter list, it should look like: "
2672
                    + "?action=setaccess&docid=pipeline.1.1&principal=public"
2673
                    + "&permission=read&permType=allow&permOrder=allowFirst";
2674
            errorList.addElement(error);
2675
            outputResponse(successList, errorList, out);
2676
            return;
2677
        }
2678

    
2679
        // Only select first element for permission, type and order
2680
        permission = permissionList[0];
2681
        permType = permTypeList[0];
2682
        if (permOrderList != null) {
2683
            permOrder = permOrderList[0];
2684
        }
2685

    
2686
        // Get package doctype set
2687
        Vector packageSet = MetaCatUtil.getOptionList(MetaCatUtil
2688
                .getOption("packagedoctypeset"));
2689
        //debug
2690
        if (packageSet != null) {
2691
            for (int i = 0; i < packageSet.size(); i++) {
2692
                MetaCatUtil.debugMessage("doctype in package set: "
2693
                        + (String) packageSet.elementAt(i), 34);
2694
            }
2695
        }
2696

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

    
2723
            // If docid publicid is BIN data file or other beta4, 6 package
2724
            // document
2725
            // we could not do set access control. Because we don't want
2726
            // inconsistent
2727
            // to its access docuemnt
2728
            if (publicId != null && packageSet != null
2729
                    && packageSet.contains(publicId)) {
2730
                error = "Could not set access control to document "
2731
                        + accessionNumber
2732
                        + "because it is in a pakcage and it has a access file for it";
2733
                errorList.addElement(error);
2734
                continue;
2735
            }
2736

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

    
2763
    /*
2764
     * A method try to determin a docid's public id, if couldn't find null will
2765
     * be returned.
2766
     */
2767
    private String getFieldValueForDoc(String accessionNumber, String fieldName)
2768
            throws Exception
2769
    {
2770
        if (accessionNumber == null || accessionNumber.equals("")
2771
                || fieldName == null || fieldName.equals("")) { throw new Exception(
2772
                "Docid or field name was not specified"); }
2773

    
2774
        PreparedStatement pstmt = null;
2775
        ResultSet rs = null;
2776
        String fieldValue = null;
2777
        String docId = null;
2778
        DBConnection conn = null;
2779
        int serialNumber = -1;
2780

    
2781
        // get rid of revision if access number has
2782
        docId = MetaCatUtil.getDocIdFromString(accessionNumber);
2783
        try {
2784
            //check out DBConnection
2785
            conn = DBConnectionPool
2786
                    .getDBConnection("MetaCatServlet.getPublicIdForDoc");
2787
            serialNumber = conn.getCheckOutSerialNumber();
2788
            pstmt = conn.prepareStatement("SELECT " + fieldName
2789
                    + " FROM xml_documents " + "WHERE docid = ? ");
2790

    
2791
            pstmt.setString(1, docId);
2792
            pstmt.execute();
2793
            rs = pstmt.getResultSet();
2794
            boolean hasRow = rs.next();
2795
            int perm = 0;
2796
            if (hasRow) {
2797
                fieldValue = rs.getString(1);
2798
            } else {
2799
                throw new Exception("Could not find document: "
2800
                        + accessionNumber);
2801
            }
2802
        } catch (Exception e) {
2803
            MetaCatUtil.debugMessage(
2804
                    "Exception in MetacatServlet.getPublicIdForDoc: "
2805
                            + e.getMessage(), 30);
2806
            throw e;
2807
        } finally {
2808
            try {
2809
                rs.close();
2810
                pstmt.close();
2811

    
2812
            } finally {
2813
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2814
            }
2815
        }
2816
        return fieldValue;
2817
    }
2818

    
2819
    /*
2820
     * Get the list of documents from the database and return the list in an
2821
     * Vector of identifiers.
2822
     *
2823
     * @ returns the array of identifiers
2824
     */
2825
    private Vector getDocumentList() throws SQLException
2826
    {
2827
        Vector docList = new Vector();
2828
        PreparedStatement pstmt = null;
2829
        ResultSet rs = null;
2830
        DBConnection conn = null;
2831
        int serialNumber = -1;
2832

    
2833
        try {
2834
            //check out DBConnection
2835
            conn = DBConnectionPool
2836
                    .getDBConnection("MetaCatServlet.getDocumentList");
2837
            serialNumber = conn.getCheckOutSerialNumber();
2838
            pstmt = conn.prepareStatement("SELECT docid, rev"
2839
                    + " FROM xml_documents ");
2840
            pstmt.execute();
2841
            rs = pstmt.getResultSet();
2842
            while (rs.next()) {
2843
                String docid = rs.getString(1);
2844
                String rev = rs.getString(2);
2845
                docList.add(docid + "." + rev);
2846
            }
2847
        } catch (SQLException e) {
2848
            MetaCatUtil.debugMessage(
2849
                    "Exception in MetacatServlet.getDocumentList: "
2850
                            + e.getMessage(), 30);
2851
            throw e;
2852
        } finally {
2853
            try {
2854
                rs.close();
2855
                pstmt.close();
2856

    
2857
            } catch (SQLException se) {
2858
                MetaCatUtil.debugMessage(
2859
                    "Exception in MetacatServlet.getDocumentList: "
2860
                            + se.getMessage(), 30);
2861
                throw se;
2862
            } finally {
2863
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2864
            }
2865
        }
2866
        return docList;
2867
    }
2868

    
2869
    /*
2870
     * A method to output setAccess action result
2871
     */
2872
    private void outputResponse(Vector successList, Vector errorList,
2873
            PrintWriter out)
2874
    {
2875
        boolean error = false;
2876
        boolean success = false;
2877
        // Output prolog
2878
        out.println(PROLOG);
2879
        // output success message
2880
        if (successList != null) {
2881
            for (int i = 0; i < successList.size(); i++) {
2882
                out.println(SUCCESS);
2883
                out.println((String) successList.elementAt(i));
2884
                out.println(SUCCESSCLOSE);
2885
                success = true;
2886
            }
2887
        }
2888
        // output error message
2889
        if (errorList != null) {
2890
            for (int i = 0; i < errorList.size(); i++) {
2891
                out.println(ERROR);
2892
                out.println((String) errorList.elementAt(i));
2893
                out.println(ERRORCLOSE);
2894
                error = true;
2895
            }
2896
        }
2897

    
2898
        // if no error and no success info, send a error that nothing happened
2899
        if (!error && !success) {
2900
            out.println(ERROR);
2901
            out.println("Nothing happend for setaccess action");
2902
            out.println(ERRORCLOSE);
2903
        }
2904
    }
2905
}
(42-42/63)