Project

General

Profile

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

    
28
package edu.ucsb.nceas.metacat;
29

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

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

    
61
import org.ecoinformatics.eml.EMLParser;
62

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

    
68
import org.apache.log4j.Logger;
69
import org.apache.log4j.PropertyConfigurator;
70

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

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

    
120
    private ServletConfig config = null;
121

    
122
    private ServletContext context = null;
123

    
124
    private String resultStyleURL = null;
125

    
126
    private String xmlcatalogfile = null;
127

    
128
    private String saxparser = null;
129

    
130
    private String datafilepath = null;
131

    
132
    private File dataDirectory = null;
133

    
134
    private String servletpath = null;
135

    
136
    private String htmlpath = null;
137

    
138
    private PropertyResourceBundle options = null;
139

    
140
    private MetaCatUtil util = null;
141

    
142
    private DBConnectionPool connPool = null;
143

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
197
            util = new MetaCatUtil();
198

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
417
            while (paramlist.hasMoreElements()) {
418

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

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

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

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

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

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

    
454
            // This block handles session management for the servlet
455
            // by looking up the current session information for all actions
456
            // other than "login" and "logout"
457
            String username = null;
458
            String password = null;
459
            String[] groupnames = null;
460
            String sess_id = null;
461
            name = null;
462
            
463
            // handle login action
464
            if (action.equals("login")) {
465
                PrintWriter out = response.getWriter();
466
                handleLoginAction(out, params, request, response);
467
                out.close();
468

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

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

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

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

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

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

    
728
            //util.closeConnections();
729
            // Close the stream to the client
730
            //out.close();
731
        }
732
    }
733

    
734
    // LOGIN & LOGOUT SECTION
735
    /**
736
     * Handle the login request. Create a new session object. Do user
737
     * authentication through the session.
738
     */
739
    private void handleLoginAction(PrintWriter out, Hashtable params,
740
            HttpServletRequest request, HttpServletResponse response)
741
    {
742

    
743
        AuthSession sess = null;
744

    
745
        if(params.get("username") == null){
746
            response.setContentType("text/xml");
747
            out.println("<?xml version=\"1.0\"?>");
748
            out.println("<error>");
749
            out.println("Username not specified");
750
            out.println("</error>");
751
            return;
752
        }
753

    
754
        if(params.get("password") == null){
755
            response.setContentType("text/xml");
756
            out.println("<?xml version=\"1.0\"?>");
757
            out.println("<error>");
758
            out.println("Password not specified");
759
            out.println("</error>");
760
            return;
761
        }
762

    
763
        String un = ((String[]) params.get("username"))[0];
764
        logMetacat.warn("user " + un + " is trying to login");
765
        String pw = ((String[]) params.get("password"))[0];
766

    
767
        String qformat = "xml";
768
        if(params.get("qformat") != null){
769
            qformat = ((String[]) params.get("qformat"))[0];
770
        }
771

    
772
        try {
773
            sess = new AuthSession();
774
        } catch (Exception e) {
775
            System.out.println("error in MetacatServlet.handleLoginAction: "
776
                    + e.getMessage());
777
            out.println(e.getMessage());
778
            return;
779
        }
780
        boolean isValid = sess.authenticate(request, un, pw);
781

    
782
        //if it is authernticate is true, store the session
783
        if (isValid) {
784
            HttpSession session = sess.getSessions();
785
            String id = session.getId();
786
            logMetacat.info("Store session id " + id
787
                    + "which has username" + session.getAttribute("username")
788
                    + " into hash in login method");
789
            sessionHash.put(id, session);
790
        }
791

    
792
        // format and transform the output
793
        if (qformat.equals("xml")) {
794
            response.setContentType("text/xml");
795
            out.println(sess.getMessage());
796
        } else {
797
            try {
798
                DBTransform trans = new DBTransform();
799
                response.setContentType("text/html");
800
                trans.transformXMLDocument(sess.getMessage(),
801
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
802
                        out, null);
803
            } catch (Exception e) {
804

    
805
                logMetacat.error(
806
                        "Error in MetaCatServlet.handleLoginAction: "
807
                                + e.getMessage());
808
            }
809
        }
810
    }
811

    
812
    /**
813
     * Handle the logout request. Close the connection.
814
     */
815
    private void handleLogoutAction(PrintWriter out, Hashtable params,
816
            HttpServletRequest request, HttpServletResponse response)
817
    {
818

    
819
        String qformat = "xml";
820
        if(params.get("qformat") != null){
821
            qformat = ((String[]) params.get("qformat"))[0];
822
        }
823

    
824
        // close the connection
825
        HttpSession sess = request.getSession(false);
826
        logMetacat.info("After get session in logout request");
827
        if (sess != null) {
828
            logMetacat.info("The session id " + sess.getId()
829
                    + " will be invalidate in logout action");
830
            logMetacat.warn("The session contains user "
831
                    + sess.getAttribute("username")
832
                    + " will be invalidate in logout action");
833
            sess.invalidate();
834
        }
835

    
836
        // produce output
837
        StringBuffer output = new StringBuffer();
838
        output.append("<?xml version=\"1.0\"?>");
839
        output.append("<logout>");
840
        output.append("User logged out");
841
        output.append("</logout>");
842

    
843
        //format and transform the output
844
        if (qformat.equals("xml")) {
845
            response.setContentType("text/xml");
846
            out.println(output.toString());
847
        } else {
848
            try {
849
                DBTransform trans = new DBTransform();
850
                response.setContentType("text/html");
851
                trans.transformXMLDocument(output.toString(),
852
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
853
                        out, null);
854
            } catch (Exception e) {
855
                logMetacat.error(
856
                        "Error in MetaCatServlet.handleLogoutAction"
857
                                + e.getMessage());
858
            }
859
        }
860
    }
861

    
862
    // END OF LOGIN & LOGOUT SECTION
863

    
864
    // SQUERY & QUERY SECTION
865
    /**
866
     * Retreive the squery xml, execute it and display it
867
     *
868
     * @param out the output stream to the client
869
     * @param params the Hashtable of parameters that should be included in the
870
     *            squery.
871
     * @param response the response object linked to the client
872
     * @param conn the database connection
873
     */
874
    private void handleSQuery(PrintWriter out, Hashtable params,
875
            HttpServletResponse response, String user, String[] groups,
876
            String sessionid)
877
    {
878
        double startTime = System.currentTimeMillis() / 1000;
879
        DBQuery queryobj = new DBQuery(saxparser);
880
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
881
        double outPutTime = System.currentTimeMillis() / 1000;
882
        logMetacat.warn("Total search time for action 'squery': "
883
                + (outPutTime - startTime));
884

    
885
    }
886

    
887
    /**
888
     * Create the xml query, execute it and display the results.
889
     *
890
     * @param out the output stream to the client
891
     * @param params the Hashtable of parameters that should be included in the
892
     *            squery.
893
     * @param response the response object linked to the client
894
     */
895
    private void handleQuery(PrintWriter out, Hashtable params,
896
            HttpServletResponse response, String user, String[] groups,
897
            String sessionid)
898
    {
899
        //create the query and run it
900
        String xmlquery = DBQuery.createSQuery(params);
901
        String[] queryArray = new String[1];
902
        queryArray[0] = xmlquery;
903
        params.put("query", queryArray);
904
        double startTime = System.currentTimeMillis() / 1000;
905
        DBQuery queryobj = new DBQuery(saxparser);
906
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
907
        double outPutTime = System.currentTimeMillis() / 1000;
908
        logMetacat.warn("Total search time for action 'query': "
909
                + (outPutTime - startTime));
910

    
911
        //handleSQuery(out, params, response,user, groups, sessionid);
912
    }
913

    
914
    // END OF SQUERY & QUERY SECTION
915

    
916
    //Exoport section
917
    /**
918
     * Handle the "export" request of data package from Metacat in zip format
919
     *
920
     * @param params the Hashtable of HTTP request parameters
921
     * @param response the HTTP response object linked to the client
922
     * @param user the username sent the request
923
     * @param groups the user's groupnames
924
     */
925
    private void handleExportAction(Hashtable params,
926
            HttpServletResponse response,
927
            String user, String[] groups, String passWord)
928
    {
929
        // Output stream
930
        ServletOutputStream out = null;
931
        // Zip output stream
932
        ZipOutputStream zOut = null;
933
        DBQuery queryObj = null;
934

    
935
        String[] docs = new String[10];
936
        String docId = "";
937

    
938
        try {
939
            // read the params
940
            if (params.containsKey("docid")) {
941
                docs = (String[]) params.get("docid");
942
            }
943
            // Create a DBuery to handle export
944
            queryObj = new DBQuery(saxparser);
945
            // Get the docid
946
            docId = docs[0];
947
            // Make sure the client specify docid
948
            if (docId == null || docId.equals("")) {
949
                response.setContentType("text/xml"); //MIME type
950
                // Get a printwriter
951
                PrintWriter pw = response.getWriter();
952
                // Send back message
953
                pw.println("<?xml version=\"1.0\"?>");
954
                pw.println("<error>");
955
                pw.println("You didn't specify requested docid");
956
                pw.println("</error>");
957
                // Close printwriter
958
                pw.close();
959
                return;
960
            }
961
            // Get output stream
962
            out = response.getOutputStream();
963
            response.setContentType("application/zip"); //MIME type
964
            response.setHeader("Content-Disposition", 
965
            		"attachment; filename=" 
966
            		+ docId + ".zip"); // Set the name of the zip file
967
            		
968
            zOut = new ZipOutputStream(out);
969
            zOut = queryObj
970
                    .getZippedPackage(docId, out, user, groups, passWord);
971
            zOut.finish(); //terminate the zip file
972
            zOut.close(); //close the zip stream
973

    
974
        } catch (Exception e) {
975
            try {
976
                response.setContentType("text/xml"); //MIME type
977
                // Send error message back
978
                if (out != null) {
979
                    PrintWriter pw = new PrintWriter(out);
980
                    pw.println("<?xml version=\"1.0\"?>");
981
                    pw.println("<error>");
982
                    pw.println(e.getMessage());
983
                    pw.println("</error>");
984
                    // Close printwriter
985
                    pw.close();
986
                    // Close output stream
987
                    out.close();
988
                }
989
                // Close zip output stream
990
                if (zOut != null) {
991
                    zOut.close();
992
                }
993
            } catch (IOException ioe) {
994
                logMetacat.error("Problem with the servlet output "
995
                        + "in MetacatServlet.handleExportAction: "
996
                        + ioe.getMessage());
997
            }
998

    
999
            logMetacat.error(
1000
                    "Error in MetacatServlet.handleExportAction: "
1001
                            + e.getMessage());
1002
            e.printStackTrace(System.out);
1003

    
1004
        }
1005

    
1006
    }
