Project

General

Profile

1 51 jones
/**
2 203 jones
 *  '$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 361 berkley
 *    Authors: Matt Jones, Dan Higgins, Jivka Bojilova, Chad Berkley
7 348 jones
 *    Release: @release@
8 154 jones
 *
9 203 jones
 *   '$Author$'
10
 *     '$Date$'
11
 * '$Revision$'
12 669 jones
 *
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 51 jones
 */
27
28
package edu.ucsb.nceas.metacat;
29
30 2098 jones
import java.io.BufferedInputStream;
31 733 bojilova
import java.io.File;
32 2098 jones
import java.io.FileInputStream;
33
import java.io.IOException;
34 46 jones
import java.io.PrintWriter;
35 50 jones
import java.io.StringReader;
36 2098 jones
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 2113 jones
import java.sql.Timestamp;
42
import java.text.ParseException;
43
import java.text.SimpleDateFormat;
44 46 jones
import java.util.Enumeration;
45
import java.util.Hashtable;
46 2312 jones
import java.util.Iterator;
47 82 jones
import java.util.PropertyResourceBundle;
48 1369 tao
import java.util.Vector;
49 2098 jones
import java.util.zip.ZipEntry;
50
import java.util.zip.ZipOutputStream;
51 46 jones
52
import javax.servlet.ServletConfig;
53
import javax.servlet.ServletContext;
54
import javax.servlet.ServletException;
55 2098 jones
import javax.servlet.ServletOutputStream;
56 46 jones
import javax.servlet.http.HttpServlet;
57
import javax.servlet.http.HttpServletRequest;
58
import javax.servlet.http.HttpServletResponse;
59 210 bojilova
import javax.servlet.http.HttpSession;
60 46 jones
61 2098 jones
import org.ecoinformatics.eml.EMLParser;
62 204 jones
63 2098 jones
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 2570 jones
import edu.ucsb.nceas.utilities.Options;
69
70 46 jones
/**
71
 * A metadata catalog server implemented as a Java Servlet
72 2169 sgarg
 *
73 205 jones
 * <p>
74 2098 jones
 * Valid parameters are: <br>
75
 * action=query -- query the values of all elements and attributes and return a
76
 * result set of nodes <br>
77
 * action=squery -- structured query (see pathquery.dtd) <br>
78
 * action= -- export a zip format for data packadge <br>
79
 * action=read -- read any metadata/data file from Metacat and from Internet
80
 * <br>
81
 * action=insert -- insert an XML document into the database store <br>
82
 * action=update -- update an XML document that is in the database store <br>
83
 * action=delete -- delete an XML document from the database store <br>
84
 * action=validate -- vallidate the xml contained in valtext <br>
85
 * doctype -- document type list returned by the query (publicID) <br>
86
 * qformat=xml -- display resultset from query in XML <br>
87
 * qformat=html -- display resultset from query in HTML <br>
88
 * qformat=zip -- zip resultset from query <br>
89
 * docid=34 -- display the document with the document ID number 34 <br>
90
 * doctext -- XML text of the document to load into the database <br>
91
 * acltext -- XML access text for a document to load into the database <br>
92
 * dtdtext -- XML DTD text for a new DTD to load into Metacat XML Catalog <br>
93
 * query -- actual query text (to go with 'action=query' or 'action=squery')
94
 * <br>
95
 * valtext -- XML text to be validated <br>
96
 * action=getaccesscontrol -- retrieve acl info for Metacat document <br>
97
 * action=getdoctypes -- retrieve all doctypes (publicID) <br>
98
 * action=getdtdschema -- retrieve a DTD or Schema file <br>
99
 * action=getdataguide -- retrieve a Data Guide <br>
100
 * action=getprincipals -- retrieve a list of principals in XML <br>
101
 * datadoc -- data document name (id) <br>
102 2113 jones
 * action=getlog -- get a report of events that have occurred in the system<br>
103
 * ipAddress --  filter on one or more IP addresses<br>
104
 * principal -- filter on one or more principals (LDAP DN syntax)<br>
105
 * docid -- filter on one or more document identifiers (with revision)<br>
106
 * event -- filter on event type (e.g., read, insert, update, delete)<br>
107
 * start -- filter out events before the start date-time<br>
108
 * end -- filter out events before the end date-time<br>
109 2098 jones
 * <p>
110
 * The particular combination of parameters that are valid for each particular
111
 * action value is quite specific. This documentation will be reorganized to
112
 * reflect this information.
113 46 jones
 */