1007

    
1008
    /**
1009
     * In eml2 document, the xml can have inline data and data was stripped off
1010
     * and store in file system. This action can be used to read inline data
1011
     * only
1012
     *
1013
     * @param params the Hashtable of HTTP request parameters
1014
     * @param response the HTTP response object linked to the client
1015
     * @param user the username sent the request
1016
     * @param groups the user's groupnames
1017
     */
1018
    private void handleReadInlineDataAction(Hashtable params,
1019
            HttpServletRequest request, HttpServletResponse response,
1020
            String user, String passWord, String[] groups)
1021
    {
1022
        String[] docs = new String[10];
1023
        String inlineDataId = null;
1024
        String docId = "";
1025
        ServletOutputStream out = null;
1026

    
1027
        try {
1028
            // read the params
1029
            if (params.containsKey("inlinedataid")) {
1030
                docs = (String[]) params.get("inlinedataid");
1031
            }
1032
            // Get the docid
1033
            inlineDataId = docs[0];
1034
            // Make sure the client specify docid
1035
            if (inlineDataId == null || inlineDataId.equals("")) {
1036
                throw new Exception("You didn't specify requested inlinedataid"); }
1037

    
1038
            // check for permission
1039
            docId = MetaCatUtil
1040
                    .getDocIdWithoutRevFromInlineDataID(inlineDataId);
1041
            PermissionController controller = new PermissionController(docId);
1042
            // check top level read permission
1043
            if (!controller.hasPermission(user, groups,
1044
                    AccessControlInterface.READSTRING))
1045
            {
1046
                throw new Exception("User " + user
1047
                        + " doesn't have permission " + " to read document "
1048
                        + docId);
1049
            }
1050
            else
1051
            {
1052
              //check data access level
1053
              try
1054
              {
1055
                Hashtable unReadableInlineDataList =
1056
                    PermissionController.getUnReadableInlineDataIdList(docId,
1057
                    user, groups, false);
1058
                if (unReadableInlineDataList.containsValue(
1059
                          MetaCatUtil.getInlineDataIdWithoutRev(inlineDataId)))
1060
                {
1061
                  throw new Exception("User " + user
1062
                       + " doesn't have permission " + " to read inlinedata "
1063
                       + inlineDataId);
1064

    
1065
                }//if
1066
              }//try
1067
              catch (Exception e)
1068
              {
1069
                throw e;
1070
              }//catch
1071
            }//else
1072

    
1073
            // Get output stream
1074
            out = response.getOutputStream();
1075
            // read the inline data from the file
1076
            String inlinePath = MetaCatUtil.getOption("inlinedatafilepath");
1077
            File lineData = new File(inlinePath, inlineDataId);
1078
            FileInputStream input = new FileInputStream(lineData);
1079
            byte[] buffer = new byte[4 * 1024];
1080
            int bytes = input.read(buffer);
1081
            while (bytes != -1) {
1082
                out.write(buffer, 0, bytes);
1083
                bytes = input.read(buffer);
1084
            }
1085
            out.close();
1086

    
1087
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1088
                    inlineDataId, "readinlinedata");
1089
        } catch (Exception e) {
1090
            try {
1091
                PrintWriter pw = null;
1092
                // Send error message back
1093
                if (out != null) {
1094
                    pw = new PrintWriter(out);
1095
                } else {
1096
                    pw = response.getWriter();
1097
                }
1098
                pw.println("<?xml version=\"1.0\"?>");
1099
                pw.println("<error>");
1100
                pw.println(e.getMessage());
1101
                pw.println("</error>");
1102
                // Close printwriter
1103
                pw.close();
1104
                // Close output stream if out is not null
1105
                if (out != null) {
1106
                    out.close();
1107
                }
1108
            } catch (IOException ioe) {
1109
                logMetacat.error("Problem with the servlet output "
1110
                        + "in MetacatServlet.handleExportAction: "
1111
                        + ioe.getMessage());
1112
            }
1113
            logMetacat.error(
1114
                    "Error in MetacatServlet.handleReadInlineDataAction: "
1115
                            + e.getMessage());
1116
        }
1117
    }
1118

    
1119
    /*
1120
     * Get the nodeid from xml_nodes for the inlinedataid
1121
     */
1122
    private long getInlineDataNodeId(String inLineDataId, String docId)
1123
            throws SQLException
1124
    {
1125
        long nodeId = 0;
1126
        String INLINE = "inline";
1127
        boolean hasRow;
1128
        PreparedStatement pStmt = null;
1129
        DBConnection conn = null;
1130
        int serialNumber = -1;
1131
        String sql = "SELECT nodeid FROM xml_nodes WHERE docid=? AND nodedata=? "
1132
                + "AND nodetype='TEXT' AND parentnodeid IN "
1133
                + "(SELECT nodeid FROM xml_nodes WHERE docid=? AND "
1134
                + "nodetype='ELEMENT' AND nodename='" + INLINE + "')";
1135

    
1136
        try {
1137
            //check out DBConnection
1138
            conn = DBConnectionPool
1139
                    .getDBConnection("AccessControlList.isAllowFirst");
1140
            serialNumber = conn.getCheckOutSerialNumber();
1141

    
1142
            pStmt = conn.prepareStatement(sql);
1143
            //bind value
1144
            pStmt.setString(1, docId);//docid
1145
            pStmt.setString(2, inLineDataId);//inlinedataid
1146
            pStmt.setString(3, docId);
1147
            // excute query
1148
            pStmt.execute();
1149
            ResultSet rs = pStmt.getResultSet();
1150
            hasRow = rs.next();
1151
            // get result
1152
            if (hasRow) {
1153
                nodeId = rs.getLong(1);
1154
            }//if
1155

    
1156
        } catch (SQLException e) {
1157
            throw e;
1158
        } finally {
1159
            try {
1160
                pStmt.close();
1161
            } finally {
1162
                DBConnectionPool.returnDBConnection(conn, serialNumber);
1163
            }
1164
        }
1165
        logMetacat.info("The nodeid for inlinedataid " + inLineDataId
1166
                + " is: " + nodeId);
1167
        return nodeId;
1168
    }
1169

    
1170
    /**
1171
     * Handle the "read" request of metadata/data files from Metacat or any
1172
     * files from Internet; transformed metadata XML document into HTML
1173
     * presentation if requested; zip files when more than one were requested.
1174
     *
1175
     * @param params the Hashtable of HTTP request parameters
1176
     * @param request the HTTP request object linked to the client
1177
     * @param response the HTTP response object linked to the client
1178
     * @param user the username sent the request
1179
     * @param groups the user's groupnames
1180
     */
1181
    private void handleReadAction(Hashtable params, HttpServletRequest request,
1182
            HttpServletResponse response, String user, String passWord,
1183
            String[] groups)