114 2098 jones
public class MetaCatServlet extends HttpServlet
115
{
116 46 jones
117 2098 jones
    private ServletConfig config = null;
118 380 jones
119 2098 jones
    private ServletContext context = null;
120 82 jones
121 2098 jones
    private String resultStyleURL = null;
122 1951 jones
123 2098 jones
    private String xmlcatalogfile = null;
124 1360 tao
125 2098 jones
    private String saxparser = null;
126 184 jones
127 2098 jones
    private String datafilepath = null;
128 598 bojilova
129 2098 jones
    private File dataDirectory = null;
130 1217 tao
131 2098 jones
    private String servletpath = null;
132 46 jones
133 2098 jones
    private String htmlpath = null;
134 320 bojilova
135 2098 jones
    private PropertyResourceBundle options = null;
136 46 jones
137 2098 jones
    private MetaCatUtil util = null;
138 48 jones
139 2098 jones
    private DBConnectionPool connPool = null;
140 48 jones
141 2582 tao
    private static Hashtable sessionHash = new Hashtable();
142 48 jones
143 2098 jones
    private static final String PROLOG = "<?xml version=\"1.0\"?>";
144 48 jones
145 2098 jones
    private static final String SUCCESS = "<success>";
146 1360 tao
147 2098 jones
    private static final String SUCCESSCLOSE = "</success>";
148 1360 tao
149 2098 jones
    private static final String ERROR = "<error>";
150 1360 tao
151 2098 jones
    private static final String ERRORCLOSE = "</error>";
152 1360 tao
153 2098 jones
    public static final String SCHEMALOCATIONKEYWORD = ":schemaLocation";
154 1360 tao
155 2098 jones
    public static final String NONAMESPACELOCATION = ":noNamespaceSchemaLocation";
156 1360 tao
157 2098 jones
    public static final String EML2KEYWORD = ":eml";
158 1360 tao
159 2098 jones
    public static final String XMLFORMAT = "xml";
160 1360 tao
161 2098 jones
    private static final String CONFIG_DIR = "WEB-INF";
162 1360 tao
163 2098 jones
    private static final String CONFIG_NAME = "metacat.properties";
164 2594 sgarg
165
    public static String LOG_CONFIG_NAME;
166
167 2098 jones
    /**
168
     * Initialize the servlet by creating appropriate database connections
169
     */
170
    public void init(ServletConfig config) throws ServletException
171
    {
172
        try {
173
            super.init(config);
174
            this.config = config;
175
            this.context = config.getServletContext();
176 1360 tao
177 2098 jones
            // Initialize the properties file for our options
178
            String dirPath = context.getRealPath(CONFIG_DIR);
179
            File propertyFile = new File(dirPath, CONFIG_NAME);
180 2594 sgarg
181
    	    LOG_CONFIG_NAME = dirPath + "/log4j.properties";
182
183 2098 jones
            Options options = null;
184
            try {
185
                options = Options.initialize(propertyFile);
186
                MetaCatUtil.debugMessage("Options configured: "
187
                        + options.getOption("configured"), 20);
188
            } catch (IOException ioe) {
189
                MetaCatUtil.debugMessage("Error in loading options: "
190
                        + ioe.getMessage(), 20);
191
            }
192 1716 berkley
193 2098 jones
            util = new MetaCatUtil();
194 1360 tao
195 2098 jones
            //initial DBConnection pool
196
            connPool = DBConnectionPool.getInstance();
197 1360 tao
198 2098 jones
            // Get the configuration file information
199
            resultStyleURL = MetaCatUtil.getOption("resultStyleURL");
200
            xmlcatalogfile = MetaCatUtil.getOption("xmlcatalogfile");
201
            saxparser = MetaCatUtil.getOption("saxparser");
202
            datafilepath = MetaCatUtil.getOption("datafilepath");
203
            dataDirectory = new File(datafilepath);
204
            servletpath = MetaCatUtil.getOption("servletpath");
205
            htmlpath = MetaCatUtil.getOption("htmlpath");
206 1360 tao
207 2521 sgarg
            // Index the paths specified in the metacat.properties
208
            checkIndexPaths();
209
210 2098 jones
            System.out.println("Metacat (" + Version.getVersion()
211 2521 sgarg
                               + ") initialized.");
212
213 2098 jones
        } catch (ServletException ex) {
214
            throw ex;
215
        } catch (SQLException e) {
216
            MetaCatUtil.debugMessage("Error in MetacatServlet.init: "
217
                    + e.getMessage(), 20);
218 1221 tao
        }
219 2098 jones
    }
220 1360 tao
221 2570 jones
    /**
222
     * Close all db connections from the pool
223
     */
224
    public void destroy()
225
    {
226
        // Close all db connection
227
        System.out.println("Destroying MetacatServlet");
228
        DBConnectionPool.release();
229
    }
230 2521 sgarg
231 2570 jones
    /** Handle "GET" method requests from HTTP clients */
232
    public void doGet(HttpServletRequest request, HttpServletResponse response)
233
            throws ServletException, IOException
234
    {
235
236
        // Process the data and send back the response
237
        handleGetOrPost(request, response);
238
    }
239
240
    /** Handle "POST" method requests from HTTP clients */
241
    public void doPost(HttpServletRequest request, HttpServletResponse response)
242
            throws ServletException, IOException
243
    {
244
245
        // Process the data and send back the response
246
        handleGetOrPost(request, response);
247
    }
248
249 2098 jones
    /**
250 2521 sgarg
     * Index the paths specified in the metacat.properties
251
     */
252 2570 jones
    private void checkIndexPaths(){
253 2521 sgarg
        MetaCatUtil.pathsForIndexing
254
            = MetaCatUtil.getOptionList(MetaCatUtil.getOption("indexed_paths"));
255 2570 jones
256 2521 sgarg
        if (MetaCatUtil.pathsForIndexing != null) {
257 2570 jones
258 2521 sgarg
            MetaCatUtil.debugMessage("Indexing paths....", 20);
259 2570 jones
260 2521 sgarg
            DBConnection conn = null;
261
            int serialNumber = -1;
262
            PreparedStatement pstmt = null;
263
            PreparedStatement pstmt1 = null;
264
            ResultSet rs = null;
265 2570 jones
266 2521 sgarg
            for (int i = 0; i < MetaCatUtil.pathsForIndexing.size(); i++) {
267
                MetaCatUtil.formattedDebugMessage("Checking if '"
268
                           + (String) MetaCatUtil.pathsForIndexing.elementAt(i)
269
                           + "' is indexed.... ",30, false, true);
270 2570 jones
271 2521 sgarg
                try {
272
                    //check out DBConnection
273
                    conn = DBConnectionPool.
274
                        getDBConnection("MetaCatServlet.checkIndexPaths");
275
                    serialNumber = conn.getCheckOutSerialNumber();
276 2570 jones
277 2521 sgarg
                    pstmt = conn.prepareStatement(
278
                        "SELECT * FROM xml_path_index " + "WHERE path = ?");
279
                    pstmt.setString(1, (String) MetaCatUtil.pathsForIndexing
280
                                    .elementAt(i));
281 2570 jones
282 2521 sgarg
                    pstmt.execute();
283
                    rs = pstmt.getResultSet();
284 2570 jones
285 2521 sgarg
                    if (!rs.next()) {
286
                        MetaCatUtil.formattedDebugMessage("not indexed yet.", 30,
287
                                                       true, false);
288
                        rs.close();
289
                        pstmt.close();
290
                        conn.increaseUsageCount(1);
291 2570 jones
292 2521 sgarg
                        MetaCatUtil.debugMessage(
293
                              "Inserting following path in xml_path_index: "
294
                              + (String)MetaCatUtil.pathsForIndexing
295
                                                   .elementAt(i), 60);
296 2570 jones
297 2521 sgarg
                        pstmt = conn.prepareStatement("SELECT DISTINCT n.docid, "
298
                              + "n.nodedata, n.nodedatanumerical, n.parentnodeid"
299
                              + " FROM xml_nodes n, xml_index i WHERE"
300
                              + " i.path = ? and n.parentnodeid=i.nodeid and"
301
                              + " n.nodetype LIKE 'TEXT'");
302
                        pstmt.setString(1, (String) MetaCatUtil.
303
                                        pathsForIndexing.elementAt(i));
304
                        pstmt.execute();
305
                        rs = pstmt.getResultSet();
306 2570 jones
307 2521 sgarg
                        int count = 0;
308
                        MetaCatUtil.debugMessage(
309
                                       "Executed the select statement for: "
310
                                       + (String) MetaCatUtil.pathsForIndexing
311
                                         .elementAt(i), 60);
312 2570 jones
313 2521 sgarg
                        try {
314
                            while (rs.next()) {
315 2570 jones
316 2521 sgarg
                                String docid = rs.getString(1);
317
                                String nodedata = rs.getString(2);
318
                                float nodedatanumerical = rs.getFloat(3);
319
                                int parentnodeid = rs.getInt(4);
320 2570 jones
321 2521 sgarg
                                if (!nodedata.trim().equals("")) {
322
                                    pstmt1 = conn.prepareStatement(
323
                                        "INSERT INTO xml_path_index"
324
                                        + " (docid, path, nodedata, "
325
                                        + "nodedatanumerical, parentnodeid)"
326
                                        + " VALUES (?, ?, ?, ?, ?)");
327 2570 jones
328 2521 sgarg
                                    pstmt1.setString(1, docid);
329
                                    pstmt1.setString(2, (String) MetaCatUtil.
330
                                                pathsForIndexing.elementAt(i));
331
                                    pstmt1.setString(3, nodedata);
332
                                    pstmt1.setFloat(4, nodedatanumerical);
333
                                    pstmt1.setFloat(5, parentnodeid);
334 2570 jones
335 2521 sgarg
                                    pstmt1.execute();
336
                                    pstmt1.close();
337 2570 jones
338 2521 sgarg
                                    count++;
339 2570 jones
340 2521 sgarg
                                }
341
                            }
342
                        }
343
                        catch (Exception e) {
344
                            System.out.println("Exception:" + e.getMessage());
345
                            e.printStackTrace();
346
                        }
347 2570 jones
348 2521 sgarg
                        rs.close();
349
                        pstmt.close();
350
                        conn.increaseUsageCount(1);
351 2570 jones
352 2521 sgarg
                        MetaCatUtil.debugMessage("Indexed " + count
353
                                + " records from xml_nodes for '"
354
                                + (String) MetaCatUtil.pathsForIndexing.elementAt(i)
355
                                + "'", 20);
356 2570 jones
357 2521 sgarg
                    } else {
358
                        MetaCatUtil.formattedDebugMessage("already indexed.", 30,
359
                                                       true, false);
360
                    }
361 2570 jones
362 2521 sgarg
                    rs.close();
363
                    pstmt.close();
364
                    conn.increaseUsageCount(1);
365 2570 jones
366 2521 sgarg
                } catch (Exception e) {
367
                    MetaCatUtil.debugMessage("error in DocumentImpl.delete: "
368
                                             + e.getMessage(), 30);
369
                }finally {
370
                    //check in DBonnection
371
                    DBConnectionPool.returnDBConnection(conn, serialNumber);
372
                }
373 2570 jones
374
375 2521 sgarg
            }
376 2570 jones
377 2521 sgarg
            MetaCatUtil.debugMessage("Path Indexing Completed", 20);
378
        }
379
    }
380 1723 berkley
381 2089 tao
382 2098 jones
    /**
383
     * Control servlet response depending on the action parameter specified
384
     */
385
    private void handleGetOrPost(HttpServletRequest request,
386
            HttpServletResponse response) throws ServletException, IOException
387 2045 tao
    {
388 2089 tao
389 2098 jones
        if (util == null) {
390
            util = new MetaCatUtil();
391
        }
392
        /*
393
         * MetaCatUtil.debugMessage("Connection pool size: "
394
         * +connPool.getSizeOfDBConnectionPool(),10);
395
         * MetaCatUtil.debugMessage("Free DBConnection number: "
396
         */
397
        //If all DBConnection in the pool are free and DBConnection pool
398
        //size is greater than initial value, shrink the connection pool
399
        //size to initial value
400
        DBConnectionPool.shrinkDBConnectionPoolSize();
401 1360 tao
402 2098 jones
        //Debug message to print out the method which have a busy DBConnection
403
        connPool.printMethodNameHavingBusyDBConnection();
404 1360 tao
405 2098 jones
        String ctype = request.getContentType();
406
        if (ctype != null && ctype.startsWith("multipart/form-data")) {
407
            handleMultipartForm(request, response);
408
        } else {
409 1360 tao
410 2098 jones
            String name = null;
411
            String[] value = null;
412
            String[] docid = new String[3];
413
            Hashtable params = new Hashtable();
414
            Enumeration paramlist = request.getParameterNames();
415 1360 tao
416 2098 jones
            while (paramlist.hasMoreElements()) {
417 1360 tao
418 2098 jones
                name = (String) paramlist.nextElement();
419
                value = request.getParameterValues(name);
420 509 bojilova
421 2098 jones
                // Decode the docid and mouse click information
422
                if (name.endsWith(".y")) {
423
                    docid[0] = name.substring(0, name.length() - 2);
424
                    params.put("docid", docid);
425
                    name = "ypos";
426
                }
427
                if (name.endsWith(".x")) {
428
                    name = "xpos";
429
                }
430 509 bojilova
431 2098 jones
                params.put(name, value);
432
            }
433 509 bojilova
434 2098 jones
            //handle param is emptpy
435
            if (params.isEmpty() || params == null) { return; }
436 509 bojilova
437 2098 jones
            //if the user clicked on the input images, decode which image
438
            //was clicked then set the action.
439 2252 sgarg
            if(params.get("action") == null){
440
                PrintWriter out = response.getWriter();
441
                response.setContentType("text/xml");
442
                out.println("<?xml version=\"1.0\"?>");
443
                out.println("<error>");
444
                out.println("Action not specified");
445
                out.println("</error>");
446
                out.close();
447
                return;
448
            }
449
450 2098 jones
            String action = ((String[]) params.get("action"))[0];
451
            MetaCatUtil.debugMessage("Line 230: Action is: " + action, 1);
452 509 bojilova
453 2098 jones
            // This block handles session management for the servlet
454
            // by looking up the current session information for all actions
455
            // other than "login" and "logout"
456
            String username = null;
457
            String password = null;
458
            String[] groupnames = null;
459
            String sess_id = null;
460 1360 tao
461 2098 jones
            // handle login action
462
            if (action.equals("login")) {
463
                PrintWriter out = response.getWriter();
464
                handleLoginAction(out, params, request, response);
465
                out.close();
466 1360 tao
467 2098 jones
                // handle logout action
468
            } else if (action.equals("logout")) {
469
                PrintWriter out = response.getWriter();
470
                handleLogoutAction(out, params, request, response);
471
                out.close();
472 1360 tao
473 2098 jones
                // handle shrink DBConnection request
474
            } else if (action.equals("shrink")) {
475
                PrintWriter out = response.getWriter();
476
                boolean success = false;
477
                //If all DBConnection in the pool are free and DBConnection
478
                // pool
479
                //size is greater than initial value, shrink the connection
480
                // pool
481
                //size to initial value
482
                success = DBConnectionPool.shrinkConnectionPoolSize();
483
                if (success) {
484
                    //if successfully shrink the pool size to initial value
485
                    out.println("DBConnection Pool shrunk successfully.");
486
                }//if
487
                else {
488
                    out.println("DBConnection pool not shrunk successfully.");
489
                }
490
                //close out put
491
                out.close();
492 1360 tao
493 2098 jones
                // aware of session expiration on every request
494
            } else {
495
                HttpSession sess = request.getSession(true);
496
                if (sess.isNew() && !params.containsKey("sessionid")) {
497
                    // session expired or has not been stored b/w user requests
498
                    MetaCatUtil.debugMessage(
499
                            "in session is new or no sessionid", 40);
500
                    username = "public";
501
                    sess.setAttribute("username", username);
502
                } else {
503
                    MetaCatUtil.debugMessage("in session is not new or "
504
                            + " has sessionid parameter", 40);
505
                    try {
506
                        if (params.containsKey("sessionid")) {
507
                            sess_id = ((String[]) params.get("sessionid"))[0];
508
                            MetaCatUtil.debugMessage("in has sessionid "
509
                                    + sess_id, 40);
510
                            if (sessionHash.containsKey(sess_id)) {
511
                                MetaCatUtil.debugMessage("find the id "
512
                                        + sess_id + " in hash table", 40);
513
                                sess = (HttpSession) sessionHash.get(sess_id);
514
                            }
515
                        } else {
516
                            // we already store the session in login, so we
517
                            // don't need here
518
                            /*
519
                             * MetaCatUtil.debugMessage("in no sessionid
520
                             * parameter ", 40); sess_id =
521
                             * (String)sess.getId();
522
                             * MetaCatUtil.debugMessage("storing the session id "
523
                             * + sess_id + " which has username " +
524
                             * sess.getAttribute("username") + " into session
525
                             * hash in handleGetOrPost method", 35);
526
                             */
527
                        }
528
                    } catch (IllegalStateException ise) {
529
                        System.out.println(
530
                                "error in handleGetOrPost: this shouldn't "
531
                                + "happen: the session should be valid: "
532
                                + ise.getMessage());
533
                    }
534 1360 tao
535 2098 jones
                    username = (String) sess.getAttribute("username");
536
                    MetaCatUtil.debugMessage("The user name from session is: "
537
                            + username, 20);
538
                    password = (String) sess.getAttribute("password");
539
                    groupnames = (String[]) sess.getAttribute("groupnames");
540
                }
541 1360 tao
542 2098 jones
                //make user user username should be public
543
                if (username == null || (username.trim().equals(""))) {
544
                    username = "public";
545
                }
546
                MetaCatUtil.debugMessage("The user is : " + username, 5);
547
            }
548
            // Now that we know the session is valid, we can delegate the
549
            // request
550
            // to a particular action handler
551
            if (action.equals("query")) {
552
                PrintWriter out = response.getWriter();
553
                handleQuery(out, params, response, username, groupnames,
554
                        sess_id);
555
                out.close();
556
            } else if (action.equals("squery")) {
557
                PrintWriter out = response.getWriter();
558
                if (params.containsKey("query")) {
559
                    handleSQuery(out, params, response, username, groupnames,
560
                            sess_id);
561
                    out.close();
562
                } else {
563
                    out.println(
564
                            "Illegal action squery without \"query\" parameter");
565
                    out.close();
566
                }
567
            } else if (action.equals("export")) {
568 1298 tao
569 2169 sgarg
                handleExportAction(params, response, username,
570 2102 jones
                        groupnames, password);
571 2098 jones
            } else if (action.equals("read")) {
572 2102 jones
                handleReadAction(params, request, response, username, password,
573 2098 jones
                        groupnames);
574
            } else if (action.equals("readinlinedata")) {
575 2102 jones
                handleReadInlineDataAction(params, request, response, username,
576 2098 jones
                        password, groupnames);
577
            } else if (action.equals("insert") || action.equals("update")) {
578
                PrintWriter out = response.getWriter();
579
                if ((username != null) && !username.equals("public")) {
580 2102 jones
                    handleInsertOrUpdateAction(request, response,
581
                            out, params, username, groupnames);
582 2098 jones
                } else {
583 2252 sgarg
                    response.setContentType("text/xml");
584
                    out.println("<?xml version=\"1.0\"?>");
585
                    out.println("<error>");
586 2098 jones
                    out.println("Permission denied for user " + username + " "
587
                            + action);
588 2252 sgarg
                    out.println("</error>");
589 2098 jones
                }
590
                out.close();
591
            } else if (action.equals("delete")) {
592
                PrintWriter out = response.getWriter();
593
                if ((username != null) && !username.equals("public")) {
594 2102 jones
                    handleDeleteAction(out, params, request, response, username,
595 2098 jones
                            groupnames);
596
                } else {
597 2252 sgarg
                    response.setContentType("text/xml");
598
                    out.println("<?xml version=\"1.0\"?>");
599
                    out.println("<error>");
600 2098 jones
                    out.println("Permission denied for " + action);
601 2252 sgarg
                    out.println("</error>");
602 2098 jones
                }
603
                out.close();
604
            } else if (action.equals("validate")) {
605
                PrintWriter out = response.getWriter();
606
                handleValidateAction(out, params);
607
                out.close();
608
            } else if (action.equals("setaccess")) {
609
                PrintWriter out = response.getWriter();
610
                handleSetAccessAction(out, params, username);
611
                out.close();
612
            } else if (action.equals("getaccesscontrol")) {
613
                PrintWriter out = response.getWriter();
614
                handleGetAccessControlAction(out, params, response, username,
615
                        groupnames);
616
                out.close();
617
            } else if (action.equals("getprincipals")) {
618
                PrintWriter out = response.getWriter();
619
                handleGetPrincipalsAction(out, username, password);
620
                out.close();
621
            } else if (action.equals("getdoctypes")) {
622
                PrintWriter out = response.getWriter();
623
                handleGetDoctypesAction(out, params, response);
624
                out.close();
625
            } else if (action.equals("getdtdschema")) {
626
                PrintWriter out = response.getWriter();
627
                handleGetDTDSchemaAction(out, params, response);
628
                out.close();
629
            } else if (action.equals("getlastdocid")) {
630
                PrintWriter out = response.getWriter();
631
                handleGetMaxDocidAction(out, params, response);
632
                out.close();
633
            } else if (action.equals("getrevisionanddoctype")) {
634
                PrintWriter out = response.getWriter();
635
                handleGetRevisionAndDocTypeAction(out, params);
636
                out.close();
637
            } else if (action.equals("getversion")) {
638
                response.setContentType("text/xml");
639
                PrintWriter out = response.getWriter();
640
                out.println(Version.getVersionAsXml());
641
                out.close();
642 2113 jones
            } else if (action.equals("getlog")) {
643 2558 sgarg
                handleGetLogAction(params, request, response, username, groupnames);
644 2312 jones
            } else if (action.equals("buildindex")) {
645 2558 sgarg
                handleBuildIndexAction(params, request, response, username, groupnames);
646 2098 jones
            } else if (action.equals("login") || action.equals("logout")) {
647 2312 jones
                /*
648 2098 jones
            } else if (action.equals("protocoltest")) {
649
                String testURL = "metacat://dev.nceas.ucsb.edu/NCEAS.897766.9";
650
                try {
651
                    testURL = ((String[]) params.get("url"))[0];
652
                } catch (Throwable t) {
653
                }
654
                String phandler = System
655
                        .getProperty("java.protocol.handler.pkgs");
656
                response.setContentType("text/html");
657
                PrintWriter out = response.getWriter();
658
                out.println("<body bgcolor=\"white\">");
659
                out.println("<p>Handler property: <code>" + phandler
660
                        + "</code></p>");
661
                out.println("<p>Starting test for:<br>");
662
                out.println("    " + testURL + "</p>");
663
                try {
664
                    URL u = new URL(testURL);
665
                    out.println("<pre>");
666
                    out.println("Protocol: " + u.getProtocol());
667
                    out.println("    Host: " + u.getHost());
668
                    out.println("    Port: " + u.getPort());
669
                    out.println("    Path: " + u.getPath());
670
                    out.println("     Ref: " + u.getRef());
671
                    String pquery = u.getQuery();
672
                    out.println("   Query: " + pquery);
673
                    out.println("  Params: ");
674
                    if (pquery != null) {
675 2099 jones
                        Hashtable qparams = MetaCatUtil.parseQuery(u.getQuery());
676 2098 jones
                        for (Enumeration en = qparams.keys(); en
677
                                .hasMoreElements();) {
678
                            String pname = (String) en.nextElement();
679
                            String pvalue = (String) qparams.get(pname);
680
                            out.println("    " + pname + ": " + pvalue);
681
                        }
682
                    }
683
                    out.println("</pre>");
684
                    out.println("</body>");
685
                    out.close();
686
                } catch (MalformedURLException mue) {
687
                    System.out.println(
688
                            "bad url from MetacatServlet.handleGetOrPost");
689
                    out.println(mue.getMessage());
690
                    mue.printStackTrace(out);
691
                    out.close();
692
                }
693 2312 jones
                */
694 2098 jones
            } else {
695
                PrintWriter out = response.getWriter();
696
                out.println("<?xml version=\"1.0\"?>");
697
                out.println("<error>");
698
                out.println(
699
                     "Error: action not registered.  Please report this error.");
700
                out.println("</error>");
701
                out.close();
702
            }
703 1360 tao
704 2098 jones
            //util.closeConnections();
705
            // Close the stream to the client
706
            //out.close();
707
        }
708
    }
709 425 bojilova
710 2098 jones
    // LOGIN & LOGOUT SECTION
711
    /**
712
     * Handle the login request. Create a new session object. Do user
713
     * authentication through the session.
714
     */
715
    private void handleLoginAction(PrintWriter out, Hashtable params,
716
            HttpServletRequest request, HttpServletResponse response)
717 943 tao
    {
718 1360 tao
719 2098 jones
        AuthSession sess = null;
720 2252 sgarg
721
        if(params.get("username") == null){
722
            response.setContentType("text/xml");
723
            out.println("<?xml version=\"1.0\"?>");
724
            out.println("<error>");
725
            out.println("Username not specified");
726
            out.println("</error>");
727
            return;
728
        }
729
730
        if(params.get("password") == null){
731
            response.setContentType("text/xml");
732
            out.println("<?xml version=\"1.0\"?>");
733
            out.println("<error>");
734
            out.println("Password not specified");
735
            out.println("</error>");
736
            return;
737
        }
738
739 2098 jones
        String un = ((String[]) params.get("username"))[0];
740
        MetaCatUtil.debugMessage("user " + un + " try to login", 20);
741
        String pw = ((String[]) params.get("password"))[0];
742 943 tao
743 2252 sgarg
        String qformat = "xml";
744
        if(params.get("qformat") != null){
745
            qformat = ((String[]) params.get("qformat"))[0];
746
        }
747
748 2098 jones
        try {
749
            sess = new AuthSession();
750
        } catch (Exception e) {
751
            System.out.println("error in MetacatServlet.handleLoginAction: "
752
                    + e.getMessage());
753
            out.println(e.getMessage());
754
            return;
755
        }
756
        boolean isValid = sess.authenticate(request, un, pw);
757 1360 tao
758 2098 jones
        //if it is authernticate is true, store the session
759
        if (isValid) {
760
            HttpSession session = sess.getSessions();
761
            String id = session.getId();
762
            MetaCatUtil.debugMessage("Store session id " + id
763
                    + "which has username" + session.getAttribute("username")
764
                    + " into hash in login method", 35);
765
            sessionHash.put(id, session);
766
        }
767 1360 tao
768 2098 jones
        // format and transform the output
769
        if (qformat.equals("xml")) {
770
            response.setContentType("text/xml");
771
            out.println(sess.getMessage());
772
        } else {
773
            try {
774
                DBTransform trans = new DBTransform();
775
                response.setContentType("text/html");
776
                trans.transformXMLDocument(sess.getMessage(),
777
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
778
                        out, null);
779
            } catch (Exception e) {
780 1360 tao
781 2098 jones
                MetaCatUtil.debugMessage(
782
                        "Error in MetaCatServlet.handleLoginAction: "
783
                                + e.getMessage(), 30);
784
            }
785
        }
786
    }
787 1716 berkley
788 2098 jones
    /**
789
     * Handle the logout request. Close the connection.
790
     */
791
    private void handleLogoutAction(PrintWriter out, Hashtable params,
792
            HttpServletRequest request, HttpServletResponse response)
793 1483 tao
    {
794 1716 berkley
795 2252 sgarg
        String qformat = "xml";
796
        if(params.get("qformat") != null){
797
            qformat = ((String[]) params.get("qformat"))[0];
798
        }
799 1716 berkley
800 2098 jones
        // close the connection
801
        HttpSession sess = request.getSession(false);
802
        MetaCatUtil.debugMessage("After get session in logout request", 40);
803
        if (sess != null) {
804
            MetaCatUtil.debugMessage("The session id " + sess.getId()
805
                    + " will be invalidate in logout action", 30);
806
            MetaCatUtil.debugMessage("The session contains user "
807
                    + sess.getAttribute("username")
808
                    + " will be invalidate in logout action", 30);
809
            sess.invalidate();
810
        }
811 1716 berkley
812 2098 jones
        // produce output
813
        StringBuffer output = new StringBuffer();
814
        output.append("<?xml version=\"1.0\"?>");
815
        output.append("<logout>");
816
        output.append("User logged out");
817
        output.append("</logout>");
818 1483 tao
819 2098 jones
        //format and transform the output
820
        if (qformat.equals("xml")) {
821
            response.setContentType("text/xml");
822
            out.println(output.toString());
823
        } else {
824
            try {
825
                DBTransform trans = new DBTransform();
826
                response.setContentType("text/html");
827
                trans.transformXMLDocument(output.toString(),
828
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
829
                        out, null);
830
            } catch (Exception e) {
831
                MetaCatUtil.debugMessage(
832
                        "Error in MetaCatServlet.handleLogoutAction"
833
                                + e.getMessage(), 30);
834
            }
835 1716 berkley
        }
836 2098 jones
    }
837 1483 tao
838 2098 jones
    // END OF LOGIN & LOGOUT SECTION
839 1716 berkley
840 2098 jones
    // SQUERY & QUERY SECTION
841
    /**
842
     * Retreive the squery xml, execute it and display it
843 2169 sgarg
     *
844 2098 jones
     * @param out the output stream to the client
845
     * @param params the Hashtable of parameters that should be included in the
846
     *            squery.
847
     * @param response the response object linked to the client
848
     * @param conn the database connection
849
     */
850 2570 jones
    private void handleSQuery(PrintWriter out, Hashtable params,
851 2098 jones
            HttpServletResponse response, String user, String[] groups,
852
            String sessionid)
853
    {
854
        double startTime = System.currentTimeMillis() / 1000;
855
        DBQuery queryobj = new DBQuery(saxparser);
856
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
857
        double outPutTime = System.currentTimeMillis() / 1000;
858
        MetaCatUtil.debugMessage("total search time: "
859
                + (outPutTime - startTime), 30);
860 1483 tao
861 2098 jones
    }
862 1716 berkley
863 2098 jones
    /**
864
     * Create the xml query, execute it and display the results.
865 2169 sgarg
     *
866 2098 jones
     * @param out the output stream to the client
867
     * @param params the Hashtable of parameters that should be included in the
868
     *            squery.
869
     * @param response the response object linked to the client
870
     */
871 2570 jones
    private void handleQuery(PrintWriter out, Hashtable params,
872 2098 jones
            HttpServletResponse response, String user, String[] groups,
873
            String sessionid)
874 1490 tao
    {
875 2098 jones
        //create the query and run it
876
        String xmlquery = DBQuery.createSQuery(params);
877
        String[] queryArray = new String[1];
878
        queryArray[0] = xmlquery;
879
        params.put("query", queryArray);
880
        double startTime = System.currentTimeMillis() / 1000;
881
        DBQuery queryobj = new DBQuery(saxparser);
882
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
883
        double outPutTime = System.currentTimeMillis() / 1000;
884
        MetaCatUtil.debugMessage("total search time: "
885
                + (outPutTime - startTime), 30);
886 1716 berkley
887 2098 jones
        //handleSQuery(out, params, response,user, groups, sessionid);
888 1490 tao
    }
889 1716 berkley
890 2098 jones
    // END OF SQUERY & QUERY SECTION
891 1716 berkley
892 2098 jones
    //Exoport section
893
    /**
894
     * Handle the "export" request of data package from Metacat in zip format
895 2169 sgarg
     *
896 2098 jones
     * @param params the Hashtable of HTTP request parameters
897
     * @param response the HTTP response object linked to the client
898
     * @param user the username sent the request
899
     * @param groups the user's groupnames
900
     */
901 2169 sgarg
    private void handleExportAction(Hashtable params,
902
            HttpServletResponse response,
903 2102 jones
            String user, String[] groups, String passWord)
904 2098 jones
    {
905
        // Output stream
906
        ServletOutputStream out = null;
907
        // Zip output stream
908
        ZipOutputStream zOut = null;
909
        DBQuery queryObj = null;
910 1716 berkley
911 2098 jones
        String[] docs = new String[10];
912
        String docId = "";
913 1360 tao
914 731 bojilova
        try {
915 2098 jones
            // read the params
916
            if (params.containsKey("docid")) {
917
                docs = (String[]) params.get("docid");
918 731 bojilova
            }
919 2098 jones
            // Create a DBuery to handle export
920
            queryObj = new DBQuery(saxparser);
921
            // Get the docid
922
            docId = docs[0];
923
            // Make sure the client specify docid
924
            if (docId == null || docId.equals("")) {
925
                response.setContentType("text/xml"); //MIME type
926
                // Get a printwriter
927
                PrintWriter pw = response.getWriter();
928
                // Send back message
929
                pw.println("<?xml version=\"1.0\"?>");
930
                pw.println("<error>");
931
                pw.println("You didn't specify requested docid");
932
                pw.println("</error>");
933
                // Close printwriter
934
                pw.close();
935
                return;
936
            }
937
            // Get output stream
938
            out = response.getOutputStream();
939
            response.setContentType("application/zip"); //MIME type
940 2556 sgarg
            response.setHeader("Content-Disposition",
941
            		"attachment; filename="
942
            		+ docId + ".zip"); // Set the name of the zip file
943
944 2098 jones
            zOut = new ZipOutputStream(out);
945
            zOut = queryObj
946
                    .getZippedPackage(docId, out, user, groups, passWord);
947
            zOut.finish(); //terminate the zip file
948
            zOut.close(); //close the zip stream
949 731 bojilova
950 2098 jones
        } catch (Exception e) {
951
            try {
952
                response.setContentType("text/xml"); //MIME type
953
                // Send error message back
954
                if (out != null) {
955
                    PrintWriter pw = new PrintWriter(out);
956
                    pw.println("<?xml version=\"1.0\"?>");
957
                    pw.println("<error>");
958
                    pw.println(e.getMessage());
959
                    pw.println("</error>");
960
                    // Close printwriter
961
                    pw.close();
962
                    // Close output stream
963
                    out.close();
964
                }
965
                // Close zip output stream
966
                if (zOut != null) {
967
                    zOut.close();
968
                }
969
            } catch (IOException ioe) {
970
                MetaCatUtil.debugMessage("Problem with the servlet output "
971
                        + "in MetacatServlet.handleExportAction: "
972
                        + ioe.getMessage(), 30);
973 731 bojilova
            }
974
975 2098 jones
            MetaCatUtil.debugMessage(
976
                    "Error in MetacatServlet.handleExportAction: "
977
                            + e.getMessage(), 30);
978
            e.printStackTrace(System.out);
979
980 731 bojilova
        }
981 1360 tao
982 2098 jones
    }
983 1360 tao
984 2098 jones
    /**
985
     * In eml2 document, the xml can have inline data and data was stripped off
986
     * and store in file system. This action can be used to read inline data
987
     * only
988 2169 sgarg
     *
989 2098 jones
     * @param params the Hashtable of HTTP request parameters
990
     * @param response the HTTP response object linked to the client
991
     * @param user the username sent the request
992
     * @param groups the user's groupnames
993
     */
994
    private void handleReadInlineDataAction(Hashtable params,
995 2169 sgarg
            HttpServletRequest request, HttpServletResponse response,
996 2102 jones
            String user, String passWord, String[] groups)
997 2098 jones
    {
998
        String[] docs = new String[10];
999
        String inlineDataId = null;
1000
        String docId = "";
1001
        ServletOutputStream out = null;
1002 1360 tao
1003 2098 jones
        try {
1004
            // read the params
1005
            if (params.containsKey("inlinedataid")) {
1006
                docs = (String[]) params.get("inlinedataid");
1007
            }
1008
            // Get the docid
1009
            inlineDataId = docs[0];
1010
            // Make sure the client specify docid
1011 2169 sgarg
            if (inlineDataId == null || inlineDataId.equals("")) {
1012 2098 jones
                throw new Exception("You didn't specify requested inlinedataid"); }
1013 1360 tao
1014 2098 jones
            // check for permission
1015
            docId = MetaCatUtil
1016
                    .getDocIdWithoutRevFromInlineDataID(inlineDataId);
1017
            PermissionController controller = new PermissionController(docId);
1018
            // check top level read permission
1019
            if (!controller.hasPermission(user, groups,
1020 2245 sgarg
                    AccessControlInterface.READSTRING))
1021
            {
1022 2098 jones
                throw new Exception("User " + user
1023
                        + " doesn't have permission " + " to read document "
1024
                        + docId);
1025
            }
1026 2245 sgarg
            else
1027
            {
1028
              //check data access level
1029
              try
1030
              {
1031
                Hashtable unReadableInlineDataList =
1032 2292 sgarg
                    PermissionController.getUnReadableInlineDataIdList(docId,
1033
                    user, groups, false);
1034
                if (unReadableInlineDataList.containsValue(
1035
                          MetaCatUtil.getInlineDataIdWithoutRev(inlineDataId)))
1036 2245 sgarg
                {
1037
                  throw new Exception("User " + user
1038
                       + " doesn't have permission " + " to read inlinedata "
1039
                       + inlineDataId);
1040 2098 jones
1041 2245 sgarg
                }//if
1042
              }//try
1043
              catch (Exception e)
1044
              {
1045
                throw e;
1046
              }//catch
1047
            }//else
1048
1049 2098 jones
            // Get output stream
1050
            out = response.getOutputStream();
1051
            // read the inline data from the file
1052
            String inlinePath = MetaCatUtil.getOption("inlinedatafilepath");
1053
            File lineData = new File(inlinePath, inlineDataId);
1054
            FileInputStream input = new FileInputStream(lineData);
1055
            byte[] buffer = new byte[4 * 1024];
1056
            int bytes = input.read(buffer);
1057
            while (bytes != -1) {
1058
                out.write(buffer, 0, bytes);
1059
                bytes = input.read(buffer);
1060
            }
1061 1292 tao
            out.close();
1062 1360 tao
1063 2169 sgarg
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1064 2102 jones
                    inlineDataId, "readinlinedata");
1065 2098 jones
        } catch (Exception e) {
1066
            try {
1067
                PrintWriter pw = null;
1068
                // Send error message back
1069
                if (out != null) {
1070
                    pw = new PrintWriter(out);
1071
                } else {
1072
                    pw = response.getWriter();
1073
                }
1074
                pw.println("<?xml version=\"1.0\"?>");
1075
                pw.println("<error>");
1076
                pw.println(e.getMessage());
1077
                pw.println("</error>");
1078
                // Close printwriter
1079
                pw.close();
1080
                // Close output stream if out is not null
1081
                if (out != null) {
1082
                    out.close();
1083
                }
1084
            } catch (IOException ioe) {
1085
                MetaCatUtil.debugMessage("Problem with the servlet output "
1086
                        + "in MetacatServlet.handleExportAction: "
1087
                        + ioe.getMessage(), 30);
1088
            }
1089
            MetaCatUtil.debugMessage(
1090
                    "Error in MetacatServlet.handleReadInlineDataAction: "
1091
                            + e.getMessage(), 30);
1092 1292 tao
        }
1093 2098 jones
    }