1184
    {
1185
        ServletOutputStream out = null;
1186
        ZipOutputStream zout = null;
1187
        PrintWriter pw = null;
1188
        boolean zip = false;
1189
        boolean withInlineData = true;
1190

    
1191
        try {
1192
            String[] docs = new String[0];
1193
            String docid = "";
1194
            String qformat = "";
1195
            String abstrpath = null;
1196

    
1197
            // read the params
1198
            if (params.containsKey("docid")) {
1199
                docs = (String[]) params.get("docid");
1200
            }
1201
            if (params.containsKey("qformat")) {
1202
                qformat = ((String[]) params.get("qformat"))[0];
1203
            }
1204
            // the param for only metadata (eml)
1205
            // we don't support read a eml document without inline data now.
1206
            /*if (params.containsKey("inlinedata")) {
1207

    
1208
                String inlineData = ((String[]) params.get("inlinedata"))[0];
1209
                if (inlineData.equalsIgnoreCase("false")) {
1210
                    withInlineData = false;
1211
                }
1212
            }*/
1213
            if ((docs.length > 1) || qformat.equals("zip")) {
1214
                zip = true;
1215
                out = response.getOutputStream();
1216
                response.setContentType("application/zip"); //MIME type
1217
                zout = new ZipOutputStream(out);
1218
            }
1219
            // go through the list of docs to read
1220
            for (int i = 0; i < docs.length; i++) {
1221
                try {
1222

    
1223
                    URL murl = new URL(docs[i]);
1224
                    Hashtable murlQueryStr = MetaCatUtil.parseQuery(
1225
                            murl.getQuery());
1226
                    // case docid="http://.../?docid=aaa"
1227
                    // or docid="metacat://.../?docid=bbb"
1228
                    if (murlQueryStr.containsKey("docid")) {
1229
                        // get only docid, eliminate the rest
1230
                        docid = (String) murlQueryStr.get("docid");
1231
                        if (zip) {
1232
                            addDocToZip(request, docid, zout, user, groups);
1233
                        } else {
1234
                            readFromMetacat(request, response, docid, qformat,
1235
                                    abstrpath, user, groups, zip, zout,
1236
                                    withInlineData, params);
1237
                        }
1238

    
1239
                        // case docid="http://.../filename"
1240
                    } else {
1241
                        docid = docs[i];
1242
                        if (zip) {
1243
                            addDocToZip(request, docid, zout, user, groups);
1244
                        } else {
1245
                            readFromURLConnection(response, docid);
1246
                        }
1247
                    }
1248

    
1249
                } catch (MalformedURLException mue) {
1250
                    docid = docs[i];
1251
                    if (zip) {
1252
                        addDocToZip(request, docid, zout, user, groups);
1253
                    } else {
1254
                        readFromMetacat(request, response, docid, qformat,
1255
                                abstrpath, user, groups, zip, zout,
1256
                                withInlineData, params);
1257
                    }
1258
                }
1259
            }
1260

    
1261
            if (zip) {
1262
                zout.finish(); //terminate the zip file
1263
                zout.close(); //close the zip stream
1264
            }
1265

    
1266
        } catch (McdbDocNotFoundException notFoundE) {
1267
            // To handle doc not found exception
1268
            // the docid which didn't be found
1269
            String notFoundDocId = notFoundE.getUnfoundDocId();
1270
            String notFoundRevision = notFoundE.getUnfoundRevision();
1271
            logMetacat.warn("Missed id: " + notFoundDocId);
1272
            logMetacat.warn("Missed rev: " + notFoundRevision);
1273
            try {
1274
                // read docid from remote server
1275
                readFromRemoteMetaCat(response, notFoundDocId,
1276
                        notFoundRevision, user, passWord, out, zip, zout);
1277
                // Close zout outputstream
1278
                if (zout != null) {
1279
                    zout.close();
1280
                }
1281
                // close output stream
1282
                if (out != null) {
1283
                    out.close();
1284
                }
1285

    
1286
            } catch (Exception exc) {
1287
                logMetacat.error(
1288
                        "Erorr in MetacatServlet.hanldReadAction: "
1289
                                + exc.getMessage());
1290
                try {
1291
                    if (out != null) {
1292
                        response.setContentType("text/xml");
1293
                        // Send back error message by printWriter
1294
                        pw = new PrintWriter(out);
1295
                        pw.println("<?xml version=\"1.0\"?>");
1296
                        pw.println("<error>");
1297
                        pw.println(notFoundE.getMessage());
1298
                        pw.println("</error>");
1299
                        pw.close();
1300
                        out.close();
1301

    
1302
                    } else {
1303
                        response.setContentType("text/xml"); //MIME type
1304
                        // Send back error message if out = null
1305
                        if (pw == null) {
1306
                            // If pw is null, open the respnose
1307
                            pw = response.getWriter();
1308
                        }
1309
                        pw.println("<?xml version=\"1.0\"?>");
1310
                        pw.println("<error>");
1311
                        pw.println(notFoundE.getMessage());
1312
                        pw.println("</error>");
1313
                        pw.close();
1314
                    }
1315
                    // close zout
1316
                    if (zout != null) {
1317
                        zout.close();
1318
                    }
1319
                } catch (IOException ie) {
1320
                    logMetacat.error("Problem with the servlet output "
1321
                            + "in MetacatServlet.handleReadAction: "
1322
                            + ie.getMessage());
1323
                }
1324
            }
1325
        } catch (Exception e) {
1326
            try {
1327

    
1328
                if (out != null) {
1329
                    response.setContentType("text/xml"); //MIME type
1330
                    pw = new PrintWriter(out);
1331
                    pw.println("<?xml version=\"1.0\"?>");
1332
                    pw.println("<error>");
1333
                    pw.println(e.getMessage());
1334
                    pw.println("</error>");
1335
                    pw.close();
1336
                    out.close();
1337
                } else {
1338
                    response.setContentType("text/xml"); //MIME type
1339
                    // Send back error message if out = null
1340
                    if (pw == null) {
1341
                        pw = response.getWriter();
1342
                    }
1343
                    pw.println("<?xml version=\"1.0\"?>");
1344
                    pw.println("<error>");
1345
                    pw.println(e.getMessage());
1346
                    pw.println("</error>");
1347
                    pw.close();
1348

    
1349
                }
1350
                // Close zip output stream
1351
                if (zout != null) {
1352
                    zout.close();
1353
                }
1354

    
1355
            } catch (IOException ioe) {
1356
                logMetacat.error("Problem with the servlet output "
1357
                        + "in MetacatServlet.handleReadAction: "
1358
                        + ioe.getMessage());
1359
                ioe.printStackTrace(System.out);
1360

    
1361
            }
1362

    
1363
            logMetacat.error(
1364
                    "Error in MetacatServlet.handleReadAction: "
1365
                            + e.getMessage());
1366
            //e.printStackTrace(System.out);
1367
        }
1368
    }
1369

    
1370
    /** read metadata or data from Metacat
1371
     */
1372
    private void readFromMetacat(HttpServletRequest request,
1373
            HttpServletResponse response, String docid, String qformat,
1374
            String abstrpath, String user, String[] groups, boolean zip,
1375
            ZipOutputStream zout, boolean withInlineData, Hashtable params)
1376
            throws ClassNotFoundException, IOException, SQLException,
1377
            McdbException, Exception
1378
    {
1379

    
1380
        try {
1381
            
1382
            // here is hack for handle docid=john.10(in order to tell mike.jim.10.1
1383
            // mike.jim.10, we require to provide entire docid with rev). But
1384
            // some old client they only provide docid without rev, so we need
1385
            // to handle this suituation. First we will check how many
1386
            // seperator here, if only one, we will append the rev in xml_documents
1387
            // to the id.
1388
            docid = appendRev(docid);
1389
         
1390
            DocumentImpl doc = new DocumentImpl(docid);
1391

    
1392
            //check the permission for read
1393
            if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1394
                Exception e = new Exception("User " + user
1395
                        + " does not have permission"
1396
                        + " to read the document with the docid " + docid);
1397

    
1398
                throw e;
1399
            }
1400

    
1401
            if (doc.getRootNodeID() == 0) {
1402
                // this is data file
1403
                String filepath = MetaCatUtil.getOption("datafilepath");
1404
                if (!filepath.endsWith("/")) {
1405
                    filepath += "/";
1406
                }
1407
                String filename = filepath + docid;
1408
                FileInputStream fin = null;
1409
                fin = new FileInputStream(filename);
1410

    
1411
                //MIME type
1412
                String contentType = getServletContext().getMimeType(filename);
1413
                if (contentType == null) {
1414
                    ContentTypeProvider provider = new ContentTypeProvider(
1415
                            docid);
1416
                    contentType = provider.getContentType();
1417
                    logMetacat.warn("Final contenttype is: "
1418
                            + contentType);
1419
                }
1420

    
1421
                response.setContentType(contentType);
1422
                // if we decide to use "application/octet-stream" for all data
1423
                // returns
1424
                // response.setContentType("application/octet-stream");
1425

    
1426
                try {
1427

    
1428
                    ServletOutputStream out = response.getOutputStream();
1429
                    byte[] buf = new byte[4 * 1024]; // 4K buffer
1430
                    int b = fin.read(buf);
1431
                    while (b != -1) {
1432
                        out.write(buf, 0, b);
1433
                        b = fin.read(buf);
1434
                    }
1435
                } finally {
1436
                    if (fin != null) fin.close();
1437
                }
1438

    
1439
            } else {
1440
                // this is metadata doc
1441
                if (qformat.equals("xml") || qformat.equals("")) {
1442
                    // if equals "", that means no qformat is specified. hence
1443
                    // by default the document should be returned in xml format
1444
                    // set content type first
1445
                    response.setContentType("text/xml"); //MIME type
1446
                    PrintWriter out = response.getWriter();
1447
                    doc.toXml(out, user, groups, withInlineData);
1448
                } else {
1449
                    response.setContentType("text/html"); //MIME type
1450
                    PrintWriter out = response.getWriter();
1451

    
1452
                    // Look up the document type
1453
                    String doctype = doc.getDoctype();
1454
                    // Transform the document to the new doctype
1455
                    DBTransform dbt = new DBTransform();
1456
                    dbt.transformXMLDocument(doc.toString(user, groups,
1457
                            withInlineData), doctype, "-//W3C//HTML//EN",
1458
                            qformat, out, params);
1459
                }
1460

    
1461
            }
1462
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1463
                    docid, "read");
1464
        } catch (Exception except) {
1465
            throw except;
1466
        }
1467
    }
1468

    
1469
    /**
1470
     * read data from URLConnection
1471
     */
1472
    private void readFromURLConnection(HttpServletResponse response,
1473
            String docid) throws IOException, MalformedURLException
1474
    {
1475
        ServletOutputStream out = response.getOutputStream();
1476
        String contentType = getServletContext().getMimeType(docid); //MIME
1477
                                                                     // type
1478
        if (contentType == null) {
1479
            if (docid.endsWith(".xml")) {
1480
                contentType = "text/xml";
1481
            } else if (docid.endsWith(".css")) {
1482
                contentType = "text/css";
1483
            } else if (docid.endsWith(".dtd")) {
1484
                contentType = "text/plain";
1485
            } else if (docid.endsWith(".xsd")) {
1486
                contentType = "text/xml";
1487
            } else if (docid.endsWith("/")) {
1488
                contentType = "text/html";
1489
            } else {
1490
                File f = new File(docid);
1491
                if (f.isDirectory()) {
1492
                    contentType = "text/html";
1493
                } else {
1494
                    contentType = "application/octet-stream";
1495
                }
1496
            }
1497
        }
1498
        response.setContentType(contentType);
1499
        // if we decide to use "application/octet-stream" for all data returns
1500
        // response.setContentType("application/octet-stream");
1501

    
1502
        // this is http url
1503
        URL url = new URL(docid);
1504
        BufferedInputStream bis = null;
1505
        try {
1506
            bis = new BufferedInputStream(url.openStream());
1507
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1508
            int b = bis.read(buf);
1509
            while (b != -1) {
1510
                out.write(buf, 0, b);
1511
                b = bis.read(buf);
1512
            }
1513
        } finally {
1514
            if (bis != null) bis.close();
1515
        }
1516

    
1517
    }
1518

    
1519
    /**
1520
     * read file/doc and write to ZipOutputStream
1521
     *
1522
     * @param docid
1523
     * @param zout
1524
     * @param user
1525
     * @param groups
1526
     * @throws ClassNotFoundException
1527
     * @throws IOException
1528
     * @throws SQLException
1529
     * @throws McdbException
1530
     * @throws Exception
1531
     */
1532
    private void addDocToZip(HttpServletRequest request, String docid,
1533
            ZipOutputStream zout, String user, String[] groups) throws
1534
            ClassNotFoundException, IOException, SQLException, McdbException,
1535
            Exception
1536
    {
1537
        byte[] bytestring = null;
1538
        ZipEntry zentry = null;
1539

    
1540
        try {
1541
            URL url = new URL(docid);
1542

    
1543
            // this http url; read from URLConnection; add to zip
1544
            zentry = new ZipEntry(docid);
1545
            zout.putNextEntry(zentry);
1546
            BufferedInputStream bis = null;
1547
            try {
1548
                bis = new BufferedInputStream(url.openStream());
1549
                byte[] buf = new byte[4 * 1024]; // 4K buffer
1550
                int b = bis.read(buf);
1551
                while (b != -1) {
1552
                    zout.write(buf, 0, b);
1553
                    b = bis.read(buf);
1554
                }
1555
            } finally {
1556
                if (bis != null) bis.close();
1557
            }
1558
            zout.closeEntry();
1559

    
1560
        } catch (MalformedURLException mue) {
1561

    
1562
            // this is metacat doc (data file or metadata doc)
1563
            try {
1564
                DocumentImpl doc = new DocumentImpl(docid);
1565

    
1566
                //check the permission for read
1567
                if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1568
                    Exception e = new Exception("User " + user
1569
                            + " does not have "
1570
                            + "permission to read the document with the docid "
1571
                            + docid);
1572
                    throw e;
1573
                }
1574

    
1575
                if (doc.getRootNodeID() == 0) {
1576
                    // this is data file; add file to zip
1577
                    String filepath = MetaCatUtil.getOption("datafilepath");
1578
                    if (!filepath.endsWith("/")) {
1579
                        filepath += "/";
1580
                    }
1581
                    String filename = filepath + docid;
1582
                    FileInputStream fin = null;
1583
                    fin = new FileInputStream(filename);
1584
                    try {
1585

    
1586
                        zentry = new ZipEntry(docid);
1587
                        zout.putNextEntry(zentry);
1588
                        byte[] buf = new byte[4 * 1024]; // 4K buffer
1589
                        int b = fin.read(buf);
1590
                        while (b != -1) {
1591
                            zout.write(buf, 0, b);
1592
                            b = fin.read(buf);
1593
                        }
1594
                    } finally {
1595
                        if (fin != null) fin.close();
1596
                    }
1597
                    zout.closeEntry();
1598

    
1599
                } else {
1600
                    // this is metadata doc; add doc to zip
1601
                    bytestring = doc.toString().getBytes();
1602
                    zentry = new ZipEntry(docid + ".xml");
1603
                    zentry.setSize(bytestring.length);
1604
                    zout.putNextEntry(zentry);
1605
                    zout.write(bytestring, 0, bytestring.length);
1606
                    zout.closeEntry();
1607
                }
1608
                EventLog.getInstance().log(request.getRemoteAddr(), user,
1609
                        docid, "read");
1610
            } catch (Exception except) {
1611
                throw except;
1612
            }
1613
        }
1614
    }
1615

    
1616
    /**
1617
     * If metacat couldn't find a data file or document locally, it will read
1618
     * this docid from its home server. This is for the replication feature
1619
     */
1620
    private void readFromRemoteMetaCat(HttpServletResponse response,
1621
            String docid, String rev, String user, String password,
1622
            ServletOutputStream out, boolean zip, ZipOutputStream zout)
1623
            throws Exception
1624
    {
1625
        // Create a object of RemoteDocument, "" is for zipEntryPath
1626
        RemoteDocument remoteDoc = new RemoteDocument(docid, rev, user,
1627
                password, "");
1628
        String docType = remoteDoc.getDocType();
1629
        // Only read data file
1630
        if (docType.equals("BIN")) {
1631
            // If it is zip format
1632
            if (zip) {
1633
                remoteDoc.readDocumentFromRemoteServerByZip(zout);
1634
            } else {
1635
                if (out == null) {
1636
                    out = response.getOutputStream();
1637
                }
1638
                response.setContentType("application/octet-stream");
1639
                remoteDoc.readDocumentFromRemoteServer(out);
1640
            }
1641
        } else {
1642
            throw new Exception("Docid: " + docid + "." + rev
1643
                    + " couldn't find");
1644
        }
1645
    }
1646

    
1647
    /**
1648
     * Handle the database putdocument request and write an XML document to the
1649
     * database connection
1650
     */
1651
    private void handleInsertOrUpdateAction(HttpServletRequest request,
1652
            HttpServletResponse response, PrintWriter out, Hashtable params,
1653
            String user, String[] groups)
1654
    {
1655
        DBConnection dbConn = null;
1656
        int serialNumber = -1;
1657

    
1658
        if(params.get("docid") == null){
1659
            out.println("<?xml version=\"1.0\"?>");
1660
            out.println("<error>");
1661
            out.println("Docid not specified");
1662
            out.println("</error>");
1663
            logMetacat.error("Docid not specified");
1664
            return;
1665
        }
1666
        
1667
        if(!MetaCatUtil.canInsertOrUpdate(user, groups)){
1668
        	out.println("<?xml version=\"1.0\"?>");
1669
            out.println("<error>");
1670
            out.println("User '" + user + "' not allowed to insert and update");
1671
            out.println("</error>");
1672
            logMetacat.error("User '" + user + "' not allowed to insert and update");
1673
            return;
1674
        }
1675

    
1676
        try {
1677
            // Get the document indicated
1678
            String[] doctext = (String[]) params.get("doctext");
1679
            String pub = null;
1680
            if (params.containsKey("public")) {
1681
                pub = ((String[]) params.get("public"))[0];
1682
            }
1683

    
1684
            StringReader dtd = null;
1685
            if (params.containsKey("dtdtext")) {
1686
                String[] dtdtext = (String[]) params.get("dtdtext");
1687
                try {
1688
                    if (!dtdtext[0].equals("")) {
1689
                        dtd = new StringReader(dtdtext[0]);
1690
                    }
1691
                } catch (NullPointerException npe) {
1692
                }
1693
            }
1694

    
1695
            if(doctext == null){
1696
                out.println("<?xml version=\"1.0\"?>");
1697
                out.println("<error>");
1698
                out.println("Document text not submitted");
1699
                out.println("</error>");
1700
                return;
1701
            }
1702

    
1703
            StringReader xml = new StringReader(doctext[0]);
1704
            boolean validate = false;
1705
            DocumentImplWrapper documentWrapper = null;
1706
            try {
1707
                // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ...
1708
                // >
1709
                // in order to decide whether to use validation parser
1710
                validate = needDTDValidation(xml);
1711
                if (validate) {
1712
                    // set a dtd base validation parser
1713
                    String rule = DocumentImpl.DTD;
1714
                    documentWrapper = new DocumentImplWrapper(rule, validate);
1715
                } else if (needSchemaValidation(xml)) {
1716
                    // for eml2
1717
                    String namespace = findNamespace(xml);
1718
                    if (namespace.compareTo(DocumentImpl.EML2_0_0NAMESPACE) == 0
1719
                                || namespace.compareTo(
1720
                                DocumentImpl.EML2_0_1NAMESPACE) == 0) {
1721
                        // set eml2 base validation parser
1722
                        String rule = DocumentImpl.EML200;
1723
                        // using emlparser to check id validation
1724
                        EMLParser parser = new EMLParser(doctext[0]);
1725
                        documentWrapper = new DocumentImplWrapper(rule, true);
1726
                    } else if (namespace.compareTo(
1727
                                DocumentImpl.EML2_1_0NAMESPACE) == 0) {
1728
                        // set eml2 base validation parser
1729
                        String rule = DocumentImpl.EML210;
1730
                        // using emlparser to check id validation
1731
                        EMLParser parser = new EMLParser(doctext[0]);
1732
                        documentWrapper = new DocumentImplWrapper(rule, true);
1733
                    } else {
1734
                        // set schema base validation parser
1735
                        String rule = DocumentImpl.SCHEMA;
1736
                        documentWrapper = new DocumentImplWrapper(rule, true);
1737
                    }
1738
                } else {
1739
                    documentWrapper = new DocumentImplWrapper("", false);
1740
                }
1741

    
1742
                String[] action = (String[]) params.get("action");
1743
                String[] docid = (String[]) params.get("docid");
1744
                String newdocid = null;
1745

    
1746
                String doAction = null;
1747
                if (action[0].equals("insert")) {
1748
                    doAction = "INSERT";
1749
                } else if (action[0].equals("update")) {
1750
                    doAction = "UPDATE";
1751
                }
1752

    
1753
                try {
1754
                    // get a connection from the pool
1755
                    dbConn = DBConnectionPool
1756
                            .getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1757
                    serialNumber = dbConn.getCheckOutSerialNumber();
1758

    
1759
                    // write the document to the database
1760
                    try {
1761
                        String accNumber = docid[0];
1762
                        logMetacat.warn("" + doAction + " "
1763
                                + accNumber + "...");
1764
                        if (accNumber.equals("")) {
1765
                            accNumber = null;
1766
                        }
1767
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1768
                                doAction, accNumber, user, groups);
1769
                        EventLog.getInstance().log(request.getRemoteAddr(),
1770
                                user, accNumber, action[0]);
1771
                    } catch (NullPointerException npe) {
1772
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1773
                                doAction, null, user, groups);
1774
                        EventLog.getInstance().log(request.getRemoteAddr(),
1775
                                user, "", action[0]);
1776
                    }
1777
                }
1778
                finally {
1779
                    // Return db connection
1780
                    DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1781
                }
1782

    
1783
                // set content type and other response header fields first
1784
                //response.setContentType("text/xml");
1785
                out.println("<?xml version=\"1.0\"?>");
1786
                out.println("<success>");
1787
                out.println("<docid>" + newdocid + "</docid>");
1788
                out.println("</success>");
1789

    
1790
            } catch (NullPointerException npe) {
1791
                //response.setContentType("text/xml");
1792
                out.println("<?xml version=\"1.0\"?>");
1793
                out.println("<error>");
1794
                out.println(npe.getMessage());
1795
                out.println("</error>");
1796
                logMetacat.warn("Error in writing eml document to the database" + npe.getMessage());
1797
            }
1798
        } catch (Exception e) {
1799
            //response.setContentType("text/xml");
1800
            out.println("<?xml version=\"1.0\"?>");
1801
            out.println("<error>");
1802
            out.println(e.getMessage());
1803
            out.println("</error>");
1804
            logMetacat.warn("Error in writing eml document to the database" + e.getMessage());
1805
        }
1806
    }
1807

    
1808
    /**
1809
     * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... > in
1810
     * order to decide whether to use validation parser
1811
     */
1812
    private static boolean needDTDValidation(StringReader xmlreader)
1813
            throws IOException