1094
1095
    /*
1096
     * Get the nodeid from xml_nodes for the inlinedataid
1097
     */
1098
    private long getInlineDataNodeId(String inLineDataId, String docId)
1099
            throws SQLException
1100 1292 tao
    {
1101 2098 jones
        long nodeId = 0;
1102
        String INLINE = "inline";
1103
        boolean hasRow;
1104
        PreparedStatement pStmt = null;
1105
        DBConnection conn = null;
1106
        int serialNumber = -1;
1107
        String sql = "SELECT nodeid FROM xml_nodes WHERE docid=? AND nodedata=? "
1108
                + "AND nodetype='TEXT' AND parentnodeid IN "
1109
                + "(SELECT nodeid FROM xml_nodes WHERE docid=? AND "
1110
                + "nodetype='ELEMENT' AND nodename='" + INLINE + "')";
1111 1360 tao
1112 2098 jones
        try {
1113
            //check out DBConnection
1114
            conn = DBConnectionPool
1115
                    .getDBConnection("AccessControlList.isAllowFirst");
1116
            serialNumber = conn.getCheckOutSerialNumber();
1117 1360 tao
1118 2098 jones
            pStmt = conn.prepareStatement(sql);
1119
            //bind value
1120
            pStmt.setString(1, docId);//docid
1121
            pStmt.setString(2, inLineDataId);//inlinedataid
1122
            pStmt.setString(3, docId);
1123
            // excute query
1124
            pStmt.execute();
1125
            ResultSet rs = pStmt.getResultSet();
1126
            hasRow = rs.next();
1127
            // get result
1128
            if (hasRow) {
1129
                nodeId = rs.getLong(1);
1130
            }//if
1131
1132
        } catch (SQLException e) {
1133
            throw e;
1134
        } finally {
1135
            try {
1136
                pStmt.close();
1137
            } finally {
1138
                DBConnectionPool.returnDBConnection(conn, serialNumber);
1139
            }
1140 1292 tao
        }
1141 2098 jones
        MetaCatUtil.debugMessage("The nodeid for inlinedataid " + inLineDataId
1142
                + " is: " + nodeId, 35);
1143
        return nodeId;
1144
    }