1814
    {
1815

    
1816
        StringBuffer cbuff = new StringBuffer();
1817
        java.util.Stack st = new java.util.Stack();
1818
        boolean validate = false;
1819
        int c;
1820
        int inx;
1821

    
1822
        // read from the stream until find the keywords
1823
        while ((st.empty() || st.size() < 4) && ((c = xmlreader.read()) != -1)) {
1824
            cbuff.append((char) c);
1825

    
1826
            // "<!DOCTYPE" keyword is found; put it in the stack
1827
            if ((inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1) {
1828
                cbuff = new StringBuffer();
1829
                st.push("<!DOCTYPE");
1830
            }
1831
            // "PUBLIC" keyword is found; put it in the stack
1832
            if ((inx = cbuff.toString().indexOf("PUBLIC")) != -1) {
1833
                cbuff = new StringBuffer();
1834
                st.push("PUBLIC");
1835
            }
1836
            // "SYSTEM" keyword is found; put it in the stack
1837
            if ((inx = cbuff.toString().indexOf("SYSTEM")) != -1) {
1838
                cbuff = new StringBuffer();
1839
                st.push("SYSTEM");
1840
            }
1841
            // ">" character is found; put it in the stack
1842
            // ">" is found twice: fisrt from <?xml ...?>
1843
            // and second from <!DOCTYPE ... >
1844
            if ((inx = cbuff.toString().indexOf(">")) != -1) {
1845
                cbuff = new StringBuffer();
1846
                st.push(">");
1847
            }
1848
        }
1849

    
1850
        // close the stream
1851
        xmlreader.reset();
1852

    
1853
        // check the stack whether it contains the keywords:
1854
        // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1855
        if (st.size() == 4) {
1856
            if (((String) st.pop()).equals(">")
1857
                    && (((String) st.peek()).equals("PUBLIC") | ((String) st
1858
                            .pop()).equals("SYSTEM"))
1859
                    && ((String) st.pop()).equals("<!DOCTYPE")) {
1860
                validate = true;
1861
            }
1862
        }
1863

    
1864
        logMetacat.warn("Validation for dtd is " + validate);
1865
        return validate;
1866
    }
1867

    
1868
    // END OF INSERT/UPDATE SECTION
1869

    
1870
    /* check if the xml string contains key words to specify schema loocation */
1871
    private boolean needSchemaValidation(StringReader xml) throws IOException
1872
    {
1873
        boolean needSchemaValidate = false;
1874
        if (xml == null) {
1875
            logMetacat.warn("Validation for schema is "
1876
                    + needSchemaValidate);
1877
            return needSchemaValidate;
1878
        }
1879
        logMetacat.info("before get target line");
1880
        String targetLine = getSchemaLine(xml);
1881
        logMetacat.info("after get target line");
1882
        // to see if the second line contain some keywords
1883
        if (targetLine != null
1884
                && (targetLine.indexOf(SCHEMALOCATIONKEYWORD) != -1 || targetLine
1885
                        .indexOf(NONAMESPACELOCATION) != -1)) {
1886
            // if contains schema location key word, should be validate
1887
            needSchemaValidate = true;
1888
        }
1889

    
1890
        logMetacat.warn("Validation for schema is "
1891
                + needSchemaValidate);
1892
        return needSchemaValidate;
1893

    
1894
    }
1895

    
1896
    /* check if the xml string contains key words to specify schema loocation */
1897
    private String findNamespace(StringReader xml) throws IOException
1898
    {
1899
        String namespace = null;
1900

    
1901
        String eml2_0_0NameSpace = DocumentImpl.EML2_0_0NAMESPACE;
1902
        String eml2_0_1NameSpace = DocumentImpl.EML2_0_1NAMESPACE;
1903
        String eml2_1_0NameSpace = DocumentImpl.EML2_1_0NAMESPACE;
1904

    
1905
        if (xml == null) {
1906
            logMetacat.warn("Validation for schema is "
1907
                    + namespace);
1908
            return namespace;
1909
        }
1910
        String targetLine = getSchemaLine(xml);
1911

    
1912
        if (targetLine != null) {
1913

    
1914
            int startIndex = targetLine.indexOf(SCHEMALOCATIONKEYWORD);
1915
            int start = 1;
1916
            int end = 1;
1917
            String schemaLocation = null;
1918
            int count = 0;
1919
            if (startIndex != -1) {
1920
                for (int i = startIndex; i < targetLine.length(); i++) {
1921
                    if (targetLine.charAt(i) == '"') {
1922
                        count++;
1923
                    }
1924
                    if (targetLine.charAt(i) == '"' && count == 1) {
1925
                        start = i;
1926
                    }
1927
                    if (targetLine.charAt(i) == '"' && count == 2) {
1928
                        end = i;
1929
                        break;
1930
                    }
1931
                }
1932
            }
1933
            schemaLocation = targetLine.substring(start + 1, end);
1934
            logMetacat.info("schemaLocation in xml is: "
1935
                    + schemaLocation);
1936
            if (schemaLocation.indexOf(eml2_0_0NameSpace) != -1) {
1937
                namespace = eml2_0_0NameSpace;
1938
            } else if (schemaLocation.indexOf(eml2_0_1NameSpace) != -1) {
1939
                namespace = eml2_0_1NameSpace;
1940
            } else if (schemaLocation.indexOf(eml2_1_0NameSpace) != -1) {
1941
                namespace = eml2_1_0NameSpace;
1942
            }
1943
        }
1944

    
1945
        logMetacat.warn("Validation for eml is " + namespace);
1946

    
1947
        return namespace;
1948

    
1949
    }
1950

    
1951
    private String getSchemaLine(StringReader xml) throws IOException
1952
    {
1953
        // find the line
1954
        String secondLine = null;
1955
        int count = 0;
1956
        int endIndex = 0;
1957
        int startIndex = 0;
1958
        final int TARGETNUM = 2;
1959
        StringBuffer buffer = new StringBuffer();
1960
        boolean comment = false;
1961
        char thirdPreviousCharacter = '?';
1962
        char secondPreviousCharacter = '?';
1963
        char previousCharacter = '?';
1964
        char currentCharacter = '?';
1965
        int tmp = xml.read();
1966
        while (tmp != -1) {
1967
            currentCharacter = (char)tmp;
1968
            //in a comment
1969
            if (currentCharacter == '-' && previousCharacter == '-'
1970
                    && secondPreviousCharacter == '!'
1971
                    && thirdPreviousCharacter == '<') {
1972
                comment = true;
1973
            }
1974
            //out of comment
1975
            if (comment && currentCharacter == '>' && previousCharacter == '-'
1976
                    && secondPreviousCharacter == '-') {
1977
                comment = false;
1978
            }
1979

    
1980
            //this is not comment
1981
            if (currentCharacter != '!' && previousCharacter == '<' && !comment) {
1982
                count++;
1983
            }
1984
            // get target line
1985
            if (count == TARGETNUM && currentCharacter != '>') {
1986
                buffer.append(currentCharacter);
1987
            }
1988
            if (count == TARGETNUM && currentCharacter == '>') {
1989
                break;
1990
            }
1991
            thirdPreviousCharacter = secondPreviousCharacter;
1992
            secondPreviousCharacter = previousCharacter;
1993
            previousCharacter = currentCharacter;
1994
            tmp = xml.read();
1995
        }
1996
        secondLine = buffer.toString();
1997
        logMetacat.info("the second line string is: " + secondLine);
1998
        
1999
        xml.reset();
2000
        return secondLine;
2001
    }
2002

    
2003
    /**
2004
     * Handle the database delete request and delete an XML document from the
2005
     * database connection
2006
     */
2007
    private void handleDeleteAction(PrintWriter out, Hashtable params,
2008
            HttpServletRequest request, HttpServletResponse response,
2009
            String user, String[] groups)
2010
    {
2011

    
2012
        String[] docid = (String[]) params.get("docid");
2013

    
2014
        if(docid == null){
2015
          response.setContentType("text/xml");
2016
          out.println("<?xml version=\"1.0\"?>");
2017
          out.println("<error>");
2018
          out.println("Docid not specified.");
2019
          out.println("</error>");
2020
          logMetacat.error("Docid not specified for the document to be deleted.");
2021
        } else {
2022

    
2023
            // delete the document from the database
2024
            try {
2025

    
2026
                try {
2027
                    // null means notify server is null
2028
                    DocumentImpl.delete(docid[0], user, groups, null);
2029
                    EventLog.getInstance().log(request.getRemoteAddr(),
2030
                                               user, docid[0], "delete");
2031
                    response.setContentType("text/xml");
2032
                    out.println("<?xml version=\"1.0\"?>");
2033
                    out.println("<success>");
2034
                    out.println("Document deleted.");
2035
                    out.println("</success>");
2036
                    logMetacat.warn("Document deleted.");
2037
                }
2038
                catch (AccessionNumberException ane) {
2039
                    response.setContentType("text/xml");
2040
                    out.println("<?xml version=\"1.0\"?>");
2041
                    out.println("<error>");
2042
                    //out.println("Error deleting document!!!");
2043
                    out.println(ane.getMessage());
2044
                    out.println("</error>");
2045
                    logMetacat.error("Document could not be deleted: " 
2046
                    		+ ane.getMessage());
2047
                }
2048
            }
2049
            catch (Exception e) {
2050
                response.setContentType("text/xml");
2051
                out.println("<?xml version=\"1.0\"?>");
2052
                out.println("<error>");
2053
                out.println(e.getMessage());
2054
                out.println("</error>");
2055
                logMetacat.error("Document could not be deleted: " 
2056
                		+ e.getMessage());
2057
            }
2058
        }
2059
    }
2060

    
2061
    /**
2062
     * Handle the validation request and return the results to the requestor
2063
     */
2064
    private void handleValidateAction(PrintWriter out, Hashtable params)
2065
    {
2066

    
2067
        // Get the document indicated
2068
        String valtext = null;
2069
        DBConnection dbConn = null;
2070
        int serialNumber = -1;
2071

    
2072
        try {
2073
            valtext = ((String[]) params.get("valtext"))[0];
2074
        } catch (Exception nullpe) {
2075

    
2076
            String docid = null;
2077
            try {
2078
                // Find the document id number
2079
                docid = ((String[]) params.get("docid"))[0];
2080

    
2081
                // Get the document indicated from the db
2082
                DocumentImpl xmldoc = new DocumentImpl(docid);
2083
                valtext = xmldoc.toString();
2084

    
2085
            } catch (NullPointerException npe) {
2086

    
2087
                out.println("<error>Error getting document ID: " + docid
2088
                        + "</error>");
2089
                //if ( conn != null ) { util.returnConnection(conn); }
2090
                return;
2091
            } catch (Exception e) {
2092

    
2093
                out.println(e.getMessage());
2094
            }
2095
        }
2096

    
2097
        try {
2098
            // get a connection from the pool
2099
            dbConn = DBConnectionPool
2100
                    .getDBConnection("MetaCatServlet.handleValidateAction");
2101
            serialNumber = dbConn.getCheckOutSerialNumber();
2102
            DBValidate valobj = new DBValidate(saxparser, dbConn);
2103
            boolean valid = valobj.validateString(valtext);
2104

    
2105
            // set content type and other response header fields first
2106

    
2107
            out.println(valobj.returnErrors());
2108

    
2109
        } catch (NullPointerException npe2) {
2110
            // set content type and other response header fields first
2111

    
2112
            out.println("<error>Error validating document.</error>");
2113
        } catch (Exception e) {
2114

    
2115
            out.println(e.getMessage());
2116
        } finally {
2117
            // Return db connection
2118
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2119
        }
2120
    }
2121

    
2122
    /**
2123
     * Handle "getrevsionanddoctype" action Given a docid, return it's current
2124
     * revision and doctype from data base The output is String look like
2125
     * "rev;doctype"
2126
     */
2127
    private void handleGetRevisionAndDocTypeAction(PrintWriter out,
2128
            Hashtable params)
2129
    {
2130
        // To store doc parameter
2131
        String[] docs = new String[10];
2132
        // Store a single doc id
2133
        String givenDocId = null;
2134
        // Get docid from parameters
2135
        if (params.containsKey("docid")) {
2136
            docs = (String[]) params.get("docid");
2137
        }
2138
        // Get first docid form string array
2139
        givenDocId = docs[0];
2140

    
2141
        try {
2142
            // Make sure there is a docid
2143
            if (givenDocId == null || givenDocId.equals("")) { throw new Exception(
2144
                    "User didn't specify docid!"); }//if
2145

    
2146
            // Create a DBUtil object
2147
            DBUtil dbutil = new DBUtil();
2148
            // Get a rev and doctype
2149
            String revAndDocType = dbutil
2150
                    .getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
2151
            out.println(revAndDocType);
2152

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

    
2161
    }
2162

    
2163
    /**
2164
     * Handle "getaccesscontrol" action. Read Access Control List from db
2165
     * connection in XML format
2166
     */
2167
    private void handleGetAccessControlAction(PrintWriter out,
2168
            Hashtable params, HttpServletResponse response, String username,
2169
            String[] groupnames)
2170
    {
2171
        DBConnection dbConn = null;
2172
        int serialNumber = -1;
2173
        String docid = ((String[]) params.get("docid"))[0];
2174

    
2175
        try {
2176

    
2177
            // get connection from the pool
2178
            dbConn = DBConnectionPool
2179
                    .getDBConnection("MetaCatServlet.handleGetAccessControlAction");
2180
            serialNumber = dbConn.getCheckOutSerialNumber();
2181
            AccessControlList aclobj = new AccessControlList(dbConn);
2182
            String acltext = aclobj.getACL(docid, username, groupnames);
2183
            out.println(acltext);
2184

    
2185
        } catch (Exception e) {
2186
            out.println("<?xml version=\"1.0\"?>");
2187
            out.println("<error>");
2188
            out.println(e.getMessage());
2189
            out.println("</error>");
2190
        } finally {
2191
            // Retrun db connection to pool
2192
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2193
        }
2194
    }
2195

    
2196
    /**
2197
     * Handle the "getprincipals" action. Read all principals from
2198
     * authentication scheme in XML format
2199
     */
2200
    private void handleGetPrincipalsAction(PrintWriter out, String user,
2201
            String password)
2202
    {
2203
        try {
2204
            AuthSession auth = new AuthSession();
2205
            String principals = auth.getPrincipals(user, password);
2206
            out.println(principals);
2207

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

    
2216
    /**
2217
     * Handle "getdoctypes" action. Read all doctypes from db connection in XML
2218
     * format
2219
     */
2220
    private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
2221
            HttpServletResponse response)
2222
    {
2223
        try {
2224
            DBUtil dbutil = new DBUtil();
2225
            String doctypes = dbutil.readDoctypes();
2226
            out.println(doctypes);
2227
        } catch (Exception e) {
2228
            out.println("<?xml version=\"1.0\"?>");
2229
            out.println("<error>");
2230
            out.println(e.getMessage());
2231
            out.println("</error>");
2232
        }
2233
    }
2234

    
2235
    /**
2236
     * Handle the "getdtdschema" action. Read DTD or Schema file for a given
2237
     * doctype from Metacat catalog system
2238
     */
2239
    private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
2240
            HttpServletResponse response)
2241
    {
2242

    
2243
        String doctype = null;
2244
        String[] doctypeArr = (String[]) params.get("doctype");
2245

    
2246
        // get only the first doctype specified in the list of doctypes
2247
        // it could be done for all doctypes in that list
2248
        if (doctypeArr != null) {
2249
            doctype = ((String[]) params.get("doctype"))[0];
2250
        }
2251

    
2252
        try {
2253
            DBUtil dbutil = new DBUtil();
2254
            String dtdschema = dbutil.readDTDSchema(doctype);
2255
            out.println(dtdschema);
2256

    
2257
        } catch (Exception e) {
2258
            out.println("<?xml version=\"1.0\"?>");
2259
            out.println("<error>");
2260
            out.println(e.getMessage());
2261
            out.println("</error>");
2262
        }
2263

    
2264
    }
2265

    
2266
    /**
2267
     * Handle the "getlastdocid" action. Get the latest docid with rev number
2268
     * from db connection in XML format
2269
     */
2270
    private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
2271
            HttpServletResponse response)
2272
    {
2273

    
2274
        String scope = ((String[]) params.get("scope"))[0];
2275
        if (scope == null) {
2276
            scope = ((String[]) params.get("username"))[0];
2277
        }
2278

    
2279
        try {
2280

    
2281
            DBUtil dbutil = new DBUtil();
2282
            String lastDocid = dbutil.getMaxDocid(scope);
2283
            out.println("<?xml version=\"1.0\"?>");
2284
            out.println("<lastDocid>");
2285
            out.println("  <scope>" + scope + "</scope>");
2286
            out.println("  <docid>" + lastDocid + "</docid>");
2287
            out.println("</lastDocid>");
2288

    
2289
        } catch (Exception e) {
2290
            out.println("<?xml version=\"1.0\"?>");
2291
            out.println("<error>");
2292
            out.println(e.getMessage());
2293
            out.println("</error>");
2294
        }
2295
    }
2296

    
2297
    /**
2298
     * Print a report from the event log based on filter parameters passed in
2299
     * from the web.
2300
     *
2301
     * @param params the parameters from the web request
2302
     * @param request the http request object for getting request details
2303
     * @param response the http response object for writing output
2304
     */
2305
    private void handleGetLogAction(Hashtable params, HttpServletRequest request,
2306
            HttpServletResponse response, String username, String[] groups)
2307
    {
2308
        try {
2309
            response.setContentType("text/xml");
2310
            PrintWriter out = response.getWriter();
2311

    
2312
            // Check that the user is authenticated as an administrator account
2313
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2314
                out.print("<error>");
2315
                out.print("The user \"" + username +
2316
                        "\" is not authorized for this action.");
2317
                out.print("</error>");
2318
                return;
2319
            }
2320

    
2321
            // Get all of the parameters in the correct formats
2322
            String[] ipAddress = (String[])params.get("ipaddress");
2323
            String[] principal = (String[])params.get("principal");
2324
            String[] docid = (String[])params.get("docid");
2325
            String[] event = (String[])params.get("event");
2326
            String[] startArray = (String[]) params.get("start");
2327
            String[] endArray = (String[]) params.get("end");
2328
            String start = null;
2329
            String end = null;
2330
            if (startArray != null) {
2331
                start = startArray[0];
2332
            }
2333
            if (endArray != null) {
2334
                end = endArray[0];
2335
            }
2336
            Timestamp startDate = null;
2337
            Timestamp endDate = null;
2338
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2339
            try {
2340
                if (start != null) {
2341
                    startDate = new Timestamp((format.parse(start)).getTime());
2342
                }
2343
                if (end != null) {
2344
                    endDate = new Timestamp((format.parse(end)).getTime());
2345
                }
2346
            } catch (ParseException e) {
2347
                System.out.println("Failed to created Timestamp from input.");
2348
            }
2349

    
2350
            // Request the report by passing the filter parameters
2351
            out.println(EventLog.getInstance().getReport(ipAddress, principal,
2352
                    docid, event, startDate, endDate));
2353
            out.close();
2354
        } catch (IOException e) {
2355
            logMetacat.error(
2356
                    "Could not open http response for writing: " + e.getMessage());
2357
        }
2358
    }