1145 1360 tao
1146 2098 jones
    /**
1147
     * Handle the "read" request of metadata/data files from Metacat or any
1148
     * files from Internet; transformed metadata XML document into HTML
1149
     * presentation if requested; zip files when more than one were requested.
1150 2169 sgarg
     *
1151 2098 jones
     * @param params the Hashtable of HTTP request parameters
1152 2102 jones
     * @param request the HTTP request object linked to the client
1153 2098 jones
     * @param response the HTTP response object linked to the client
1154
     * @param user the username sent the request
1155
     * @param groups the user's groupnames
1156
     */
1157 2102 jones
    private void handleReadAction(Hashtable params, HttpServletRequest request,
1158 2098 jones
            HttpServletResponse response, String user, String passWord,
1159
            String[] groups)
1160
    {
1161
        ServletOutputStream out = null;
1162
        ZipOutputStream zout = null;
1163
        PrintWriter pw = null;
1164
        boolean zip = false;
1165
        boolean withInlineData = true;
1166 1360 tao
1167 2098 jones
        try {
1168
            String[] docs = new String[0];
1169
            String docid = "";
1170
            String qformat = "";
1171
            String abstrpath = null;
1172 731 bojilova
1173 2098 jones
            // read the params
1174
            if (params.containsKey("docid")) {
1175
                docs = (String[]) params.get("docid");
1176
            }
1177
            if (params.containsKey("qformat")) {
1178
                qformat = ((String[]) params.get("qformat"))[0];
1179
            }
1180
            // the param for only metadata (eml)
1181 2245 sgarg
            // we don't support read a eml document without inline data now.
1182
            /*if (params.containsKey("inlinedata")) {
1183 1360 tao
1184 2098 jones
                String inlineData = ((String[]) params.get("inlinedata"))[0];
1185
                if (inlineData.equalsIgnoreCase("false")) {
1186
                    withInlineData = false;
1187
                }
1188 2245 sgarg
            }*/
1189 2098 jones
            if ((docs.length > 1) || qformat.equals("zip")) {
1190
                zip = true;
1191
                out = response.getOutputStream();
1192
                response.setContentType("application/zip"); //MIME type
1193
                zout = new ZipOutputStream(out);
1194
            }
1195
            // go through the list of docs to read
1196
            for (int i = 0; i < docs.length; i++) {
1197
                try {
1198 1360 tao
1199 2098 jones
                    URL murl = new URL(docs[i]);
1200 2099 jones
                    Hashtable murlQueryStr = MetaCatUtil.parseQuery(
1201
                            murl.getQuery());
1202 2098 jones
                    // case docid="http://.../?docid=aaa"
1203
                    // or docid="metacat://.../?docid=bbb"
1204
                    if (murlQueryStr.containsKey("docid")) {
1205
                        // get only docid, eliminate the rest
1206
                        docid = (String) murlQueryStr.get("docid");
1207
                        if (zip) {
1208 2102 jones
                            addDocToZip(request, docid, zout, user, groups);
1209 2098 jones
                        } else {
1210 2102 jones
                            readFromMetacat(request, response, docid, qformat,
1211 2098 jones
                                    abstrpath, user, groups, zip, zout,
1212
                                    withInlineData, params);
1213
                        }
1214 1360 tao
1215 2098 jones
                        // case docid="http://.../filename"
1216
                    } else {
1217
                        docid = docs[i];
1218
                        if (zip) {
1219 2102 jones
                            addDocToZip(request, docid, zout, user, groups);
1220 2098 jones
                        } else {
1221
                            readFromURLConnection(response, docid);
1222
                        }
1223
                    }
1224 2169 sgarg
1225 2098 jones
                } catch (MalformedURLException mue) {
1226
                    docid = docs[i];
1227
                    if (zip) {
1228 2102 jones
                        addDocToZip(request, docid, zout, user, groups);
1229 2098 jones
                    } else {
1230 2169 sgarg
                        readFromMetacat(request, response, docid, qformat,
1231
                                abstrpath, user, groups, zip, zout,
1232 2102 jones
                                withInlineData, params);
1233 2098 jones
                    }
1234
                }
1235 2099 jones
            }
1236 1360 tao
1237 2098 jones
            if (zip) {
1238
                zout.finish(); //terminate the zip file
1239
                zout.close(); //close the zip stream
1240
            }
1241 1360 tao
1242 2098 jones
        } catch (McdbDocNotFoundException notFoundE) {
1243
            // To handle doc not found exception
1244
            // the docid which didn't be found
1245
            String notFoundDocId = notFoundE.getUnfoundDocId();
1246
            String notFoundRevision = notFoundE.getUnfoundRevision();
1247
            MetaCatUtil.debugMessage("Missed id: " + notFoundDocId, 30);
1248
            MetaCatUtil.debugMessage("Missed rev: " + notFoundRevision, 30);
1249
            try {
1250
                // read docid from remote server
1251
                readFromRemoteMetaCat(response, notFoundDocId,
1252
                        notFoundRevision, user, passWord, out, zip, zout);
1253
                // Close zout outputstream
1254
                if (zout != null) {
1255
                    zout.close();
1256
                }
1257
                // close output stream
1258
                if (out != null) {
1259
                    out.close();
1260
                }
1261 1360 tao
1262 2098 jones
            } catch (Exception exc) {
1263
                MetaCatUtil.debugMessage(
1264
                        "Erorr in MetacatServlet.hanldReadAction: "
1265
                                + exc.getMessage(), 30);
1266
                try {
1267
                    if (out != null) {
1268
                        response.setContentType("text/xml");
1269
                        // Send back error message by printWriter
1270
                        pw = new PrintWriter(out);
1271
                        pw.println("<?xml version=\"1.0\"?>");
1272
                        pw.println("<error>");
1273
                        pw.println(notFoundE.getMessage());
1274
                        pw.println("</error>");
1275
                        pw.close();
1276
                        out.close();
1277 1360 tao
1278 2098 jones
                    } else {
1279
                        response.setContentType("text/xml"); //MIME type
1280
                        // Send back error message if out = null
1281
                        if (pw == null) {
1282
                            // If pw is null, open the respnose
1283
                            pw = response.getWriter();
1284
                        }
1285
                        pw.println("<?xml version=\"1.0\"?>");
1286
                        pw.println("<error>");
1287
                        pw.println(notFoundE.getMessage());
1288
                        pw.println("</error>");
1289
                        pw.close();
1290
                    }
1291
                    // close zout
1292
                    if (zout != null) {
1293
                        zout.close();
1294
                    }
1295
                } catch (IOException ie) {
1296
                    MetaCatUtil.debugMessage("Problem with the servlet output "
1297
                            + "in MetacatServlet.handleReadAction: "
1298
                            + ie.getMessage(), 30);
1299
                }
1300
            }
1301
        } catch (Exception e) {
1302
            try {
1303 1716 berkley
1304 2098 jones
                if (out != null) {
1305
                    response.setContentType("text/xml"); //MIME type
1306
                    pw = new PrintWriter(out);
1307
                    pw.println("<?xml version=\"1.0\"?>");
1308
                    pw.println("<error>");
1309
                    pw.println(e.getMessage());
1310
                    pw.println("</error>");
1311
                    pw.close();
1312
                    out.close();
1313
                } else {
1314
                    response.setContentType("text/xml"); //MIME type
1315
                    // Send back error message if out = null
1316
                    if (pw == null) {
1317
                        pw = response.getWriter();
1318
                    }
1319
                    pw.println("<?xml version=\"1.0\"?>");
1320
                    pw.println("<error>");
1321
                    pw.println(e.getMessage());
1322
                    pw.println("</error>");
1323
                    pw.close();
1324 1360 tao
1325 2098 jones
                }
1326
                // Close zip output stream
1327
                if (zout != null) {
1328
                    zout.close();
1329
                }
1330 1360 tao
1331 2098 jones
            } catch (IOException ioe) {
1332
                MetaCatUtil.debugMessage("Problem with the servlet output "
1333
                        + "in MetacatServlet.handleReadAction: "
1334
                        + ioe.getMessage(), 30);
1335
                ioe.printStackTrace(System.out);
1336 731 bojilova
1337 2098 jones
            }
1338 1360 tao
1339 2098 jones
            MetaCatUtil.debugMessage(
1340
                    "Error in MetacatServlet.handleReadAction: "
1341
                            + e.getMessage(), 30);
1342
            //e.printStackTrace(System.out);
1343 731 bojilova
        }
1344 2098 jones
    }
1345 1360 tao
1346 2169 sgarg
    /** read metadata or data from Metacat
1347 2098 jones
     */
1348 2169 sgarg
    private void readFromMetacat(HttpServletRequest request,
1349 2102 jones
            HttpServletResponse response, String docid, String qformat,
1350
            String abstrpath, String user, String[] groups, boolean zip,
1351
            ZipOutputStream zout, boolean withInlineData, Hashtable params)
1352
            throws ClassNotFoundException, IOException, SQLException,
1353
            McdbException, Exception
1354 1292 tao
    {
1355 1360 tao
1356 2098 jones
        try {
1357 1360 tao
1358 2098 jones
            DocumentImpl doc = new DocumentImpl(docid);
1359 1360 tao
1360 2098 jones
            //check the permission for read
1361 2113 jones
            if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1362 2098 jones
                Exception e = new Exception("User " + user
1363
                        + " does not have permission"
1364
                        + " to read the document with the docid " + docid);
1365 731 bojilova
1366 2098 jones
                throw e;
1367
            }
1368 1360 tao
1369 2098 jones
            if (doc.getRootNodeID() == 0) {
1370
                // this is data file
1371
                String filepath = MetaCatUtil.getOption("datafilepath");
1372
                if (!filepath.endsWith("/")) {
1373
                    filepath += "/";
1374
                }
1375
                String filename = filepath + docid;
1376
                FileInputStream fin = null;
1377
                fin = new FileInputStream(filename);
1378 1360 tao
1379 2098 jones
                //MIME type
1380
                String contentType = getServletContext().getMimeType(filename);
1381
                if (contentType == null) {
1382
                    ContentTypeProvider provider = new ContentTypeProvider(
1383
                            docid);
1384
                    contentType = provider.getContentType();
1385
                    MetaCatUtil.debugMessage("Final contenttype is: "
1386
                            + contentType, 30);
1387
                }
1388 731 bojilova
1389 2098 jones
                response.setContentType(contentType);
1390
                // if we decide to use "application/octet-stream" for all data
1391
                // returns
1392
                // response.setContentType("application/octet-stream");
1393 731 bojilova
1394 2098 jones
                try {
1395 731 bojilova
1396 2098 jones
                    ServletOutputStream out = response.getOutputStream();
1397
                    byte[] buf = new byte[4 * 1024]; // 4K buffer
1398
                    int b = fin.read(buf);
1399
                    while (b != -1) {
1400
                        out.write(buf, 0, b);
1401
                        b = fin.read(buf);
1402
                    }
1403
                } finally {
1404
                    if (fin != null) fin.close();
1405
                }
1406 2169 sgarg
1407 2098 jones
            } else {
1408
                // this is metadata doc
1409 2273 sgarg
                if (qformat.equals("xml") || qformat.equals("")) {
1410
                    // if equals "", that means no qformat is specified. hence
1411
                    // by default the document should be returned in xml format
1412 2098 jones
                    // set content type first
1413
                    response.setContentType("text/xml"); //MIME type
1414
                    PrintWriter out = response.getWriter();
1415
                    doc.toXml(out, user, groups, withInlineData);
1416
                } else {
1417
                    response.setContentType("text/html"); //MIME type
1418
                    PrintWriter out = response.getWriter();
1419 1360 tao
1420 2098 jones
                    // Look up the document type
1421
                    String doctype = doc.getDoctype();
1422
                    // Transform the document to the new doctype
1423
                    DBTransform dbt = new DBTransform();
1424
                    dbt.transformXMLDocument(doc.toString(user, groups,
1425
                            withInlineData), doctype, "-//W3C//HTML//EN",
1426
                            qformat, out, params);
1427
                }
1428 1360 tao
1429 2098 jones
            }
1430 2169 sgarg
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1431 2101 jones
                    docid, "read");
1432 2098 jones
        } catch (Exception except) {
1433
            throw except;
1434
        }
1435
    }
1436 1360 tao
1437 2169 sgarg
    /**
1438
     * read data from URLConnection
1439 2098 jones
     */
1440
    private void readFromURLConnection(HttpServletResponse response,
1441
            String docid) throws IOException, MalformedURLException