2359

    
2360
    /**
2361
     * Rebuild the index for one or more documents. If the docid parameter is
2362
     * provided, rebuild for just that one document or list of documents. If
2363
     * not, then rebuild the index for all documents in the xml_documents
2364
     * table.
2365
     *
2366
     * @param params the parameters from the web request
2367
     * @param request the http request object for getting request details
2368
     * @param response the http response object for writing output
2369
     * @param username the username of the authenticated user
2370
     */
2371
    private void handleBuildIndexAction(Hashtable params,
2372
            HttpServletRequest request, HttpServletResponse response,
2373
            String username, String[] groups)
2374
    {
2375
        // Get all of the parameters in the correct formats
2376
        String[] docid = (String[])params.get("docid");
2377

    
2378
        // Rebuild the indices for appropriate documents
2379
        try {
2380
            response.setContentType("text/xml");
2381
            PrintWriter out = response.getWriter();
2382

    
2383
            // Check that the user is authenticated as an administrator account
2384
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2385
                out.print("<error>");
2386
                out.print("The user \"" + username +
2387
                        "\" is not authorized for this action.");
2388
                out.print("</error>");
2389
                return;
2390
            }
2391

    
2392
            // Process the documents
2393
            out.println("<success>");
2394
            if (docid == null || docid.length == 0) {
2395
                // Process all of the documents
2396
                try {
2397
                    Vector documents = getDocumentList();
2398
                    Iterator it = documents.iterator();
2399
                    while (it.hasNext()) {
2400
                        String id = (String) it.next();
2401
                        buildDocumentIndex(id, out);
2402
                    }
2403
                } catch (SQLException se) {
2404
                    out.print("<error>");
2405
                    out.print(se.getMessage());
2406
                    out.println("</error>");
2407
                }
2408
            } else {
2409
                // Only process the requested documents
2410
                for (int i = 0; i < docid.length; i++) {
2411
                    buildDocumentIndex(docid[i], out);
2412
                }
2413
            }
2414
            out.println("</success>");
2415
            out.close();
2416
        } catch (IOException e) {
2417
            logMetacat.error(
2418
                    "Could not open http response for writing: "
2419
                    + e.getMessage());
2420
        }
2421
    }
2422

    
2423
    /**
2424
     * Build the index for one document by reading the document and
2425
     * calling its buildIndex() method.
2426
     *
2427
     * @param docid the document (with revision) to rebuild
2428
     * @param out the PrintWriter to which output is printed
2429
     */
2430
    private void buildDocumentIndex(String docid, PrintWriter out)
2431
    {
2432
        try {
2433
            DocumentImpl doc = new DocumentImpl(docid, false);
2434
            doc.buildIndex();
2435
            out.print("<docid>" + docid);
2436
            out.println("</docid>");
2437
        } catch (McdbException me) {
2438
            out.print("<error>");
2439
            out.print(me.getMessage());
2440
            out.println("</error>");
2441
        }
2442
    }
2443

    
2444
    /**
2445
     * Handle documents passed to metacat that are encoded using the
2446
     * "multipart/form-data" mime type. This is typically used for uploading
2447
     * data files which may be binary and large.
2448
     */
2449
    private void handleMultipartForm(HttpServletRequest request,
2450
            HttpServletResponse response)
2451
    {
2452
        PrintWriter out = null;
2453
        String action = null;
2454

    
2455
        // Parse the multipart form, and save the parameters in a Hashtable and
2456
        // save the FileParts in a hashtable
2457

    
2458
        Hashtable params = new Hashtable();
2459
        Hashtable fileList = new Hashtable();
2460
        int sizeLimit = (new Integer(MetaCatUtil.getOption("datafilesizelimit")))
2461
                .intValue();
2462
        logMetacat.info(
2463
                "The limit size of data file is: " + sizeLimit);
2464

    
2465
        try {
2466
            // MBJ: need to put filesize limit in Metacat config
2467
            // (metacat.properties)
2468
            MultipartParser mp = new MultipartParser(request,
2469
                    sizeLimit * 1024 * 1024);
2470
            Part part;
2471
            while ((part = mp.readNextPart()) != null) {
2472
                String name = part.getName();
2473

    
2474
                if (part.isParam()) {
2475
                    // it's a parameter part
2476
                    ParamPart paramPart = (ParamPart) part;
2477
                    String value = paramPart.getStringValue();
2478
                    params.put(name, value);
2479
                    if (name.equals("action")) {
2480
                        action = value;
2481
                    }
2482
                } else if (part.isFile()) {
2483
                    // it's a file part
2484
                    FilePart filePart = (FilePart) part;
2485
                    fileList.put(name, filePart);
2486

    
2487
                    // Stop once the first file part is found, otherwise going
2488
                    // onto the
2489
                    // next part prevents access to the file contents. So...for
2490
                    // upload
2491
                    // to work, the datafile must be the last part
2492
                    break;
2493
                }
2494
            }
2495
        } catch (IOException ioe) {
2496
            try {
2497
                out = response.getWriter();
2498
            } catch (IOException ioe2) {
2499
                logMetacat.fatal("Fatal Error: couldn't get response output stream.");
2500
            }
2501
            out.println("<?xml version=\"1.0\"?>");
2502
            out.println("<error>");
2503
            out.println("Error: problem reading multipart data.");
2504
            out.println("</error>");
2505
        }
2506

    
2507
        // Get the session information
2508
        String username = null;
2509
        String password = null;
2510
        String[] groupnames = null;
2511
        String sess_id = null;
2512

    
2513
        // be aware of session expiration on every request
2514
        HttpSession sess = request.getSession(true);
2515
        if (sess.isNew()) {
2516
            // session expired or has not been stored b/w user requests
2517
            username = "public";
2518
            sess.setAttribute("username", username);
2519
        } else {
2520
            username = (String) sess.getAttribute("username");
2521
            password = (String) sess.getAttribute("password");
2522
            groupnames = (String[]) sess.getAttribute("groupnames");
2523
            try {
2524
                sess_id = (String) sess.getId();
2525
            } catch (IllegalStateException ise) {
2526
                System.out
2527
                        .println("error in  handleMultipartForm: this shouldn't "
2528
                                + "happen: the session should be valid: "
2529
                                + ise.getMessage());
2530
            }
2531
        }
2532

    
2533
        // Get the out stream
2534
        try {
2535
            out = response.getWriter();
2536
        } catch (IOException ioe2) {
2537
            logMetacat.error("Fatal Error: couldn't get response "
2538
                    + "output stream.");
2539
        }
2540

    
2541
        if (action.equals("upload")) {
2542
            if (username != null && !username.equals("public")) {
2543
                handleUploadAction(request, out, params, fileList, username,
2544
                        groupnames);
2545
            } else {
2546

    
2547
                out.println("<?xml version=\"1.0\"?>");
2548
                out.println("<error>");
2549
                out.println("Permission denied for " + action);
2550
                out.println("</error>");
2551
            }
2552
        } else {
2553
            /*
2554
             * try { out = response.getWriter(); } catch (IOException ioe2) {
2555
             * System.err.println("Fatal Error: couldn't get response output
2556
             * stream.");
2557
             */
2558
            out.println("<?xml version=\"1.0\"?>");
2559
            out.println("<error>");
2560
            out.println(
2561
                    "Error: action not registered.  Please report this error.");
2562
            out.println("</error>");
2563
        }
2564
        out.close();
2565
    }
2566

    
2567
    /**
2568
     * Handle the upload action by saving the attached file to disk and
2569
     * registering it in the Metacat db
2570
     */
2571
    private void handleUploadAction(HttpServletRequest request,
2572
            PrintWriter out, Hashtable params, Hashtable fileList,
2573
            String username, String[] groupnames)
2574
    {
2575
        //PrintWriter out = null;
2576
        //Connection conn = null;
2577
        String action = null;
2578
        String docid = null;
2579

    
2580
        /*
2581
         * response.setContentType("text/xml"); try { out =
2582
         * response.getWriter(); } catch (IOException ioe2) {
2583
         * System.err.println("Fatal Error: couldn't get response output
2584
         * stream.");
2585
         */
2586

    
2587
        if (params.containsKey("docid")) {
2588
            docid = (String) params.get("docid");
2589
        }
2590

    
2591
        // Make sure we have a docid and datafile
2592
        if (docid != null && fileList.containsKey("datafile")) {
2593

    
2594
            // Get a reference to the file part of the form
2595
            FilePart filePart = (FilePart) fileList.get("datafile");
2596
            String fileName = filePart.getFileName();
2597
            logMetacat.warn("Uploading filename: " + fileName);
2598

    
2599
            // Check if the right file existed in the uploaded data
2600
            if (fileName != null) {
2601

    
2602
                try {
2603
                    //logMetacat.info("Upload datafile " + docid
2604
                    // +"...", 10);
2605
                    //If document get lock data file grant
2606
                    if (DocumentImpl.getDataFileLockGrant(docid)) {
2607
                        // register the file in the database (which generates
2608
                        // an exception
2609
                        //if the docid is not acceptable or other untoward
2610
                        // things happen
2611
                        DocumentImpl.registerDocument(fileName, "BIN", docid,
2612
                                username, groupnames);
2613

    
2614
                        // Save the data file to disk using "docid" as the name
2615
                        dataDirectory.mkdirs();
2616
                        File newFile = new File(dataDirectory, docid);
2617
                        long size = filePart.writeTo(newFile);
2618

    
2619
                        EventLog.getInstance().log(request.getRemoteAddr(),
2620
                                username, docid, "upload");
2621
                        // Force replication this data file
2622
                        // To data file, "insert" and update is same
2623
                        // The fourth parameter is null. Because it is
2624
                        // notification server
2625
                        // and this method is in MetaCatServerlet. It is
2626
                        // original command,
2627
                        // not get force replication info from another metacat
2628
                        ForceReplicationHandler frh = new ForceReplicationHandler(
2629
                                docid, "insert", false, null);
2630

    
2631
                        // set content type and other response header fields
2632
                        // first
2633
                        out.println("<?xml version=\"1.0\"?>");
2634
                        out.println("<success>");
2635
                        out.println("<docid>" + docid + "</docid>");
2636
                        out.println("<size>" + size + "</size>");
2637
                        out.println("</success>");
2638
                    }
2639

    
2640
                } catch (Exception e) {
2641
                    out.println("<?xml version=\"1.0\"?>");
2642
                    out.println("<error>");
2643
                    out.println(e.getMessage());
2644
                    out.println("</error>");
2645
                }
2646
            } else {
2647
                // the field did not contain a file
2648
                out.println("<?xml version=\"1.0\"?>");
2649
                out.println("<error>");
2650
                out.println("The uploaded data did not contain a valid file.");
2651
                out.println("</error>");
2652
            }
2653
        } else {
2654
            // Error bcse docid missing or file missing
2655
            out.println("<?xml version=\"1.0\"?>");
2656
            out.println("<error>");
2657
            out.println("The uploaded data did not contain a valid docid "
2658
                    + "or valid file.");
2659
            out.println("</error>");
2660
        }
2661
    }
2662

    
2663
    /*
2664
     * A method to handle set access action
2665
     */
2666
    private void handleSetAccessAction(PrintWriter out, Hashtable params,
2667
            String username)