1442
    {
1443
        ServletOutputStream out = response.getOutputStream();
1444
        String contentType = getServletContext().getMimeType(docid); //MIME
1445
                                                                     // type
1446
        if (contentType == null) {
1447
            if (docid.endsWith(".xml")) {
1448
                contentType = "text/xml";
1449
            } else if (docid.endsWith(".css")) {
1450
                contentType = "text/css";
1451
            } else if (docid.endsWith(".dtd")) {
1452
                contentType = "text/plain";
1453
            } else if (docid.endsWith(".xsd")) {
1454
                contentType = "text/xml";
1455
            } else if (docid.endsWith("/")) {
1456
                contentType = "text/html";
1457
            } else {
1458
                File f = new File(docid);
1459
                if (f.isDirectory()) {
1460
                    contentType = "text/html";
1461
                } else {
1462
                    contentType = "application/octet-stream";
1463
                }
1464
            }
1465 1360 tao
        }
1466 2098 jones
        response.setContentType(contentType);
1467
        // if we decide to use "application/octet-stream" for all data returns
1468
        // response.setContentType("application/octet-stream");
1469 1360 tao
1470 2098 jones
        // this is http url
1471
        URL url = new URL(docid);
1472
        BufferedInputStream bis = null;
1473
        try {
1474
            bis = new BufferedInputStream(url.openStream());
1475 731 bojilova
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1476 2098 jones
            int b = bis.read(buf);
1477 731 bojilova
            while (b != -1) {
1478 2098 jones
                out.write(buf, 0, b);
1479
                b = bis.read(buf);
1480 731 bojilova
            }
1481 2098 jones
        } finally {
1482
            if (bis != null) bis.close();
1483 636 berkley
        }
1484 1360 tao
1485 636 berkley
    }
1486 1360 tao
1487 2169 sgarg
    /**
1488 2098 jones
     * read file/doc and write to ZipOutputStream
1489 2169 sgarg
     *
1490 2098 jones
     * @param docid
1491
     * @param zout
1492
     * @param user
1493
     * @param groups
1494
     * @throws ClassNotFoundException
1495
     * @throws IOException
1496
     * @throws SQLException
1497
     * @throws McdbException
1498
     * @throws Exception
1499
     */
1500 2169 sgarg
    private void addDocToZip(HttpServletRequest request, String docid,
1501 2102 jones
            ZipOutputStream zout, String user, String[] groups) throws
1502
            ClassNotFoundException, IOException, SQLException, McdbException,
1503
            Exception
1504 1293 tao
    {
1505 2098 jones
        byte[] bytestring = null;
1506
        ZipEntry zentry = null;
1507 1360 tao
1508 598 bojilova
        try {
1509 2098 jones
            URL url = new URL(docid);
1510 1360 tao
1511 2098 jones
            // this http url; read from URLConnection; add to zip
1512
            zentry = new ZipEntry(docid);
1513
            zout.putNextEntry(zentry);
1514
            BufferedInputStream bis = null;
1515
            try {
1516
                bis = new BufferedInputStream(url.openStream());
1517
                byte[] buf = new byte[4 * 1024]; // 4K buffer
1518
                int b = bis.read(buf);
1519
                while (b != -1) {
1520
                    zout.write(buf, 0, b);
1521
                    b = bis.read(buf);
1522
                }
1523
            } finally {
1524
                if (bis != null) bis.close();
1525
            }
1526
            zout.closeEntry();
1527 1716 berkley
1528 2098 jones
        } catch (MalformedURLException mue) {
1529 203 jones
1530 2098 jones
            // this is metacat doc (data file or metadata doc)
1531
            try {
1532
                DocumentImpl doc = new DocumentImpl(docid);
1533 1360 tao
1534 2098 jones
                //check the permission for read
1535 2113 jones
                if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1536 2098 jones
                    Exception e = new Exception("User " + user
1537
                            + " does not have "
1538
                            + "permission to read the document with the docid "
1539
                            + docid);
1540
                    throw e;
1541
                }
1542 1360 tao
1543 2098 jones
                if (doc.getRootNodeID() == 0) {
1544
                    // this is data file; add file to zip
1545
                    String filepath = MetaCatUtil.getOption("datafilepath");
1546
                    if (!filepath.endsWith("/")) {
1547
                        filepath += "/";
1548
                    }
1549
                    String filename = filepath + docid;
1550
                    FileInputStream fin = null;
1551
                    fin = new FileInputStream(filename);
1552
                    try {
1553 1360 tao
1554 2098 jones
                        zentry = new ZipEntry(docid);
1555
                        zout.putNextEntry(zentry);
1556
                        byte[] buf = new byte[4 * 1024]; // 4K buffer
1557
                        int b = fin.read(buf);
1558
                        while (b != -1) {
1559
                            zout.write(buf, 0, b);
1560
                            b = fin.read(buf);
1561
                        }
1562
                    } finally {
1563
                        if (fin != null) fin.close();
1564
                    }
1565
                    zout.closeEntry();
1566 1716 berkley
1567 2098 jones
                } else {
1568
                    // this is metadata doc; add doc to zip
1569
                    bytestring = doc.toString().getBytes();
1570
                    zentry = new ZipEntry(docid + ".xml");
1571
                    zentry.setSize(bytestring.length);
1572
                    zout.putNextEntry(zentry);
1573
                    zout.write(bytestring, 0, bytestring.length);
1574
                    zout.closeEntry();
1575
                }
1576 2169 sgarg
                EventLog.getInstance().log(request.getRemoteAddr(), user,
1577 2101 jones
                        docid, "read");
1578 2098 jones
            } catch (Exception except) {
1579
                throw except;
1580
            }
1581 1360 tao
        }
1582 2098 jones
    }
1583 309 bojilova
1584 2098 jones
    /**
1585
     * If metacat couldn't find a data file or document locally, it will read
1586
     * this docid from its home server. This is for the replication feature
1587
     */
1588
    private void readFromRemoteMetaCat(HttpServletResponse response,
1589
            String docid, String rev, String user, String password,
1590
            ServletOutputStream out, boolean zip, ZipOutputStream zout)
1591
            throws Exception
1592 1466 tao
    {
1593 2098 jones
        // Create a object of RemoteDocument, "" is for zipEntryPath
1594
        RemoteDocument remoteDoc = new RemoteDocument(docid, rev, user,
1595
                password, "");
1596
        String docType = remoteDoc.getDocType();
1597
        // Only read data file
1598
        if (docType.equals("BIN")) {
1599
            // If it is zip format
1600
            if (zip) {
1601
                remoteDoc.readDocumentFromRemoteServerByZip(zout);
1602
            } else {
1603
                if (out == null) {
1604
                    out = response.getOutputStream();
1605
                }
1606
                response.setContentType("application/octet-stream");
1607
                remoteDoc.readDocumentFromRemoteServer(out);
1608
            }
1609
        } else {
1610
            throw new Exception("Docid: " + docid + "." + rev
1611
                    + " couldn't find");
1612
        }
1613 203 jones
    }
1614
1615 2098 jones
    /**
1616
     * Handle the database putdocument request and write an XML document to the
1617
     * database connection
1618
     */
1619 2102 jones
    private void handleInsertOrUpdateAction(HttpServletRequest request,
1620
            HttpServletResponse response, PrintWriter out, Hashtable params,
1621 2098 jones
            String user, String[] groups)
1622
    {
1623
        DBConnection dbConn = null;
1624
        int serialNumber = -1;
1625 1360 tao
1626 2252 sgarg
        if(params.get("docid") == null){
1627
            out.println("<?xml version=\"1.0\"?>");
1628
            out.println("<error>");
1629
            out.println("Docid not specified");
1630
            out.println("</error>");
1631 2576 sgarg
            MetaCatUtil.debugMessage("Docid not specified",10);
1632 2252 sgarg
            return;
1633
        }
1634 2576 sgarg
1635
        if(!MetaCatUtil.canInsertOrUpdate(user, groups)){
1636
        	out.println("<?xml version=\"1.0\"?>");
1637
            out.println("<error>");
1638
            out.println("User '" + user + "' not allowed to insert and update");
1639
            out.println("</error>");
1640
            MetaCatUtil.debugMessage("User '" + user + "' not allowed to insert and update",10);
1641
            return;
1642
        }
1643 2252 sgarg
1644 2098 jones
        try {
1645
            // Get the document indicated
1646
            String[] doctext = (String[]) params.get("doctext");
1647
            String pub = null;
1648
            if (params.containsKey("public")) {
1649
                pub = ((String[]) params.get("public"))[0];
1650
            }
1651 1360 tao
1652 2098 jones
            StringReader dtd = null;
1653
            if (params.containsKey("dtdtext")) {
1654
                String[] dtdtext = (String[]) params.get("dtdtext");
1655
                try {
1656
                    if (!dtdtext[0].equals("")) {
1657
                        dtd = new StringReader(dtdtext[0]);
1658
                    }
1659
                } catch (NullPointerException npe) {
1660
                }
1661
            }
1662 2347 sgarg
1663
            if(doctext == null){
1664
                out.println("<?xml version=\"1.0\"?>");
1665
                out.println("<error>");
1666
                out.println("Document text not submitted");
1667
                out.println("</error>");
1668
                return;
1669
            }
1670
1671 2098 jones
            StringReader xml = new StringReader(doctext[0]);
1672
            boolean validate = false;
1673
            DocumentImplWrapper documentWrapper = null;
1674
            try {
1675
                // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ...
1676
                // >
1677
                // in order to decide whether to use validation parser
1678
                validate = needDTDValidation(xml);
1679
                if (validate) {
1680
                    // set a dtd base validation parser
1681
                    String rule = DocumentImpl.DTD;
1682
                    documentWrapper = new DocumentImplWrapper(rule, validate);
1683
                } else if (needSchemaValidation(xml)) {
1684
                    // for eml2
1685 2169 sgarg
                    String namespace = findNamespace(xml);
1686 2224 sgarg
                    if (namespace.compareTo(DocumentImpl.EML2_0_0NAMESPACE) == 0
1687
                                || namespace.compareTo(
1688
                                DocumentImpl.EML2_0_1NAMESPACE) == 0) {
1689 2098 jones
                        // set eml2 base validation parser
1690 2163 tao
                        String rule = DocumentImpl.EML200;
1691 2098 jones
                        // using emlparser to check id validation
1692
                        EMLParser parser = new EMLParser(doctext[0]);
1693
                        documentWrapper = new DocumentImplWrapper(rule, true);
1694 2169 sgarg
                    } else if (namespace.compareTo(
1695
                                DocumentImpl.EML2_1_0NAMESPACE) == 0) {
1696
                        // set eml2 base validation parser
1697
                        String rule = DocumentImpl.EML210;
1698
                        // using emlparser to check id validation
1699
                        EMLParser parser = new EMLParser(doctext[0]);
1700
                        documentWrapper = new DocumentImplWrapper(rule, true);
1701 2098 jones
                    } else {
1702
                        // set schema base validation parser
1703
                        String rule = DocumentImpl.SCHEMA;
1704
                        documentWrapper = new DocumentImplWrapper(rule, true);
1705
                    }
1706
                } else {
1707
                    documentWrapper = new DocumentImplWrapper("", false);
1708
                }
1709 695 bojilova
1710 2098 jones
                String[] action = (String[]) params.get("action");
1711
                String[] docid = (String[]) params.get("docid");
1712
                String newdocid = null;
1713 695 bojilova
1714 2098 jones
                String doAction = null;
1715
                if (action[0].equals("insert")) {
1716
                    doAction = "INSERT";
1717
                } else if (action[0].equals("update")) {
1718
                    doAction = "UPDATE";
1719
                }
1720 695 bojilova
1721 2098 jones
                try {
1722
                    // get a connection from the pool
1723
                    dbConn = DBConnectionPool
1724
                            .getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1725
                    serialNumber = dbConn.getCheckOutSerialNumber();
1726 1716 berkley
1727 2098 jones
                    // write the document to the database
1728
                    try {
1729
                        String accNumber = docid[0];
1730
                        MetaCatUtil.debugMessage("" + doAction + " "
1731
                                + accNumber + "...", 10);
1732
                        if (accNumber.equals("")) {
1733
                            accNumber = null;
1734 2102 jones
                        }
1735 2098 jones
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1736
                                doAction, accNumber, user, groups);
1737 2169 sgarg
                        EventLog.getInstance().log(request.getRemoteAddr(),
1738 2102 jones
                                user, accNumber, action[0]);
1739
                    } catch (NullPointerException npe) {
1740 2098 jones
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1741
                                doAction, null, user, groups);
1742 2169 sgarg
                        EventLog.getInstance().log(request.getRemoteAddr(),
1743 2102 jones
                                user, "", action[0]);
1744
                    }
1745
                }
1746 2098 jones
                finally {
1747
                    // Return db connection
1748
                    DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1749
                }
1750 1716 berkley
1751 2098 jones
                // set content type and other response header fields first
1752
                //response.setContentType("text/xml");
1753
                out.println("<?xml version=\"1.0\"?>");
1754
                out.println("<success>");
1755
                out.println("<docid>" + newdocid + "</docid>");
1756
                out.println("</success>");
1757 1716 berkley
1758 2098 jones
            } catch (NullPointerException npe) {
1759
                //response.setContentType("text/xml");
1760
                out.println("<?xml version=\"1.0\"?>");
1761
                out.println("<error>");
1762
                out.println(npe.getMessage());
1763
                out.println("</error>");
1764
            }
1765
        } catch (Exception e) {
1766
            //response.setContentType("text/xml");
1767
            out.println("<?xml version=\"1.0\"?>");
1768
            out.println("<error>");
1769
            out.println(e.getMessage());
1770
            out.println("</error>");
1771 1760 tao
        }
1772 1409 tao
    }
1773 1716 berkley
1774 2098 jones
    /**
1775
     * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... > in
1776
     * order to decide whether to use validation parser
1777
     */
1778
    private static boolean needDTDValidation(StringReader xmlreader)
1779
            throws IOException