2668
    {
2669
        String[] docList = null;
2670
        String[] principalList = null;
2671
        String[] permissionList = null;
2672
        String[] permTypeList = null;
2673
        String[] permOrderList = null;
2674
        String permission = null;
2675
        String permType = null;
2676
        String permOrder = null;
2677
        Vector errorList = new Vector();
2678
        String error = null;
2679
        Vector successList = new Vector();
2680
        String success = null;
2681

    
2682
        // Get parameters
2683
        if (params.containsKey("docid")) {
2684
            docList = (String[]) params.get("docid");
2685
        }
2686
        if (params.containsKey("principal")) {
2687
            principalList = (String[]) params.get("principal");
2688
        }
2689
        if (params.containsKey("permission")) {
2690
            permissionList = (String[]) params.get("permission");
2691

    
2692
        }
2693
        if (params.containsKey("permType")) {
2694
            permTypeList = (String[]) params.get("permType");
2695

    
2696
        }
2697
        if (params.containsKey("permOrder")) {
2698
            permOrderList = (String[]) params.get("permOrder");
2699

    
2700
        }
2701

    
2702
        // Make sure the parameter is not null
2703
        if (docList == null || principalList == null || permTypeList == null
2704
                || permissionList == null) {
2705
            error = "Please check your parameter list, it should look like: "
2706
                    + "?action=setaccess&docid=pipeline.1.1&principal=public"
2707
                    + "&permission=read&permType=allow&permOrder=allowFirst";
2708
            errorList.addElement(error);
2709
            outputResponse(successList, errorList, out);
2710
            return;
2711
        }
2712

    
2713
        // Only select first element for permission, type and order
2714
        permission = permissionList[0];
2715
        permType = permTypeList[0];
2716
        if (permOrderList != null) {
2717
            permOrder = permOrderList[0];
2718
        }
2719

    
2720
        // Get package doctype set
2721
        Vector packageSet = MetaCatUtil.getOptionList(MetaCatUtil
2722
                .getOption("packagedoctypeset"));
2723
        //debug
2724
        if (packageSet != null) {
2725
            for (int i = 0; i < packageSet.size(); i++) {
2726
                logMetacat.info("doctype in package set: "
2727
                        + (String) packageSet.elementAt(i));
2728
            }
2729
        }
2730

    
2731
        // handle every accessionNumber
2732
        for (int i = 0; i < docList.length; i++) {
2733
            String accessionNumber = docList[i];
2734
            String owner = null;
2735
            String publicId = null;
2736
            // Get document owner and public id
2737
            try {
2738
                owner = getFieldValueForDoc(accessionNumber, "user_owner");
2739
                publicId = getFieldValueForDoc(accessionNumber, "doctype");
2740
            } catch (Exception e) {
2741
                logMetacat.error("Error in handleSetAccessAction: "
2742
                        + e.getMessage());
2743
                error = "Error in set access control for document - "
2744
                        + accessionNumber + e.getMessage();
2745
                errorList.addElement(error);
2746
                continue;
2747
            }
2748
            //check if user is the owner. Only owner can do owner
2749
            if (username == null || owner == null || !username.equals(owner)) {
2750
                error = "User - " + username
2751
                        + " does not have permission to set "
2752
                        + "access control for docid - " + accessionNumber;
2753
                errorList.addElement(error);
2754
                continue;
2755
            }
2756

    
2757
            // If docid publicid is BIN data file or other beta4, 6 package
2758
            // document
2759
            // we could not do set access control. Because we don't want
2760
            // inconsistent
2761
            // to its access docuemnt
2762
            if (publicId != null && packageSet != null
2763
                    && packageSet.contains(publicId)) {
2764
                error = "Could not set access control to document "
2765
                        + accessionNumber
2766
                        + "because it is in a pakcage and it has a access file for it";
2767
                errorList.addElement(error);
2768
                continue;
2769
            }
2770

    
2771
            // for every principle
2772
            for (int j = 0; j < principalList.length; j++) {
2773
                String principal = principalList[j];
2774
                try {
2775
                    //insert permission
2776
                    AccessControlForSingleFile accessControl = new AccessControlForSingleFile(
2777
                            accessionNumber, principal, permission, permType,
2778
                            permOrder);
2779
                    accessControl.insertPermissions();
2780
                    success = "Set access control to document "
2781
                            + accessionNumber + " successfully";
2782
                    successList.addElement(success);
2783
                } catch (Exception ee) {
2784
                    logMetacat.error(
2785
                            "Erorr in handleSetAccessAction2: "
2786
                                    + ee.getMessage());
2787
                    error = "Faild to set access control for document "
2788
                            + accessionNumber + " because " + ee.getMessage();
2789
                    errorList.addElement(error);
2790
                    continue;
2791
                }
2792
            }
2793
        }
2794
        outputResponse(successList, errorList, out);
2795
    }
2796

    
2797
    /*
2798
     * A method try to determin a docid's public id, if couldn't find null will
2799
     * be returned.
2800
     */
2801
    private String getFieldValueForDoc(String accessionNumber, String fieldName)
2802
            throws Exception
2803
    {
2804
        if (accessionNumber == null || accessionNumber.equals("")
2805
                || fieldName == null || fieldName.equals("")) { throw new Exception(
2806
                "Docid or field name was not specified"); }
2807

    
2808
        PreparedStatement pstmt = null;
2809
        ResultSet rs = null;
2810
        String fieldValue = null;
2811
        String docId = null;
2812
        DBConnection conn = null;
2813
        int serialNumber = -1;
2814

    
2815
        // get rid of revision if access number has
2816
        docId = MetaCatUtil.getDocIdFromString(accessionNumber);
2817
        try {
2818
            //check out DBConnection
2819
            conn = DBConnectionPool
2820
                    .getDBConnection("MetaCatServlet.getPublicIdForDoc");
2821
            serialNumber = conn.getCheckOutSerialNumber();
2822
            pstmt = conn.prepareStatement("SELECT " + fieldName
2823
                    + " FROM xml_documents " + "WHERE docid = ? ");
2824

    
2825
            pstmt.setString(1, docId);
2826
            pstmt.execute();
2827
            rs = pstmt.getResultSet();
2828
            boolean hasRow = rs.next();
2829
            int perm = 0;
2830
            if (hasRow) {
2831
                fieldValue = rs.getString(1);
2832
            } else {
2833
                throw new Exception("Could not find document: "
2834
                        + accessionNumber);
2835
            }
2836
        } catch (Exception e) {
2837
            logMetacat.error(
2838
                    "Exception in MetacatServlet.getPublicIdForDoc: "
2839
                            + e.getMessage());
2840
            throw e;
2841
        } finally {
2842
            try {
2843
                rs.close();
2844
                pstmt.close();
2845

    
2846
            } finally {
2847
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2848
            }
2849
        }
2850
        return fieldValue;
2851
    }
2852

    
2853
    /*
2854
     * Get the list of documents from the database and return the list in an
2855
     * Vector of identifiers.
2856
     *
2857
     * @ returns the array of identifiers
2858
     */
2859
    private Vector getDocumentList() throws SQLException
2860
    {
2861
        Vector docList = new Vector();
2862
        PreparedStatement pstmt = null;
2863
        ResultSet rs = null;
2864
        DBConnection conn = null;
2865
        int serialNumber = -1;
2866

    
2867
        try {
2868
            //check out DBConnection
2869
            conn = DBConnectionPool
2870
                    .getDBConnection("MetaCatServlet.getDocumentList");
2871
            serialNumber = conn.getCheckOutSerialNumber();
2872
            pstmt = conn.prepareStatement("SELECT docid, rev"
2873
                    + " FROM xml_documents ");
2874
            pstmt.execute();
2875
            rs = pstmt.getResultSet();
2876
            while (rs.next()) {
2877
                String docid = rs.getString(1);
2878
                String rev = rs.getString(2);
2879
                docList.add(docid + "." + rev);
2880
            }
2881
        } catch (SQLException e) {
2882
            logMetacat.error(
2883
                    "Exception in MetacatServlet.getDocumentList: "
2884
                            + e.getMessage());
2885
            throw e;
2886
        } finally {
2887
            try {
2888
                rs.close();
2889
                pstmt.close();
2890

    
2891
            } catch (SQLException se) {
2892
                logMetacat.error(
2893
                    "Exception in MetacatServlet.getDocumentList: "
2894
                            + se.getMessage());
2895
                throw se;
2896
            } finally {
2897
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2898
            }
2899
        }
2900
        return docList;
2901
    }
2902

    
2903
    /*
2904
     * A method to output setAccess action result
2905
     */
2906
    private void outputResponse(Vector successList, Vector errorList,
2907
            PrintWriter out)
2908
    {
2909
        boolean error = false;
2910
        boolean success = false;
2911
        // Output prolog
2912
        out.println(PROLOG);
2913
        // output success message
2914
        if (successList != null) {
2915
            for (int i = 0; i < successList.size(); i++) {
2916
                out.println(SUCCESS);
2917
                out.println((String) successList.elementAt(i));
2918
                out.println(SUCCESSCLOSE);
2919
                success = true;
2920
            }
2921
        }
2922
        // output error message
2923
        if (errorList != null) {
2924
            for (int i = 0; i < errorList.size(); i++) {
2925
                out.println(ERROR);
2926
                out.println((String) errorList.elementAt(i));
2927
                out.println(ERRORCLOSE);
2928
                error = true;
2929
            }
2930
        }
2931

    
2932
        // if no error and no success info, send a error that nothing happened
2933
        if (!error && !success) {
2934
            out.println(ERROR);
2935
            out.println("Nothing happend for setaccess action");
2936
            out.println(ERRORCLOSE);
2937
        }
2938
    }
2939
    
2940
    /**
2941
     * Method to get session table which store the session info
2942
     * @return
2943
     */
2944
    public static Hashtable getSessionHash()
2945
    {
2946
        return sessionHash;
2947
    }
2948
    
2949
    /*
2950
     * If the given docid only have one seperter, we need 
2951
     * append rev for it. The rev come from xml_documents
2952
     */
2953
    private static String appendRev(String docid) throws Exception
2954
    {
2955
        String newAccNum = null;
2956
        String separator = MetaCatUtil.getOption("accNumSeparator");
2957
        int firstIndex = docid.indexOf(separator);
2958
        int lastIndex = docid.lastIndexOf(separator);
2959
        if (firstIndex == lastIndex)
2960
        {
2961
            
2962
           //only one seperater
2963
            int rev = DBUtil.getLatestRevisionInDocumentTable(docid);
2964
            if (rev == -1)
2965
            {
2966
                throw new Exception("Couldn't find the document "+docid);
2967
            }
2968
            else
2969
            {
2970
                newAccNum = docid+ separator+ rev;
2971
            }
2972
        }
2973
        else
2974
        {
2975
            // in other suituation we don't change the docid
2976
            newAccNum = docid;
2977
        }
2978
        logMetacat.warn("The docid will be read is "+newAccNum);
2979
        return newAccNum;
2980
    }
2981
}
(42-42/63)