1780 1629 tao
    {
1781 2089 tao
1782 2098 jones
        StringBuffer cbuff = new StringBuffer();
1783
        java.util.Stack st = new java.util.Stack();
1784
        boolean validate = false;
1785
        int c;
1786
        int inx;
1787 2089 tao
1788 2098 jones
        // read from the stream until find the keywords
1789
        while ((st.empty() || st.size() < 4) && ((c = xmlreader.read()) != -1)) {
1790
            cbuff.append((char) c);
1791 1716 berkley
1792 2098 jones
            // "<!DOCTYPE" keyword is found; put it in the stack
1793
            if ((inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1) {
1794
                cbuff = new StringBuffer();
1795
                st.push("<!DOCTYPE");
1796
            }
1797
            // "PUBLIC" keyword is found; put it in the stack
1798
            if ((inx = cbuff.toString().indexOf("PUBLIC")) != -1) {
1799
                cbuff = new StringBuffer();
1800
                st.push("PUBLIC");
1801
            }
1802
            // "SYSTEM" keyword is found; put it in the stack
1803
            if ((inx = cbuff.toString().indexOf("SYSTEM")) != -1) {
1804
                cbuff = new StringBuffer();
1805
                st.push("SYSTEM");
1806
            }
1807
            // ">" character is found; put it in the stack
1808
            // ">" is found twice: fisrt from <?xml ...?>
1809
            // and second from <!DOCTYPE ... >
1810
            if ((inx = cbuff.toString().indexOf(">")) != -1) {
1811
                cbuff = new StringBuffer();
1812
                st.push(">");
1813
            }
1814
        }
1815 203 jones
1816 2098 jones
        // close the stream
1817
        xmlreader.reset();
1818 1360 tao
1819 2098 jones
        // check the stack whether it contains the keywords:
1820
        // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1821
        if (st.size() == 4) {
1822
            if (((String) st.pop()).equals(">")
1823
                    && (((String) st.peek()).equals("PUBLIC") | ((String) st
1824
                            .pop()).equals("SYSTEM"))
1825
                    && ((String) st.pop()).equals("<!DOCTYPE")) {
1826
                validate = true;
1827
            }
1828
        }
1829 1360 tao
1830 2098 jones
        MetaCatUtil.debugMessage("Validation for dtd is " + validate, 10);
1831
        return validate;
1832 1360 tao
    }
1833
1834 2098 jones
    // END OF INSERT/UPDATE SECTION
1835 68 higgins
1836 2098 jones
    /* check if the xml string contains key words to specify schema loocation */
1837
    private boolean needSchemaValidation(StringReader xml) throws IOException
1838
    {
1839
        boolean needSchemaValidate = false;
1840
        if (xml == null) {
1841
            MetaCatUtil.debugMessage("Validation for schema is "
1842
                    + needSchemaValidate, 10);
1843
            return needSchemaValidate;
1844
        }
1845
        System.out.println("before get target line");
1846
        String targetLine = getSchemaLine(xml);
1847 2268 sgarg
        System.out.println("after get target line");
1848 2098 jones
        // to see if the second line contain some keywords
1849
        if (targetLine != null
1850
                && (targetLine.indexOf(SCHEMALOCATIONKEYWORD) != -1 || targetLine
1851
                        .indexOf(NONAMESPACELOCATION) != -1)) {
1852
            // if contains schema location key word, should be validate
1853
            needSchemaValidate = true;
1854
        }
1855 1360 tao
1856 2098 jones
        MetaCatUtil.debugMessage("Validation for schema is "
1857
                + needSchemaValidate, 10);
1858
        return needSchemaValidate;
1859 68 higgins
1860 2098 jones
    }
1861 1360 tao
1862 2098 jones
    /* check if the xml string contains key words to specify schema loocation */
1863 2169 sgarg
    private String findNamespace(StringReader xml) throws IOException
1864 2098 jones
    {
1865 2169 sgarg
        String namespace = null;
1866
1867
        String eml2_0_0NameSpace = DocumentImpl.EML2_0_0NAMESPACE;
1868 2224 sgarg
        String eml2_0_1NameSpace = DocumentImpl.EML2_0_1NAMESPACE;
1869 2169 sgarg
        String eml2_1_0NameSpace = DocumentImpl.EML2_1_0NAMESPACE;
1870
1871 2098 jones
        if (xml == null) {
1872
            MetaCatUtil.debugMessage("Validation for schema is "
1873 2169 sgarg
                    + namespace, 10);
1874
            return namespace;
1875 2098 jones
        }
1876
        String targetLine = getSchemaLine(xml);
1877 309 bojilova
1878 2098 jones
        if (targetLine != null) {
1879 1360 tao
1880 2098 jones
            int startIndex = targetLine.indexOf(SCHEMALOCATIONKEYWORD);
1881
            int start = 1;
1882
            int end = 1;
1883
            String schemaLocation = null;
1884
            int count = 0;
1885
            if (startIndex != -1) {
1886
                for (int i = startIndex; i < targetLine.length(); i++) {
1887
                    if (targetLine.charAt(i) == '"') {
1888
                        count++;
1889
                    }
1890
                    if (targetLine.charAt(i) == '"' && count == 1) {
1891
                        start = i;
1892
                    }
1893
                    if (targetLine.charAt(i) == '"' && count == 2) {
1894
                        end = i;
1895
                        break;
1896
                    }
1897
                }
1898
            }
1899
            schemaLocation = targetLine.substring(start + 1, end);
1900
            MetaCatUtil.debugMessage("schemaLocation in xml is: "
1901
                    + schemaLocation, 30);
1902 2169 sgarg
            if (schemaLocation.indexOf(eml2_0_0NameSpace) != -1) {
1903
                namespace = eml2_0_0NameSpace;
1904 2224 sgarg
            } else if (schemaLocation.indexOf(eml2_0_1NameSpace) != -1) {
1905
                namespace = eml2_0_1NameSpace;
1906 2169 sgarg
            } else if (schemaLocation.indexOf(eml2_1_0NameSpace) != -1) {
1907
                namespace = eml2_1_0NameSpace;
1908 2098 jones
            }
1909
        }
1910 185 jones
1911 2169 sgarg
        MetaCatUtil.debugMessage("Validation for eml is " + namespace,
1912 2098 jones
                10);
1913 2224 sgarg
1914 2169 sgarg
        return namespace;
1915 1360 tao
1916 103 jones
    }
1917 68 higgins
1918 2098 jones
    private String getSchemaLine(StringReader xml) throws IOException
1919
    {
1920
        // find the line
1921
        String secondLine = null;
1922
        int count = 0;
1923
        int endIndex = 0;
1924
        int startIndex = 0;
1925
        final int TARGETNUM = 2;
1926
        StringBuffer buffer = new StringBuffer();
1927
        boolean comment = false;
1928
        char thirdPreviousCharacter = '?';
1929
        char secondPreviousCharacter = '?';
1930
        char previousCharacter = '?';
1931
        char currentCharacter = '?';
1932 2268 sgarg
        int tmp = xml.read();
1933
        while (tmp != -1) {
1934
            currentCharacter = (char)tmp;
1935 2098 jones
            //in a comment
1936
            if (currentCharacter == '-' && previousCharacter == '-'
1937
                    && secondPreviousCharacter == '!'
1938
                    && thirdPreviousCharacter == '<') {
1939
                comment = true;
1940
            }
1941
            //out of comment
1942
            if (comment && currentCharacter == '>' && previousCharacter == '-'
1943
                    && secondPreviousCharacter == '-') {
1944
                comment = false;
1945
            }
1946 68 higgins
1947 2098 jones
            //this is not comment
1948
            if (currentCharacter != '!' && previousCharacter == '<' && !comment) {
1949
                count++;
1950
            }
1951
            // get target line
1952
            if (count == TARGETNUM && currentCharacter != '>') {
1953
                buffer.append(currentCharacter);
1954
            }
1955
            if (count == TARGETNUM && currentCharacter == '>') {
1956
                break;
1957
            }
1958
            thirdPreviousCharacter = secondPreviousCharacter;
1959
            secondPreviousCharacter = previousCharacter;
1960
            previousCharacter = currentCharacter;
1961 2268 sgarg
            tmp = xml.read();
1962 2098 jones
        }
1963
        secondLine = buffer.toString();
1964
        MetaCatUtil
1965
                .debugMessage("the second line string is: " + secondLine, 25);
1966
        xml.reset();
1967
        return secondLine;
1968
    }
1969 253 jones
1970 2098 jones
    /**
1971
     * Handle the database delete request and delete an XML document from the
1972
     * database connection
1973
     */
1974
    private void handleDeleteAction(PrintWriter out, Hashtable params,
1975 2169 sgarg
            HttpServletRequest request, HttpServletResponse response,
1976 2102 jones
            String user, String[] groups)
1977 2098 jones
    {
1978 1360 tao
1979 2098 jones
        String[] docid = (String[]) params.get("docid");
1980 1360 tao
1981 2251 sgarg
        if(docid == null){
1982
          response.setContentType("text/xml");
1983
          out.println("<?xml version=\"1.0\"?>");
1984
          out.println("<error>");
1985 2252 sgarg
          out.println("Docid not specified.");
1986 2251 sgarg
          out.println("</error>");
1987
        } else {
1988 1360 tao
1989 2251 sgarg
            // delete the document from the database
1990 2098 jones
            try {
1991 2251 sgarg
1992
                try {
1993 2298 tao
                    // null means notify server is null
1994
                    DocumentImpl.delete(docid[0], user, groups, null);
1995 2251 sgarg
                    EventLog.getInstance().log(request.getRemoteAddr(),
1996
                                               user, docid[0], "delete");
1997
                    response.setContentType("text/xml");
1998
                    out.println("<?xml version=\"1.0\"?>");
1999
                    out.println("<success>");
2000
                    out.println("Document deleted.");
2001
                    out.println("</success>");
2002
                }
2003
                catch (AccessionNumberException ane) {
2004
                    response.setContentType("text/xml");
2005
                    out.println("<?xml version=\"1.0\"?>");
2006
                    out.println("<error>");
2007 2253 sgarg
                    //out.println("Error deleting document!!!");
2008 2251 sgarg
                    out.println(ane.getMessage());
2009
                    out.println("</error>");
2010
                }
2011
            }
2012
            catch (Exception e) {
2013 2098 jones
                response.setContentType("text/xml");
2014
                out.println("<?xml version=\"1.0\"?>");
2015
                out.println("<error>");
2016 2251 sgarg
                out.println(e.getMessage());
2017 2098 jones
                out.println("</error>");
2018
            }
2019
        }
2020 1292 tao
    }
2021 1360 tao
2022 2098 jones
    /**
2023
     * Handle the validation request and return the results to the requestor
2024
     */
2025
    private void handleValidateAction(PrintWriter out, Hashtable params)
2026 1292 tao
    {
2027 1360 tao
2028 2098 jones
        // Get the document indicated
2029
        String valtext = null;
2030
        DBConnection dbConn = null;
2031
        int serialNumber = -1;
2032 1292 tao
2033 2098 jones
        try {
2034
            valtext = ((String[]) params.get("valtext"))[0];
2035
        } catch (Exception nullpe) {
2036 1360 tao
2037 2098 jones
            String docid = null;
2038
            try {
2039
                // Find the document id number
2040
                docid = ((String[]) params.get("docid"))[0];
2041 1360 tao
2042 2098 jones
                // Get the document indicated from the db
2043
                DocumentImpl xmldoc = new DocumentImpl(docid);
2044
                valtext = xmldoc.toString();
2045 688 bojilova
2046 2098 jones
            } catch (NullPointerException npe) {
2047 1360 tao
2048 2098 jones
                out.println("<error>Error getting document ID: " + docid
2049
                        + "</error>");
2050
                //if ( conn != null ) { util.returnConnection(conn); }
2051
                return;
2052
            } catch (Exception e) {
2053 688 bojilova
2054 2098 jones
                out.println(e.getMessage());
2055
            }
2056
        }
2057 688 bojilova
2058 2098 jones
        try {
2059
            // get a connection from the pool
2060
            dbConn = DBConnectionPool
2061
                    .getDBConnection("MetaCatServlet.handleValidateAction");
2062
            serialNumber = dbConn.getCheckOutSerialNumber();
2063
            DBValidate valobj = new DBValidate(saxparser, dbConn);
2064
            boolean valid = valobj.validateString(valtext);
2065 1360 tao
2066 2098 jones
            // set content type and other response header fields first
2067 688 bojilova
2068 2098 jones
            out.println(valobj.returnErrors());
2069 731 bojilova
2070 2098 jones
        } catch (NullPointerException npe2) {
2071
            // set content type and other response header fields first
2072 1360 tao
2073 2098 jones
            out.println("<error>Error validating document.</error>");
2074
        } catch (Exception e) {
2075 731 bojilova
2076 2098 jones
            out.println(e.getMessage());
2077
        } finally {
2078
            // Return db connection
2079
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2080
        }
2081
    }
2082 1360 tao
2083 2098 jones
    /**
2084
     * Handle "getrevsionanddoctype" action Given a docid, return it's current
2085
     * revision and doctype from data base The output is String look like
2086
     * "rev;doctype"
2087
     */
2088
    private void handleGetRevisionAndDocTypeAction(PrintWriter out,
2089
            Hashtable params)
2090
    {
2091
        // To store doc parameter
2092
        String[] docs = new String[10];
2093
        // Store a single doc id
2094
        String givenDocId = null;
2095
        // Get docid from parameters
2096
        if (params.containsKey("docid")) {
2097
            docs = (String[]) params.get("docid");
2098
        }
2099
        // Get first docid form string array
2100
        givenDocId = docs[0];
2101 731 bojilova
2102 2098 jones
        try {
2103
            // Make sure there is a docid
2104
            if (givenDocId == null || givenDocId.equals("")) { throw new Exception(
2105
                    "User didn't specify docid!"); }//if
2106 1360 tao
2107 2098 jones
            // Create a DBUtil object
2108
            DBUtil dbutil = new DBUtil();
2109
            // Get a rev and doctype
2110
            String revAndDocType = dbutil
2111
                    .getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
2112
            out.println(revAndDocType);
2113 731 bojilova
2114 2098 jones
        } catch (Exception e) {
2115
            // Handle exception
2116
            out.println("<?xml version=\"1.0\"?>");
2117
            out.println("<error>");
2118
            out.println(e.getMessage());
2119
            out.println("</error>");
2120
        }
2121 302 bojilova
2122 2098 jones
    }
2123 1360 tao
2124 2098 jones
    /**
2125
     * Handle "getaccesscontrol" action. Read Access Control List from db
2126
     * connection in XML format
2127
     */
2128
    private void handleGetAccessControlAction(PrintWriter out,
2129
            Hashtable params, HttpServletResponse response, String username,
2130
            String[] groupnames)
2131
    {
2132
        DBConnection dbConn = null;
2133
        int serialNumber = -1;
2134
        String docid = ((String[]) params.get("docid"))[0];
2135 302 bojilova
2136 2098 jones
        try {
2137 1360 tao
2138 2098 jones
            // get connection from the pool
2139
            dbConn = DBConnectionPool
2140
                    .getDBConnection("MetaCatServlet.handleGetAccessControlAction");
2141
            serialNumber = dbConn.getCheckOutSerialNumber();
2142
            AccessControlList aclobj = new AccessControlList(dbConn);
2143
            String acltext = aclobj.getACL(docid, username, groupnames);
2144
            out.println(acltext);
2145 302 bojilova
2146 2098 jones
        } catch (Exception e) {
2147
            out.println("<?xml version=\"1.0\"?>");
2148
            out.println("<error>");
2149
            out.println(e.getMessage());
2150
            out.println("</error>");
2151
        } finally {
2152
            // Retrun db connection to pool
2153
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2154
        }
2155 1360 tao
    }
2156
2157 2098 jones
    /**
2158
     * Handle the "getprincipals" action. Read all principals from
2159
     * authentication scheme in XML format
2160
     */
2161
    private void handleGetPrincipalsAction(PrintWriter out, String user,
2162
            String password)
2163
    {
2164
        try {
2165
            AuthSession auth = new AuthSession();
2166
            String principals = auth.getPrincipals(user, password);
2167
            out.println(principals);
2168 302 bojilova
2169 2098 jones
        } catch (Exception e) {
2170
            out.println("<?xml version=\"1.0\"?>");
2171
            out.println("<error>");
2172
            out.println(e.getMessage());
2173
            out.println("</error>");
2174
        }
2175
    }
2176 699 bojilova
2177 2098 jones
    /**
2178
     * Handle "getdoctypes" action. Read all doctypes from db connection in XML
2179
     * format
2180
     */
2181
    private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
2182
            HttpServletResponse response)
2183
    {
2184
        try {
2185
            DBUtil dbutil = new DBUtil();
2186
            String doctypes = dbutil.readDoctypes();
2187
            out.println(doctypes);
2188
        } catch (Exception e) {
2189
            out.println("<?xml version=\"1.0\"?>");
2190
            out.println("<error>");
2191
            out.println(e.getMessage());
2192
            out.println("</error>");
2193
        }
2194
    }
2195 1360 tao
2196 2098 jones
    /**
2197
     * Handle the "getdtdschema" action. Read DTD or Schema file for a given
2198
     * doctype from Metacat catalog system
2199
     */
2200
    private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
2201
            HttpServletResponse response)
2202
    {
2203 699 bojilova
2204 2098 jones
        String doctype = null;
2205
        String[] doctypeArr = (String[]) params.get("doctype");
2206 699 bojilova
2207 2098 jones
        // get only the first doctype specified in the list of doctypes
2208
        // it could be done for all doctypes in that list
2209
        if (doctypeArr != null) {
2210
            doctype = ((String[]) params.get("doctype"))[0];
2211
        }
2212 699 bojilova
2213 2098 jones
        try {
2214
            DBUtil dbutil = new DBUtil();
2215
            String dtdschema = dbutil.readDTDSchema(doctype);
2216
            out.println(dtdschema);
2217 1360 tao
2218 2098 jones
        } catch (Exception e) {
2219
            out.println("<?xml version=\"1.0\"?>");
2220
            out.println("<error>");
2221
            out.println(e.getMessage());
2222
            out.println("</error>");
2223
        }
2224 699 bojilova
2225 1360 tao
    }
2226
2227 2098 jones
    /**
2228
     * Handle the "getlastdocid" action. Get the latest docid with rev number
2229
     * from db connection in XML format
2230
     */
2231
    private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
2232
            HttpServletResponse response)
2233
    {
2234 699 bojilova
2235 2098 jones
        String scope = ((String[]) params.get("scope"))[0];
2236
        if (scope == null) {
2237
            scope = ((String[]) params.get("username"))[0];
2238
        }
2239 793 bojilova
2240 2098 jones
        try {
2241 1217 tao
2242 2098 jones
            DBUtil dbutil = new DBUtil();
2243
            String lastDocid = dbutil.getMaxDocid(scope);
2244
            out.println("<?xml version=\"1.0\"?>");
2245
            out.println("<lastDocid>");
2246
            out.println("  <scope>" + scope + "</scope>");
2247
            out.println("  <docid>" + lastDocid + "</docid>");
2248
            out.println("</lastDocid>");
2249 793 bojilova
2250 2098 jones
        } catch (Exception e) {
2251
            out.println("<?xml version=\"1.0\"?>");
2252
            out.println("<error>");
2253
            out.println(e.getMessage());
2254
            out.println("</error>");
2255
        }
2256 1217 tao
    }
2257 1360 tao
2258 2098 jones
    /**
2259 2113 jones
     * Print a report from the event log based on filter parameters passed in
2260
     * from the web.
2261 2169 sgarg
     *
2262 2113 jones
     * @param params the parameters from the web request
2263
     * @param request the http request object for getting request details
2264
     * @param response the http response object for writing output
2265
     */
2266
    private void handleGetLogAction(Hashtable params, HttpServletRequest request,
2267 2558 sgarg
            HttpServletResponse response, String username, String[] groups)
2268 2113 jones
    {
2269
        try {
2270 2312 jones
            response.setContentType("text/xml");
2271
            PrintWriter out = response.getWriter();
2272 2347 sgarg
2273 2312 jones
            // Check that the user is authenticated as an administrator account
2274 2558 sgarg
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2275 2312 jones
                out.print("<error>");
2276 2347 sgarg
                out.print("The user \"" + username +
2277 2312 jones
                        "\" is not authorized for this action.");
2278
                out.print("</error>");
2279
                return;
2280 2113 jones
            }
2281 2347 sgarg
2282 2312 jones
            // Get all of the parameters in the correct formats
2283
            String[] ipAddress = (String[])params.get("ipaddress");
2284
            String[] principal = (String[])params.get("principal");
2285
            String[] docid = (String[])params.get("docid");
2286
            String[] event = (String[])params.get("event");
2287
            String[] startArray = (String[]) params.get("start");
2288
            String[] endArray = (String[]) params.get("end");
2289
            String start = null;
2290
            String end = null;
2291
            if (startArray != null) {
2292
                start = startArray[0];
2293
            }
2294
            if (endArray != null) {
2295
                end = endArray[0];
2296
            }
2297
            Timestamp startDate = null;
2298
            Timestamp endDate = null;
2299
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2300
            try {
2301
                if (start != null) {
2302
                    startDate = new Timestamp((format.parse(start)).getTime());
2303
                }
2304
                if (end != null) {
2305
                    endDate = new Timestamp((format.parse(end)).getTime());
2306
                }
2307
            } catch (ParseException e) {
2308
                System.out.println("Failed to created Timestamp from input.");
2309
            }
2310 2347 sgarg
2311 2312 jones
            // Request the report by passing the filter parameters
2312
            out.println(EventLog.getInstance().getReport(ipAddress, principal,
2313
                    docid, event, startDate, endDate));
2314
            out.close();
2315
        } catch (IOException e) {
2316
            MetaCatUtil.debugMessage(
2317
                    "Could not open http response for writing: " + e.getMessage(), 5);
2318 2113 jones
        }
2319 2312 jones
    }
2320 2169 sgarg
2321 2312 jones
    /**
2322
     * Rebuild the index for one or more documents. If the docid parameter is
2323
     * provided, rebuild for just that one document or list of documents. If
2324
     * not, then rebuild the index for all documents in the xml_documents
2325
     * table.
2326
     *
2327
     * @param params the parameters from the web request
2328
     * @param request the http request object for getting request details
2329
     * @param response the http response object for writing output
2330
     * @param username the username of the authenticated user
2331
     */
2332 2347 sgarg
    private void handleBuildIndexAction(Hashtable params,
2333 2312 jones
            HttpServletRequest request, HttpServletResponse response,
2334 2558 sgarg
            String username, String[] groups)
2335 2312 jones
    {
2336
        // Get all of the parameters in the correct formats
2337
        String[] docid = (String[])params.get("docid");
2338
2339
        // Rebuild the indices for appropriate documents
2340 2113 jones
        try {
2341
            response.setContentType("text/xml");
2342
            PrintWriter out = response.getWriter();
2343 2347 sgarg
2344 2312 jones
            // Check that the user is authenticated as an administrator account
2345 2558 sgarg
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2346 2312 jones
                out.print("<error>");
2347 2347 sgarg
                out.print("The user \"" + username +
2348 2312 jones
                        "\" is not authorized for this action.");
2349
                out.print("</error>");
2350
                return;
2351
            }
2352
2353
            // Process the documents
2354
            out.println("<success>");
2355
            if (docid == null || docid.length == 0) {
2356
                // Process all of the documents
2357
                try {
2358
                    Vector documents = getDocumentList();
2359
                    Iterator it = documents.iterator();
2360
                    while (it.hasNext()) {
2361
                        String id = (String) it.next();
2362
                        buildDocumentIndex(id, out);
2363
                    }
2364
                } catch (SQLException se) {
2365
                    out.print("<error>");
2366
                    out.print(se.getMessage());
2367
                    out.println("</error>");
2368
                }
2369
            } else {
2370
                // Only process the requested documents
2371
                for (int i = 0; i < docid.length; i++) {
2372
                    buildDocumentIndex(docid[i], out);
2373
                }
2374
            }
2375
            out.println("</success>");
2376 2113 jones
            out.close();
2377
        } catch (IOException e) {
2378
            MetaCatUtil.debugMessage(
2379 2169 sgarg
                    "Could not open http response for writing: "
2380 2113 jones
                    + e.getMessage(), 5);
2381
        }
2382
    }
2383 2169 sgarg
2384 2113 jones
    /**
2385 2347 sgarg
     * Build the index for one document by reading the document and
2386 2312 jones
     * calling its buildIndex() method.
2387
     *
2388
     * @param docid the document (with revision) to rebuild
2389
     * @param out the PrintWriter to which output is printed
2390
     */
2391
    private void buildDocumentIndex(String docid, PrintWriter out)
2392
    {
2393
        try {
2394
            DocumentImpl doc = new DocumentImpl(docid, false);
2395
            doc.buildIndex();
2396
            out.print("<docid>" + docid);
2397
            out.println("</docid>");
2398
        } catch (McdbException me) {
2399
            out.print("<error>");
2400
            out.print(me.getMessage());
2401
            out.println("</error>");
2402
        }
2403
    }
2404
2405
    /**
2406 2098 jones
     * Handle documents passed to metacat that are encoded using the
2407
     * "multipart/form-data" mime type. This is typically used for uploading
2408
     * data files which may be binary and large.
2409
     */
2410
    private void handleMultipartForm(HttpServletRequest request,
2411
            HttpServletResponse response)
2412
    {
2413
        PrintWriter out = null;
2414
        String action = null;
2415 793 bojilova
2416 2098 jones
        // Parse the multipart form, and save the parameters in a Hashtable and
2417
        // save the FileParts in a hashtable
2418 798 jones
2419 2098 jones
        Hashtable params = new Hashtable();
2420
        Hashtable fileList = new Hashtable();
2421
        int sizeLimit = (new Integer(MetaCatUtil.getOption("datafilesizelimit")))
2422
                .intValue();
2423
        MetaCatUtil.debugMessage(
2424
                "The limit size of data file is: " + sizeLimit, 50);
2425 798 jones
2426 2098 jones
        try {
2427
            // MBJ: need to put filesize limit in Metacat config
2428
            // (metacat.properties)
2429
            MultipartParser mp = new MultipartParser(request,
2430
                    sizeLimit * 1024 * 1024);
2431
            Part part;
2432
            while ((part = mp.readNextPart()) != null) {
2433
                String name = part.getName();
2434 798 jones
2435 2098 jones
                if (part.isParam()) {
2436
                    // it's a parameter part
2437
                    ParamPart paramPart = (ParamPart) part;
2438
                    String value = paramPart.getStringValue();
2439
                    params.put(name, value);
2440
                    if (name.equals("action")) {
2441
                        action = value;
2442
                    }
2443
                } else if (part.isFile()) {
2444
                    // it's a file part
2445
                    FilePart filePart = (FilePart) part;
2446
                    fileList.put(name, filePart);
2447 798 jones
2448 2098 jones
                    // Stop once the first file part is found, otherwise going
2449
                    // onto the
2450
                    // next part prevents access to the file contents. So...for
2451
                    // upload
2452
                    // to work, the datafile must be the last part
2453
                    break;
2454
                }
2455
            }
2456
        } catch (IOException ioe) {
2457
            try {
2458
                out = response.getWriter();
2459
            } catch (IOException ioe2) {
2460
                System.err
2461
                        .println("Fatal Error: couldn't get response output stream.");
2462
            }
2463
            out.println("<?xml version=\"1.0\"?>");
2464
            out.println("<error>");
2465
            out.println("Error: problem reading multipart data.");
2466
            out.println("</error>");
2467 798 jones
        }
2468
2469 2098 jones
        // Get the session information
2470
        String username = null;
2471
        String password = null;
2472
        String[] groupnames = null;
2473
        String sess_id = null;
2474 798 jones
2475 2098 jones
        // be aware of session expiration on every request
2476
        HttpSession sess = request.getSession(true);
2477
        if (sess.isNew()) {
2478
            // session expired or has not been stored b/w user requests
2479
            username = "public";
2480
            sess.setAttribute("username", username);
2481
        } else {
2482
            username = (String) sess.getAttribute("username");
2483
            password = (String) sess.getAttribute("password");
2484
            groupnames = (String[]) sess.getAttribute("groupnames");
2485
            try {
2486
                sess_id = (String) sess.getId();
2487
            } catch (IllegalStateException ise) {
2488
                System.out
2489
                        .println("error in  handleMultipartForm: this shouldn't "
2490
                                + "happen: the session should be valid: "
2491
                                + ise.getMessage());
2492
            }
2493
        }
2494 1360 tao
2495 2098 jones
        // Get the out stream
2496
        try {
2497
            out = response.getWriter();
2498 798 jones
        } catch (IOException ioe2) {
2499 2098 jones
            MetaCatUtil.debugMessage("Fatal Error: couldn't get response "
2500
                    + "output stream.", 30);
2501 798 jones
        }
2502 1360 tao
2503 2098 jones
        if (action.equals("upload")) {
2504
            if (username != null && !username.equals("public")) {
2505
                handleUploadAction(request, out, params, fileList, username,
2506
                        groupnames);
2507
            } else {
2508 1360 tao
2509 2098 jones
                out.println("<?xml version=\"1.0\"?>");
2510
                out.println("<error>");
2511
                out.println("Permission denied for " + action);
2512
                out.println("</error>");
2513
            }
2514
        } else {
2515
            /*
2516
             * try { out = response.getWriter(); } catch (IOException ioe2) {
2517
             * System.err.println("Fatal Error: couldn't get response output
2518
             * stream.");
2519
             */
2520
            out.println("<?xml version=\"1.0\"?>");
2521
            out.println("<error>");
2522
            out.println(
2523
                    "Error: action not registered.  Please report this error.");
2524
            out.println("</error>");
2525
        }
2526
        out.close();
2527 798 jones
    }
2528
2529 2098 jones
    /**
2530
     * Handle the upload action by saving the attached file to disk and
2531
     * registering it in the Metacat db
2532
     */
2533
    private void handleUploadAction(HttpServletRequest request,
2534
            PrintWriter out, Hashtable params, Hashtable fileList,
2535
            String username, String[] groupnames)
2536 1041 tao
    {
2537 2098 jones
        //PrintWriter out = null;
2538
        //Connection conn = null;
2539
        String action = null;
2540
        String docid = null;
2541 798 jones
2542 2098 jones
        /*
2543
         * response.setContentType("text/xml"); try { out =
2544
         * response.getWriter(); } catch (IOException ioe2) {
2545
         * System.err.println("Fatal Error: couldn't get response output
2546
         * stream.");
2547
         */
2548 798 jones
2549 2098 jones
        if (params.containsKey("docid")) {
2550
            docid = (String) params.get("docid");
2551
        }
2552 798 jones
2553 2098 jones
        // Make sure we have a docid and datafile
2554
        if (docid != null && fileList.containsKey("datafile")) {
2555 798 jones
2556 2098 jones
            // Get a reference to the file part of the form
2557
            FilePart filePart = (FilePart) fileList.get("datafile");
2558
            String fileName = filePart.getFileName();
2559
            MetaCatUtil.debugMessage("Uploading filename: " + fileName, 10);
2560 1360 tao
2561 2098 jones
            // Check if the right file existed in the uploaded data
2562
            if (fileName != null) {
2563 1360 tao
2564 2098 jones
                try {
2565
                    //MetaCatUtil.debugMessage("Upload datafile " + docid
2566
                    // +"...", 10);
2567
                    //If document get lock data file grant
2568
                    if (DocumentImpl.getDataFileLockGrant(docid)) {
2569
                        // register the file in the database (which generates
2570
                        // an exception
2571
                        //if the docid is not acceptable or other untoward
2572
                        // things happen
2573
                        DocumentImpl.registerDocument(fileName, "BIN", docid,
2574 2259 sgarg
                                username, groupnames);
2575 1360 tao
2576 2098 jones
                        // Save the data file to disk using "docid" as the name
2577
                        dataDirectory.mkdirs();
2578
                        File newFile = new File(dataDirectory, docid);
2579
                        long size = filePart.writeTo(newFile);
2580 1360 tao
2581 2169 sgarg
                        EventLog.getInstance().log(request.getRemoteAddr(),
2582 2102 jones
                                username, docid, "upload");
2583 2098 jones
                        // Force replication this data file
2584
                        // To data file, "insert" and update is same
2585
                        // The fourth parameter is null. Because it is
2586
                        // notification server
2587
                        // and this method is in MetaCatServerlet. It is
2588
                        // original command,
2589
                        // not get force replication info from another metacat
2590
                        ForceReplicationHandler frh = new ForceReplicationHandler(
2591
                                docid, "insert", false, null);
2592 1360 tao
2593 2098 jones
                        // set content type and other response header fields
2594
                        // first
2595
                        out.println("<?xml version=\"1.0\"?>");
2596
                        out.println("<success>");
2597
                        out.println("<docid>" + docid + "</docid>");
2598
                        out.println("<size>" + size + "</size>");
2599
                        out.println("</success>");
2600
                    }
2601
2602
                } catch (Exception e) {
2603
                    out.println("<?xml version=\"1.0\"?>");
2604
                    out.println("<error>");
2605
                    out.println(e.getMessage());
2606
                    out.println("</error>");
2607
                }
2608
            } else {
2609
                // the field did not contain a file
2610
                out.println("<?xml version=\"1.0\"?>");
2611
                out.println("<error>");
2612
                out.println("The uploaded data did not contain a valid file.");
2613
                out.println("</error>");
2614
            }
2615
        } else {
2616
            // Error bcse docid missing or file missing
2617
            out.println("<?xml version=\"1.0\"?>");
2618
            out.println("<error>");
2619
            out.println("The uploaded data did not contain a valid docid "
2620
                    + "or valid file.");
2621
            out.println("</error>");
2622 798 jones
        }
2623 2098 jones
    }
2624 1360 tao
2625 2098 jones
    /*
2626
     * A method to handle set access action
2627
     */
2628
    private void handleSetAccessAction(PrintWriter out, Hashtable params,
2629
            String username)
2630 1041 tao
    {
2631 2098 jones
        String[] docList = null;
2632
        String[] principalList = null;
2633
        String[] permissionList = null;
2634
        String[] permTypeList = null;
2635
        String[] permOrderList = null;
2636
        String permission = null;
2637
        String permType = null;
2638
        String permOrder = null;
2639
        Vector errorList = new Vector();
2640
        String error = null;
2641
        Vector successList = new Vector();
2642
        String success = null;
2643 1716 berkley
2644 2098 jones
        // Get parameters
2645
        if (params.containsKey("docid")) {
2646
            docList = (String[]) params.get("docid");
2647
        }
2648
        if (params.containsKey("principal")) {
2649
            principalList = (String[]) params.get("principal");
2650
        }
2651
        if (params.containsKey("permission")) {
2652
            permissionList = (String[]) params.get("permission");
2653 1716 berkley
2654 2098 jones
        }
2655
        if (params.containsKey("permType")) {
2656
            permTypeList = (String[]) params.get("permType");
2657 1716 berkley
2658 2098 jones
        }
2659
        if (params.containsKey("permOrder")) {
2660
            permOrderList = (String[]) params.get("permOrder");
2661 1716 berkley
2662 2098 jones
        }
2663 1716 berkley
2664 2098 jones
        // Make sure the parameter is not null
2665
        if (docList == null || principalList == null || permTypeList == null
2666
                || permissionList == null) {
2667
            error = "Please check your parameter list, it should look like: "
2668
                    + "?action=setaccess&docid=pipeline.1.1&principal=public"
2669
                    + "&permission=read&permType=allow&permOrder=allowFirst";
2670
            errorList.addElement(error);
2671
            outputResponse(successList, errorList, out);
2672
            return;
2673
        }
2674 1716 berkley
2675 2098 jones
        // Only select first element for permission, type and order
2676
        permission = permissionList[0];
2677
        permType = permTypeList[0];
2678
        if (permOrderList != null) {
2679
            permOrder = permOrderList[0];
2680
        }
2681 1716 berkley
2682 2098 jones
        // Get package doctype set
2683
        Vector packageSet = MetaCatUtil.getOptionList(MetaCatUtil
2684
                .getOption("packagedoctypeset"));
2685
        //debug
2686
        if (packageSet != null) {
2687
            for (int i = 0; i < packageSet.size(); i++) {
2688
                MetaCatUtil.debugMessage("doctype in package set: "
2689
                        + (String) packageSet.elementAt(i), 34);
2690
            }
2691
        }
2692 1716 berkley
2693 2098 jones
        // handle every accessionNumber
2694
        for (int i = 0; i < docList.length; i++) {
2695
            String accessionNumber = docList[i];
2696
            String owner = null;
2697
            String publicId = null;
2698
            // Get document owner and public id
2699
            try {
2700
                owner = getFieldValueForDoc(accessionNumber, "user_owner");
2701
                publicId = getFieldValueForDoc(accessionNumber, "doctype");
2702
            } catch (Exception e) {
2703
                MetaCatUtil.debugMessage("Error in handleSetAccessAction: "
2704
                        + e.getMessage(), 30);
2705
                error = "Error in set access control for document - "
2706
                        + accessionNumber + e.getMessage();
2707
                errorList.addElement(error);
2708
                continue;
2709
            }
2710
            //check if user is the owner. Only owner can do owner
2711
            if (username == null || owner == null || !username.equals(owner)) {
2712
                error = "User - " + username
2713
                        + " does not have permission to set "
2714
                        + "access control for docid - " + accessionNumber;
2715
                errorList.addElement(error);
2716
                continue;
2717
            }
2718 1716 berkley
2719 2098 jones
            // If docid publicid is BIN data file or other beta4, 6 package
2720
            // document
2721
            // we could not do set access control. Because we don't want
2722
            // inconsistent
2723
            // to its access docuemnt
2724
            if (publicId != null && packageSet != null
2725
                    && packageSet.contains(publicId)) {
2726
                error = "Could not set access control to document "
2727
                        + accessionNumber
2728
                        + "because it is in a pakcage and it has a access file for it";
2729
                errorList.addElement(error);
2730
                continue;
2731
            }
2732 1716 berkley
2733 2098 jones
            // for every principle
2734
            for (int j = 0; j < principalList.length; j++) {
2735
                String principal = principalList[j];
2736
                try {
2737
                    //insert permission
2738
                    AccessControlForSingleFile accessControl = new AccessControlForSingleFile(
2739
                            accessionNumber, principal, permission, permType,
2740
                            permOrder);
2741
                    accessControl.insertPermissions();
2742
                    success = "Set access control to document "
2743
                            + accessionNumber + " successfully";
2744
                    successList.addElement(success);
2745
                } catch (Exception ee) {
2746
                    MetaCatUtil.debugMessage(
2747
                            "Erorr in handleSetAccessAction2: "
2748
                                    + ee.getMessage(), 30);
2749
                    error = "Faild to set access control for document "
2750
                            + accessionNumber + " because " + ee.getMessage();
2751
                    errorList.addElement(error);
2752
                    continue;
2753
                }
2754
            }
2755 1369 tao
        }
2756 2098 jones
        outputResponse(successList, errorList, out);
2757
    }
2758 1716 berkley
2759 2098 jones
    /*
2760
     * A method try to determin a docid's public id, if couldn't find null will
2761
     * be returned.
2762
     */
2763
    private String getFieldValueForDoc(String accessionNumber, String fieldName)
2764
            throws Exception
2765 1369 tao
    {
2766 2098 jones
        if (accessionNumber == null || accessionNumber.equals("")
2767
                || fieldName == null || fieldName.equals("")) { throw new Exception(
2768
                "Docid or field name was not specified"); }
2769 1716 berkley
2770 2098 jones
        PreparedStatement pstmt = null;
2771
        ResultSet rs = null;
2772
        String fieldValue = null;
2773
        String docId = null;
2774
        DBConnection conn = null;
2775
        int serialNumber = -1;
2776 1716 berkley
2777 2098 jones
        // get rid of revision if access number has
2778
        docId = MetaCatUtil.getDocIdFromString(accessionNumber);
2779
        try {
2780
            //check out DBConnection
2781
            conn = DBConnectionPool
2782
                    .getDBConnection("MetaCatServlet.getPublicIdForDoc");
2783
            serialNumber = conn.getCheckOutSerialNumber();
2784
            pstmt = conn.prepareStatement("SELECT " + fieldName
2785
                    + " FROM xml_documents " + "WHERE docid = ? ");
2786 1716 berkley
2787 2098 jones
            pstmt.setString(1, docId);
2788
            pstmt.execute();
2789
            rs = pstmt.getResultSet();
2790
            boolean hasRow = rs.next();
2791
            int perm = 0;
2792
            if (hasRow) {
2793
                fieldValue = rs.getString(1);
2794
            } else {
2795
                throw new Exception("Could not find document: "
2796
                        + accessionNumber);
2797
            }
2798
        } catch (Exception e) {
2799
            MetaCatUtil.debugMessage(
2800
                    "Exception in MetacatServlet.getPublicIdForDoc: "
2801
                            + e.getMessage(), 30);
2802
            throw e;
2803
        } finally {
2804
            try {
2805
                rs.close();
2806
                pstmt.close();
2807 1716 berkley
2808 2098 jones
            } finally {
2809
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2810
            }
2811
        }
2812
        return fieldValue;
2813 1369 tao
    }
2814 1716 berkley
2815 2098 jones
    /*
2816 2312 jones
     * Get the list of documents from the database and return the list in an
2817
     * Vector of identifiers.
2818
     *
2819
     * @ returns the array of identifiers
2820
     */
2821
    private Vector getDocumentList() throws SQLException
2822
    {
2823
        Vector docList = new Vector();
2824
        PreparedStatement pstmt = null;
2825
        ResultSet rs = null;
2826
        DBConnection conn = null;
2827
        int serialNumber = -1;
2828
2829
        try {
2830
            //check out DBConnection
2831
            conn = DBConnectionPool
2832
                    .getDBConnection("MetaCatServlet.getDocumentList");
2833
            serialNumber = conn.getCheckOutSerialNumber();
2834
            pstmt = conn.prepareStatement("SELECT docid, rev"
2835
                    + " FROM xml_documents ");
2836
            pstmt.execute();
2837
            rs = pstmt.getResultSet();
2838
            while (rs.next()) {
2839
                String docid = rs.getString(1);
2840
                String rev = rs.getString(2);
2841
                docList.add(docid + "." + rev);
2842
            }
2843
        } catch (SQLException e) {
2844
            MetaCatUtil.debugMessage(
2845
                    "Exception in MetacatServlet.getDocumentList: "
2846
                            + e.getMessage(), 30);
2847
            throw e;
2848
        } finally {
2849
            try {
2850
                rs.close();
2851
                pstmt.close();
2852
2853
            } catch (SQLException se) {
2854
                MetaCatUtil.debugMessage(
2855
                    "Exception in MetacatServlet.getDocumentList: "
2856
                            + se.getMessage(), 30);
2857
                throw se;
2858
            } finally {
2859
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2860
            }
2861
        }
2862
        return docList;
2863
    }
2864
2865
    /*
2866 2098 jones
     * A method to output setAccess action result
2867
     */
2868
    private void outputResponse(Vector successList, Vector errorList,
2869
            PrintWriter out)
2870 1369 tao
    {
2871 2098 jones
        boolean error = false;
2872
        boolean success = false;
2873
        // Output prolog
2874
        out.println(PROLOG);
2875
        // output success message
2876
        if (successList != null) {
2877
            for (int i = 0; i < successList.size(); i++) {
2878
                out.println(SUCCESS);
2879
                out.println((String) successList.elementAt(i));
2880
                out.println(SUCCESSCLOSE);
2881
                success = true;
2882
            }
2883
        }
2884
        // output error message
2885
        if (errorList != null) {
2886
            for (int i = 0; i < errorList.size(); i++) {
2887
                out.println(ERROR);
2888
                out.println((String) errorList.elementAt(i));
2889
                out.println(ERRORCLOSE);
2890
                error = true;
2891
            }
2892
        }
2893 1716 berkley
2894 2098 jones
        // if no error and no success info, send a error that nothing happened
2895
        if (!error && !success) {
2896
            out.println(ERROR);
2897
            out.println("Nothing happend for setaccess action");
2898
            out.println(ERRORCLOSE);
2899
        }
2900 1369 tao
    }
2901 2582 tao
2902
    /**
2903
     * Method to get session table which store the session info
2904
     * @return
2905
     */
2906
    public static Hashtable getSessionHash()
2907
    {
2908
        return sessionHash;
2909
    }
2910 46 jones
}