Project

General

Profile

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

    
28
package edu.ucsb.nceas.metacat;
29

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

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

    
61
import org.apache.log4j.Logger;
62
import org.apache.log4j.PropertyConfigurator;
63
import org.ecoinformatics.eml.EMLParser;
64

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

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

    
72
/**
73
 * A metadata catalog server implemented as a Java Servlet
74
 *
75
 * <p>
76
 * Valid parameters are: <br>
77
 * action=query -- query the values of all elements and attributes and return a
78
 * result set of nodes <br>
79
 * action=squery -- structured query (see pathquery.dtd) <br>
80
 * action= -- export a zip format for data packadge <br>
81
 * action=read -- read any metadata/data file from Metacat and from Internet
82
 * <br>
83
 * action=insert -- insert an XML document into the database store <br>
84
 * action=update -- update an XML document that is in the database store <br>
85
 * action=delete -- delete an XML document from the database store <br>
86
 * action=validate -- vallidate the xml contained in valtext <br>
87
 * doctype -- document type list returned by the query (publicID) <br>
88
 * qformat=xml -- display resultset from query in XML <br>
89
 * qformat=html -- display resultset from query in HTML <br>
90
 * qformat=zip -- zip resultset from query <br>
91
 * docid=34 -- display the document with the document ID number 34 <br>
92
 * doctext -- XML text of the document to load into the database <br>
93
 * acltext -- XML access text for a document to load into the database <br>
94
 * dtdtext -- XML DTD text for a new DTD to load into Metacat XML Catalog <br>
95
 * query -- actual query text (to go with 'action=query' or 'action=squery')
96
 * <br>
97
 * valtext -- XML text to be validated <br>
98
 * action=getaccesscontrol -- retrieve acl info for Metacat document <br>
99
 * action=getdoctypes -- retrieve all doctypes (publicID) <br>
100
 * action=getdtdschema -- retrieve a DTD or Schema file <br>
101
 * action=getdataguide -- retrieve a Data Guide <br>
102
 * action=getprincipals -- retrieve a list of principals in XML <br>
103
 * datadoc -- data document name (id) <br>
104
 * action=getlog -- get a report of events that have occurred in the system<br>
105
 * ipAddress --  filter on one or more IP addresses<br>
106
 * principal -- filter on one or more principals (LDAP DN syntax)<br>
107
 * docid -- filter on one or more document identifiers (with revision)<br>
108
 * event -- filter on event type (e.g., read, insert, update, delete)<br>
109
 * start -- filter out events before the start date-time<br>
110
 * end -- filter out events before the end date-time<br>
111
 * <p>
112
 * The particular combination of parameters that are valid for each particular
113
 * action value is quite specific. This documentation will be reorganized to
114
 * reflect this information.
115
 */
116
public class MetaCatServlet extends HttpServlet
117
{
118
    private static Hashtable sessionHash = new Hashtable();
119
    private Timer timer = null;
120
    
121
    // Constants -- these should be final in a servlet
122
    private static final String PROLOG = "<?xml version=\"1.0\"?>";
123
    private static final String SUCCESS = "<success>";
124
    private static final String SUCCESSCLOSE = "</success>";
125
    private static final String ERROR = "<error>";
126
    private static final String ERRORCLOSE = "</error>";
127
    public static final String SCHEMALOCATIONKEYWORD = ":schemaLocation";
128
    public static final String NONAMESPACELOCATION = ":noNamespaceSchemaLocation";
129
    public static final String NAMESPACEKEYWORD = "xmlns";
130
    public static final String EML2KEYWORD = ":eml";
131
    public static final String XMLFORMAT = "xml";
132
    private static final String CONFIG_DIR = "WEB-INF";
133
    private static final String CONFIG_NAME = "metacat.properties"; 
134
    
135
    /**
136
     * Initialize the servlet by creating appropriate database connections
137
     */
138
    public void init(ServletConfig config) throws ServletException
139
    {
140
        try {
141
            super.init(config);
142
            ServletContext context = config.getServletContext();
143

    
144
            // Initialize the properties file for our options
145
            String dirPath = context.getRealPath(CONFIG_DIR);
146
            File propertyFile = new File(dirPath, CONFIG_NAME);
147

    
148
            String LOG_CONFIG_NAME = dirPath + "/log4j.properties";
149
            PropertyConfigurator.configureAndWatch(LOG_CONFIG_NAME);
150
            
151
            Options options = null;
152
            try {
153
                options = Options.initialize(propertyFile);
154
                MetaCatUtil.printMessage("Options configured: "
155
                        + options.getOption("configured"));
156
            } catch (IOException ioe) {
157
                Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
158
                logMetacat.error("Error in loading options: "
159
                        + ioe.getMessage());
160
            }
161

    
162
            MetaCatUtil util = new MetaCatUtil();
163

    
164
            //initialize DBConnection pool
165
            DBConnectionPool connPool = DBConnectionPool.getInstance();
166
            
167
            // Index the paths specified in the metacat.properties
168
            checkIndexPaths();
169

    
170
            // initiate the indexing Queue
171
            IndexingQueue.getInstance();
172
            
173
            // start the IndexingThread if indexingTimerTaskTime more than 0. 
174
            // It will index all the documents not yet indexed in the database             
175
            int indexingTimerTaskTime = Integer.parseInt(MetaCatUtil.getOption("indexingTimerTaskTime"));
176
            if(indexingTimerTaskTime > 0){
177
            	timer = new Timer();
178
            	timer.schedule(new IndexingTimerTask(), 0, indexingTimerTaskTime);
179
            }
180
            
181
            MetaCatUtil.printMessage("Metacat (" + Version.getVersion()
182
                               + ") initialized.");
183

    
184
        } catch (ServletException ex) {
185
            throw ex;
186
        } catch (SQLException e) {
187
            Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
188
            logMetacat.error("Error in MetacatServlet.init: "
189
                    + e.getMessage());
190
        }
191
    }
192

    
193
    /**
194
     * Close all db connections from the pool
195
     */
196
    public void destroy()
197
    {
198
        // Close all db connection
199
        System.out.println("Destroying MetacatServlet");
200
        timer.cancel();
201
        DBConnectionPool.release();
202
    }
203

    
204
    /** Handle "GET" method requests from HTTP clients */
205
    public void doGet(HttpServletRequest request, HttpServletResponse response)
206
            throws ServletException, IOException
207
    {
208

    
209
        // Process the data and send back the response
210
        handleGetOrPost(request, response);
211
    }
212

    
213
    /** Handle "POST" method requests from HTTP clients */
214
    public void doPost(HttpServletRequest request, HttpServletResponse response)
215
            throws ServletException, IOException
216
    {
217

    
218
        // Process the data and send back the response
219
        handleGetOrPost(request, response);
220
    }
221

    
222
    /**
223
     * Index the paths specified in the metacat.properties
224
     */
225
    private void checkIndexPaths() {
226
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
227
        MetaCatUtil.pathsForIndexing
228
            = MetaCatUtil.getOptionList(MetaCatUtil.getOption("indexPaths"));
229
    
230
        if (MetaCatUtil.pathsForIndexing != null) {
231
    
232
            MetaCatUtil.printMessage("Indexing paths specified in metacat.properties....");
233
    
234
            DBConnection conn = null;
235
            int serialNumber = -1;
236
            PreparedStatement pstmt = null;
237
            PreparedStatement pstmt1 = null;
238
            ResultSet rs = null;
239
    
240
            for (int i = 0; i < MetaCatUtil.pathsForIndexing.size(); i++) {
241
                logMetacat.debug("Checking if '"
242
                           + (String) MetaCatUtil.pathsForIndexing.elementAt(i)
243
                           + "' is indexed.... ");
244
    
245
                try {
246
                    //check out DBConnection
247
                    conn = DBConnectionPool.
248
                        getDBConnection("MetaCatServlet.checkIndexPaths");
249
                    serialNumber = conn.getCheckOutSerialNumber();
250
    
251
                    pstmt = conn.prepareStatement(
252
                        "SELECT * FROM xml_path_index " + "WHERE path = ?");
253
                    pstmt.setString(1, (String) MetaCatUtil.pathsForIndexing
254
                                    .elementAt(i));
255
    
256
                    pstmt.execute();
257
                    rs = pstmt.getResultSet();
258
    
259
                    if (!rs.next()) {
260
                        logMetacat.debug(".....not indexed yet.");
261
                        rs.close();
262
                        pstmt.close();
263
                        conn.increaseUsageCount(1);
264
    
265
                        logMetacat.debug(
266
                              "Inserting following path in xml_path_index: "
267
                              + (String)MetaCatUtil.pathsForIndexing
268
                                                   .elementAt(i));
269
   			if(((String)MetaCatUtil.pathsForIndexing.elementAt(i)).indexOf("@")<0){ 
270
                        	pstmt = conn.prepareStatement("SELECT DISTINCT n.docid, "
271
                              		+ "n.nodedata, n.nodedatanumerical, n.parentnodeid"
272
                              		+ " FROM xml_nodes n, xml_index i WHERE"
273
                              		+ " i.path = ? and n.parentnodeid=i.nodeid and"
274
                              		+ " n.nodetype LIKE 'TEXT' order by n.parentnodeid");
275
			} else {
276
                        	pstmt = conn.prepareStatement("SELECT DISTINCT n.docid, "
277
                              		+ "n.nodedata, n.nodedatanumerical, n.parentnodeid"
278
                              		+ " FROM xml_nodes n, xml_index i WHERE"
279
                              		+ " i.path = ? and n.nodeid=i.nodeid and"
280
                              		+ " n.nodetype LIKE 'ATTRIBUTE' order by n.parentnodeid");
281
			}
282
                        pstmt.setString(1, (String) MetaCatUtil.
283
                                        pathsForIndexing.elementAt(i));
284
                        pstmt.execute();
285
                        rs = pstmt.getResultSet();
286
    
287
                        int count = 0;
288
                        logMetacat.debug(
289
                                       "Executed the select statement for: "
290
                                       + (String) MetaCatUtil.pathsForIndexing
291
                                         .elementAt(i));
292
    
293
                        try {
294
                            while (rs.next()) {
295
    
296
                                String docid = rs.getString(1);
297
                                String nodedata = rs.getString(2);
298
                                float nodedatanumerical = rs.getFloat(3);
299
                                int parentnodeid = rs.getInt(4);
300
    
301
                                if (!nodedata.trim().equals("")) {
302
                                    pstmt1 = conn.prepareStatement(
303
                                        "INSERT INTO xml_path_index"
304
                                        + " (docid, path, nodedata, "
305
                                        + "nodedatanumerical, parentnodeid)"
306
                                        + " VALUES (?, ?, ?, ?, ?)");
307
    
308
                                    pstmt1.setString(1, docid);
309
                                    pstmt1.setString(2, (String) MetaCatUtil.
310
                                                pathsForIndexing.elementAt(i));
311
                                    pstmt1.setString(3, nodedata);
312
                                    pstmt1.setFloat(4, nodedatanumerical);
313
                                    pstmt1.setInt(5, parentnodeid);
314
    
315
                                    pstmt1.execute();
316
                                    pstmt1.close();
317
    
318
                                    count++;
319
    
320
                                }
321
                            }
322
                        }
323
                        catch (Exception e) {
324
                            System.out.println("Exception:" + e.getMessage());
325
                            e.printStackTrace();
326
                        }
327
    
328
                        rs.close();
329
                        pstmt.close();
330
                        conn.increaseUsageCount(1);
331
    
332
                        logMetacat.info("Indexed " + count
333
                                + " records from xml_nodes for '"
334
                                + (String) MetaCatUtil.pathsForIndexing.elementAt(i)
335
                                + "'");
336
    
337
                    } else {
338
                    	logMetacat.debug(".....already indexed.");
339
                    }
340
    
341
                    rs.close();
342
                    pstmt.close();
343
                    conn.increaseUsageCount(1);
344
    
345
                } catch (Exception e) {
346
                    logMetacat.error("Error in MetaCatServlet.checkIndexPaths: "
347
                                             + e.getMessage());
348
                }finally {
349
                    //check in DBonnection
350
                    DBConnectionPool.returnDBConnection(conn, serialNumber);
351
                }
352
    
353
    
354
            }
355
    
356
            MetaCatUtil.printMessage("Path Indexing Completed");
357
        }
358
    }    
359

    
360
    /**
361
     * Control servlet response depending on the action parameter specified
362
     */
363
    private void handleGetOrPost(HttpServletRequest request,
364
            HttpServletResponse response) throws ServletException, IOException
365
    {
366
        MetaCatUtil util = new MetaCatUtil();
367
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
368
        
369
        /*
370
         * logMetacat.debug("Connection pool size: "
371
         * +connPool.getSizeOfDBConnectionPool(),10);
372
         * logMetacat.debug("Free DBConnection number: "
373
         */
374
        //If all DBConnection in the pool are free and DBConnection pool
375
        //size is greater than initial value, shrink the connection pool
376
        //size to initial value
377
        DBConnectionPool.shrinkDBConnectionPoolSize();
378

    
379
        //Debug message to print out the method which have a busy DBConnection
380
        try {
381
            DBConnectionPool pool = DBConnectionPool.getInstance();
382
            pool.printMethodNameHavingBusyDBConnection();
383
        } catch (SQLException e) {
384
            logMetacat.error("Error in MetacatServlet.handleGetOrPost: "
385
                    + e.getMessage());
386
            e.printStackTrace();
387
        }
388

    
389
        String ctype = request.getContentType();
390
        if (ctype != null && ctype.startsWith("multipart/form-data")) {
391
            handleMultipartForm(request, response);
392
        } else {
393

    
394
            String name = null;
395
            String[] value = null;
396
            String[] docid = new String[3];
397
            Hashtable params = new Hashtable();
398
            Enumeration paramlist = request.getParameterNames();
399

    
400
            while (paramlist.hasMoreElements()) {
401

    
402
                name = (String) paramlist.nextElement();
403
                value = request.getParameterValues(name);
404

    
405
                // Decode the docid and mouse click information
406
                if (name.endsWith(".y")) {
407
                    docid[0] = name.substring(0, name.length() - 2);
408
                    params.put("docid", docid);
409
                    name = "ypos";
410
                }
411
                if (name.endsWith(".x")) {
412
                    name = "xpos";
413
                }
414

    
415
                params.put(name, value);
416
            }
417

    
418
            //handle param is emptpy
419
            if (params.isEmpty() || params == null) { return; }
420

    
421
            //if the user clicked on the input images, decode which image
422
            //was clicked then set the action.
423
            if(params.get("action") == null){
424
                PrintWriter out = response.getWriter();
425
                response.setContentType("text/xml");
426
                out.println("<?xml version=\"1.0\"?>");
427
                out.println("<error>");
428
                out.println("Action not specified");
429
                out.println("</error>");
430
                out.close();
431
                return;
432
            }
433

    
434
            String action = ((String[]) params.get("action"))[0];
435
            logMetacat.info("Action is: " + action);
436

    
437
            // This block handles session management for the servlet
438
            // by looking up the current session information for all actions
439
            // other than "login" and "logout"
440
            String username = null;
441
            String password = null;
442
            String[] groupnames = null;
443
            String sess_id = null;
444
            name = null;
445
            
446
            // handle login action
447
            if (action.equals("login")) {
448
                PrintWriter out = response.getWriter();
449
                handleLoginAction(out, params, request, response);
450
                out.close();
451

    
452
                // handle logout action
453
            } else if (action.equals("logout")) {
454
                PrintWriter out = response.getWriter();
455
                handleLogoutAction(out, params, request, response);
456
                out.close();
457

    
458
                // handle shrink DBConnection request
459
            } else if (action.equals("shrink")) {
460
                PrintWriter out = response.getWriter();
461
                boolean success = false;
462
                //If all DBConnection in the pool are free and DBConnection
463
                // pool
464
                //size is greater than initial value, shrink the connection
465
                // pool
466
                //size to initial value
467
                success = DBConnectionPool.shrinkConnectionPoolSize();
468
                if (success) {
469
                    //if successfully shrink the pool size to initial value
470
                    out.println("DBConnection Pool shrunk successfully.");
471
                }//if
472
                else {
473
                    out.println("DBConnection pool not shrunk successfully.");
474
                }
475
                //close out put
476
                out.close();
477

    
478
                // aware of session expiration on every request
479
            } else {
480
                HttpSession sess = request.getSession(true);
481
                if (sess.isNew() && !params.containsKey("sessionid")) {
482
                    // session expired or has not been stored b/w user requests
483
                    logMetacat.info(
484
                            "The session is new or no sessionid is assigned. The user is public");
485
                    username = "public";
486
                    sess.setAttribute("username", username);
487
                } else {
488
                    logMetacat.info("The session is either old or "
489
                            + "has sessionid parameter");
490
                    try {
491
                        if (params.containsKey("sessionid")) {
492
                            sess_id = ((String[]) params.get("sessionid"))[0];
493
                            logMetacat.info("in has sessionid "
494
                                    + sess_id);
495
                            if (sessionHash.containsKey(sess_id)) {
496
                                logMetacat.info("find the id "
497
                                        + sess_id + " in hash table");
498
                                sess = (HttpSession) sessionHash.get(sess_id);
499
                            }
500
                        } else {
501
                            // we already store the session in login, so we
502
                            // don't need here
503
                            /*
504
                             * logMetacat.info("in no sessionid
505
                             * parameter ", 40); sess_id =
506
                             * (String)sess.getId();
507
                             * logMetacat.info("storing the session id "
508
                             * + sess_id + " which has username " +
509
                             * sess.getAttribute("username") + " into session
510
                             * hash in handleGetOrPost method", 35);
511
                             */
512
                        }
513
                    } catch (IllegalStateException ise) {
514
                        logMetacat.error(
515
                                "Error in handleGetOrPost: this shouldn't "
516
                                + "happen: the session should be valid: "
517
                                + ise.getMessage());
518
                    }
519

    
520
                    username = (String) sess.getAttribute("username");
521
                    logMetacat.info("The user name from session is: "
522
                            + username);
523
                    password = (String) sess.getAttribute("password");
524
                    groupnames = (String[]) sess.getAttribute("groupnames");
525
                    name = (String) sess.getAttribute("name");
526
                }
527

    
528
                //make user user username should be public
529
                if (username == null || (username.trim().equals(""))) {
530
                    username = "public";
531
                }
532
                logMetacat.info("The user is : " + username);
533
            }
534
            // Now that we know the session is valid, we can delegate the
535
            // request
536
            // to a particular action handler
537
            if (action.equals("query")) {
538
                PrintWriter out = response.getWriter();
539
                handleQuery(out, params, response, username, groupnames,
540
                        sess_id);
541
                out.close();
542
            } else if (action.equals("squery")) {
543
                PrintWriter out = response.getWriter();
544
                if (params.containsKey("query")) {
545
                    handleSQuery(out, params, response, username, groupnames,
546
                            sess_id);
547
                    out.close();
548
                } else {
549
                    out.println(
550
                            "Illegal action squery without \"query\" parameter");
551
                    out.close();
552
                }
553
            } else if (action.equals("export")) {
554

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

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

    
717
    // LOGIN & LOGOUT SECTION
718
    /**
719
     * Handle the login request. Create a new session object. Do user
720
     * authentication through the session.
721
     */
722
    private void handleLoginAction(PrintWriter out, Hashtable params,
723
            HttpServletRequest request, HttpServletResponse response)
724
    {
725
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
726
        AuthSession sess = null;
727

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

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

    
746
        String un = ((String[]) params.get("username"))[0];
747
        logMetacat.info("user " + un + " is trying to login");
748
        String pw = ((String[]) params.get("password"))[0];
749

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

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

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

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

    
788
                logMetacat.error(
789
                        "Error in MetaCatServlet.handleLoginAction: "
790
                                + e.getMessage());
791
            }
792
        }
793
    }
794

    
795
    /**
796
     * Handle the logout request. Close the connection.
797
     */
798
    private void handleLogoutAction(PrintWriter out, Hashtable params,
799
            HttpServletRequest request, HttpServletResponse response)
800
    {
801
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
802
        String qformat = "xml";
803
        if(params.get("qformat") != null){
804
            qformat = ((String[]) params.get("qformat"))[0];
805
        }
806

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

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

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

    
845
    // END OF LOGIN & LOGOUT SECTION
846

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

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

    
895
        //handleSQuery(out, params, response,user, groups, sessionid);
896
    }
897

    
898
    // END OF SQUERY & QUERY SECTION
899

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

    
920
        String[] docs = new String[10];
921
        String docId = "";
922

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

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

    
984
            logMetacat.error(
985
                    "Error in MetacatServlet.handleExportAction: "
986
                            + e.getMessage());
987
            e.printStackTrace(System.out);
988

    
989
        }
990

    
991
    }
992

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

    
1013
        try {
1014
            // read the params
1015
            if (params.containsKey("inlinedataid")) {
1016
                docs = (String[]) params.get("inlinedataid");
1017
            }
1018
            // Get the docid
1019
            inlineDataId = docs[0];
1020
            // Make sure the client specify docid
1021
            if (inlineDataId == null || inlineDataId.equals("")) {
1022
                throw new Exception("You didn't specify requested inlinedataid"); }
1023

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

    
1051
                }//if
1052
              }//try
1053
              catch (Exception e)
1054
              {
1055
                throw e;
1056
              }//catch
1057
            }//else
1058

    
1059
            // Get output stream
1060
            out = response.getOutputStream();
1061
            // read the inline data from the file
1062
            String inlinePath = MetaCatUtil.getOption("inlinedatafilepath");
1063
            File lineData = new File(inlinePath, inlineDataId);
1064
            FileInputStream input = new FileInputStream(lineData);
1065
            byte[] buffer = new byte[4 * 1024];
1066
            int bytes = input.read(buffer);
1067
            while (bytes != -1) {
1068
                out.write(buffer, 0, bytes);
1069
                bytes = input.read(buffer);
1070
            }
1071
            out.close();
1072

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

    
1105
    /*
1106
     * Get the nodeid from xml_nodes for the inlinedataid
1107
     */
1108
    private long getInlineDataNodeId(String inLineDataId, String docId)
1109
            throws SQLException
1110
    {
1111
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1112
        long nodeId = 0;
1113
        String INLINE = "inline";
1114
        boolean hasRow;
1115
        PreparedStatement pStmt = null;
1116
        DBConnection conn = null;
1117
        int serialNumber = -1;
1118
        String sql = "SELECT nodeid FROM xml_nodes WHERE docid=? AND nodedata=? "
1119
                + "AND nodetype='TEXT' AND parentnodeid IN "
1120
                + "(SELECT nodeid FROM xml_nodes WHERE docid=? AND "
1121
                + "nodetype='ELEMENT' AND nodename='" + INLINE + "')";
1122

    
1123
        try {
1124
            //check out DBConnection
1125
            conn = DBConnectionPool
1126
                    .getDBConnection("AccessControlList.isAllowFirst");
1127
            serialNumber = conn.getCheckOutSerialNumber();
1128

    
1129
            pStmt = conn.prepareStatement(sql);
1130
            //bind value
1131
            pStmt.setString(1, docId);//docid
1132
            pStmt.setString(2, inLineDataId);//inlinedataid
1133
            pStmt.setString(3, docId);
1134
            // excute query
1135
            pStmt.execute();
1136
            ResultSet rs = pStmt.getResultSet();
1137
            hasRow = rs.next();
1138
            // get result
1139
            if (hasRow) {
1140
                nodeId = rs.getLong(1);
1141
            }//if
1142

    
1143
        } catch (SQLException e) {
1144
            throw e;
1145
        } finally {
1146
            try {
1147
                pStmt.close();
1148
            } finally {
1149
                DBConnectionPool.returnDBConnection(conn, serialNumber);
1150
            }
1151
        }
1152
        logMetacat.debug("The nodeid for inlinedataid " + inLineDataId
1153
                + " is: " + nodeId);
1154
        return nodeId;
1155
    }
1156

    
1157
    /**
1158
     * Handle the "read" request of metadata/data files from Metacat or any
1159
     * files from Internet; transformed metadata XML document into HTML
1160
     * presentation if requested; zip files when more than one were requested.
1161
     *
1162
     * @param params the Hashtable of HTTP request parameters
1163
     * @param request the HTTP request object linked to the client
1164
     * @param response the HTTP response object linked to the client
1165
     * @param user the username sent the request
1166
     * @param groups the user's groupnames
1167
     */
1168
    private void handleReadAction(Hashtable params, HttpServletRequest request,
1169
            HttpServletResponse response, String user, String passWord,
1170
            String[] groups)
1171
    {
1172
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1173
        ServletOutputStream out = null;
1174
        ZipOutputStream zout = null;
1175
        PrintWriter pw = null;
1176
        boolean zip = false;
1177
        boolean withInlineData = true;
1178

    
1179
        try {
1180
            String[] docs = new String[0];
1181
            String docid = "";
1182
            String qformat = "";
1183
            String abstrpath = null;
1184

    
1185
            // read the params
1186
            if (params.containsKey("docid")) {
1187
                docs = (String[]) params.get("docid");
1188
            }
1189
            if (params.containsKey("qformat")) {
1190
                qformat = ((String[]) params.get("qformat"))[0];
1191
            }
1192
            // the param for only metadata (eml)
1193
            // we don't support read a eml document without inline data now.
1194
            /*if (params.containsKey("inlinedata")) {
1195

    
1196
                String inlineData = ((String[]) params.get("inlinedata"))[0];
1197
                if (inlineData.equalsIgnoreCase("false")) {
1198
                    withInlineData = false;
1199
                }
1200
            }*/
1201
            if ((docs.length > 1) || qformat.equals("zip")) {
1202
                zip = true;
1203
                out = response.getOutputStream();
1204
                response.setContentType("application/zip"); //MIME type
1205
                zout = new ZipOutputStream(out);
1206
            }
1207
            // go through the list of docs to read
1208
            for (int i = 0; i < docs.length; i++) {
1209
                try {
1210

    
1211
                    URL murl = new URL(docs[i]);
1212
                    Hashtable murlQueryStr = MetaCatUtil.parseQuery(
1213
                            murl.getQuery());
1214
                    // case docid="http://.../?docid=aaa"
1215
                    // or docid="metacat://.../?docid=bbb"
1216
                    if (murlQueryStr.containsKey("docid")) {
1217
                        // get only docid, eliminate the rest
1218
                        docid = (String) murlQueryStr.get("docid");
1219
                        if (zip) {
1220
                            addDocToZip(request, docid, zout, user, groups);
1221
                        } else {
1222
                            readFromMetacat(request, response, docid, qformat,
1223
                                    abstrpath, user, groups, zip, zout,
1224
                                    withInlineData, params);
1225
                        }
1226

    
1227
                        // case docid="http://.../filename"
1228
                    } else {
1229
                        docid = docs[i];
1230
                        if (zip) {
1231
                            addDocToZip(request, docid, zout, user, groups);
1232
                        } else {
1233
                            readFromURLConnection(response, docid);
1234
                        }
1235
                    }
1236

    
1237
                } catch (MalformedURLException mue) {
1238
                    docid = docs[i];
1239
                    if (zip) {
1240
                        addDocToZip(request, docid, zout, user, groups);
1241
                    } else {
1242
                        readFromMetacat(request, response, docid, qformat,
1243
                                abstrpath, user, groups, zip, zout,
1244
                                withInlineData, params);
1245
                    }
1246
                }
1247
            }
1248

    
1249
            if (zip) {
1250
                zout.finish(); //terminate the zip file
1251
                zout.close(); //close the zip stream
1252
            }
1253

    
1254
        } catch (McdbDocNotFoundException notFoundE) {
1255
            // To handle doc not found exception
1256
            // the docid which didn't be found
1257
            String notFoundDocId = notFoundE.getUnfoundDocId();
1258
            String notFoundRevision = notFoundE.getUnfoundRevision();
1259
            logMetacat.warn("Missed id: " + notFoundDocId);
1260
            logMetacat.warn("Missed rev: " + notFoundRevision);
1261
            try {
1262
                // read docid from remote server
1263
                readFromRemoteMetaCat(response, notFoundDocId,
1264
                        notFoundRevision, user, passWord, out, zip, zout);
1265
                // Close zout outputstream
1266
                if (zout != null) {
1267
                    zout.close();
1268
                }
1269
                // close output stream
1270
                if (out != null) {
1271
                    out.close();
1272
                }
1273

    
1274
            } catch (Exception exc) {
1275
                logMetacat.error(
1276
                        "Erorr in MetacatServlet.hanldReadAction: "
1277
                                + exc.getMessage());
1278
                try {
1279
                    if (out != null) {
1280
                        response.setContentType("text/xml");
1281
                        // Send back error message by printWriter
1282
                        pw = new PrintWriter(out);
1283
                        pw.println("<?xml version=\"1.0\"?>");
1284
                        pw.println("<error>");
1285
                        pw.println(notFoundE.getMessage());
1286
                        pw.println("</error>");
1287
                        pw.close();
1288
                        out.close();
1289

    
1290
                    } else {
1291
                        response.setContentType("text/xml"); //MIME type
1292
                        // Send back error message if out = null
1293
                        if (pw == null) {
1294
                            // If pw is null, open the respnose
1295
                            pw = response.getWriter();
1296
                        }
1297
                        pw.println("<?xml version=\"1.0\"?>");
1298
                        pw.println("<error>");
1299
                        pw.println(notFoundE.getMessage());
1300
                        pw.println("</error>");
1301
                        pw.close();
1302
                    }
1303
                    // close zout
1304
                    if (zout != null) {
1305
                        zout.close();
1306
                    }
1307
                } catch (IOException ie) {
1308
                    logMetacat.error("Problem with the servlet output "
1309
                            + "in MetacatServlet.handleReadAction: "
1310
                            + ie.getMessage());
1311
                }
1312
            }
1313
        } catch (Exception e) {
1314
            try {
1315

    
1316
                if (out != null) {
1317
                    response.setContentType("text/xml"); //MIME type
1318
                    pw = new PrintWriter(out);
1319
                    pw.println("<?xml version=\"1.0\"?>");
1320
                    pw.println("<error>");
1321
                    pw.println(e.getMessage());
1322
                    pw.println("</error>");
1323
                    pw.close();
1324
                    out.close();
1325
                } else {
1326
                    response.setContentType("text/xml"); //MIME type
1327
                    // Send back error message if out = null
1328
                    if (pw == null) {
1329
                        pw = response.getWriter();
1330
                    }
1331
                    pw.println("<?xml version=\"1.0\"?>");
1332
                    pw.println("<error>");
1333
                    pw.println(e.getMessage());
1334
                    pw.println("</error>");
1335
                    pw.close();
1336

    
1337
                }
1338
                // Close zip output stream
1339
                if (zout != null) {
1340
                    zout.close();
1341
                }
1342

    
1343
            } catch (IOException ioe) {
1344
                logMetacat.error("Problem with the servlet output "
1345
                        + "in MetacatServlet.handleReadAction: "
1346
                        + ioe.getMessage());
1347
                ioe.printStackTrace(System.out);
1348

    
1349
            }
1350

    
1351
            logMetacat.error(
1352
                    "Error in MetacatServlet.handleReadAction: "
1353
                            + e.getMessage());
1354
            //e.printStackTrace(System.out);
1355
        }
1356
    }
1357

    
1358
    /** read metadata or data from Metacat
1359
     */
1360
    private void readFromMetacat(HttpServletRequest request,
1361
            HttpServletResponse response, String docid, String qformat,
1362
            String abstrpath, String user, String[] groups, boolean zip,
1363
            ZipOutputStream zout, boolean withInlineData, Hashtable params)
1364
            throws ClassNotFoundException, IOException, SQLException,
1365
            McdbException, Exception
1366
    {
1367
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1368
        try {
1369
            
1370
            // here is hack for handle docid=john.10(in order to tell mike.jim.10.1
1371
            // mike.jim.10, we require to provide entire docid with rev). But
1372
            // some old client they only provide docid without rev, so we need
1373
            // to handle this suituation. First we will check how many
1374
            // seperator here, if only one, we will append the rev in xml_documents
1375
            // to the id.
1376
            docid = appendRev(docid);
1377
         
1378
            DocumentImpl doc = new DocumentImpl(docid);
1379

    
1380
            //check the permission for read
1381
            if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1382
                Exception e = new Exception("User " + user
1383
                        + " does not have permission"
1384
                        + " to read the document with the docid " + docid);
1385

    
1386
                throw e;
1387
            }
1388

    
1389
            if (doc.getRootNodeID() == 0) {
1390
                // this is data file
1391
                String filepath = MetaCatUtil.getOption("datafilepath");
1392
                if (!filepath.endsWith("/")) {
1393
                    filepath += "/";
1394
                }
1395
                String filename = filepath + docid;
1396
                FileInputStream fin = null;
1397
                fin = new FileInputStream(filename);
1398

    
1399
                //MIME type
1400
                String contentType = getServletContext().getMimeType(filename);
1401
                if (contentType == null) {
1402
                    ContentTypeProvider provider = new ContentTypeProvider(
1403
                            docid);
1404
                    contentType = provider.getContentType();
1405
                    logMetacat.info("Final contenttype is: "
1406
                            + contentType);
1407
                }
1408

    
1409
                response.setContentType(contentType);
1410
                // if we decide to use "application/octet-stream" for all data
1411
                // returns
1412
                // response.setContentType("application/octet-stream");
1413

    
1414
                try {
1415

    
1416
                    ServletOutputStream out = response.getOutputStream();
1417
                    byte[] buf = new byte[4 * 1024]; // 4K buffer
1418
                    int b = fin.read(buf);
1419
                    while (b != -1) {
1420
                        out.write(buf, 0, b);
1421
                        b = fin.read(buf);
1422
                    }
1423
                } finally {
1424
                    if (fin != null) fin.close();
1425
                }
1426

    
1427
            } else {
1428
                // this is metadata doc
1429
                if (qformat.equals("xml") || qformat.equals("")) {
1430
                    // if equals "", that means no qformat is specified. hence
1431
                    // by default the document should be returned in xml format
1432
                    // set content type first
1433
                    response.setContentType("text/xml"); //MIME type
1434
                    PrintWriter out = response.getWriter();
1435
                    doc.toXml(out, user, groups, withInlineData);
1436
                } else {
1437
                    response.setContentType("text/html"); //MIME type
1438
                    PrintWriter out = response.getWriter();
1439

    
1440
                    // Look up the document type
1441
                    String doctype = doc.getDoctype();
1442
                    // Transform the document to the new doctype
1443
                    DBTransform dbt = new DBTransform();
1444
                    dbt.transformXMLDocument(doc.toString(user, groups,
1445
                            withInlineData), doctype, "-//W3C//HTML//EN",
1446
                            qformat, out, params);
1447
                }
1448

    
1449
            }
1450
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1451
                    docid, "read");
1452
        } catch (Exception except) {
1453
            throw except;
1454
        }
1455
    }
1456

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

    
1490
        // this is http url
1491
        URL url = new URL(docid);
1492
        BufferedInputStream bis = null;
1493
        try {
1494
            bis = new BufferedInputStream(url.openStream());
1495
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1496
            int b = bis.read(buf);
1497
            while (b != -1) {
1498
                out.write(buf, 0, b);
1499
                b = bis.read(buf);
1500
            }
1501
        } finally {
1502
            if (bis != null) bis.close();
1503
        }
1504

    
1505
    }
1506

    
1507
    /**
1508
     * read file/doc and write to ZipOutputStream
1509
     *
1510
     * @param docid
1511
     * @param zout
1512
     * @param user
1513
     * @param groups
1514
     * @throws ClassNotFoundException
1515
     * @throws IOException
1516
     * @throws SQLException
1517
     * @throws McdbException
1518
     * @throws Exception
1519
     */
1520
    private void addDocToZip(HttpServletRequest request, String docid,
1521
            ZipOutputStream zout, String user, String[] groups) throws
1522
            ClassNotFoundException, IOException, SQLException, McdbException,
1523
            Exception
1524
    {
1525
        byte[] bytestring = null;
1526
        ZipEntry zentry = null;
1527

    
1528
        try {
1529
            URL url = new URL(docid);
1530

    
1531
            // this http url; read from URLConnection; add to zip
1532
            zentry = new ZipEntry(docid);
1533
            zout.putNextEntry(zentry);
1534
            BufferedInputStream bis = null;
1535
            try {
1536
                bis = new BufferedInputStream(url.openStream());
1537
                byte[] buf = new byte[4 * 1024]; // 4K buffer
1538
                int b = bis.read(buf);
1539
                while (b != -1) {
1540
                    zout.write(buf, 0, b);
1541
                    b = bis.read(buf);
1542
                }
1543
            } finally {
1544
                if (bis != null) bis.close();
1545
            }
1546
            zout.closeEntry();
1547

    
1548
        } catch (MalformedURLException mue) {
1549

    
1550
            // this is metacat doc (data file or metadata doc)
1551
            try {
1552
                DocumentImpl doc = new DocumentImpl(docid);
1553

    
1554
                //check the permission for read
1555
                if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1556
                    Exception e = new Exception("User " + user
1557
                            + " does not have "
1558
                            + "permission to read the document with the docid "
1559
                            + docid);
1560
                    throw e;
1561
                }
1562

    
1563
                if (doc.getRootNodeID() == 0) {
1564
                    // this is data file; add file to zip
1565
                    String filepath = MetaCatUtil.getOption("datafilepath");
1566
                    if (!filepath.endsWith("/")) {
1567
                        filepath += "/";
1568
                    }
1569
                    String filename = filepath + docid;
1570
                    FileInputStream fin = null;
1571
                    fin = new FileInputStream(filename);
1572
                    try {
1573

    
1574
                        zentry = new ZipEntry(docid);
1575
                        zout.putNextEntry(zentry);
1576
                        byte[] buf = new byte[4 * 1024]; // 4K buffer
1577
                        int b = fin.read(buf);
1578
                        while (b != -1) {
1579
                            zout.write(buf, 0, b);
1580
                            b = fin.read(buf);
1581
                        }
1582
                    } finally {
1583
                        if (fin != null) fin.close();
1584
                    }
1585
                    zout.closeEntry();
1586

    
1587
                } else {
1588
                    // this is metadata doc; add doc to zip
1589
                    bytestring = doc.toString().getBytes();
1590
                    zentry = new ZipEntry(docid + ".xml");
1591
                    zentry.setSize(bytestring.length);
1592
                    zout.putNextEntry(zentry);
1593
                    zout.write(bytestring, 0, bytestring.length);
1594
                    zout.closeEntry();
1595
                }
1596
                EventLog.getInstance().log(request.getRemoteAddr(), user,
1597
                        docid, "read");
1598
            } catch (Exception except) {
1599
                throw except;
1600
            }
1601
        }
1602
    }
1603

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

    
1635
    /**
1636
     * Handle the database putdocument request and write an XML document to the
1637
     * database connection
1638
     */
1639
    private void handleInsertOrUpdateAction(HttpServletRequest request,
1640
            HttpServletResponse response, PrintWriter out, Hashtable params,
1641
            String user, String[] groups)
1642
    {
1643
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1644
        DBConnection dbConn = null;
1645
        int serialNumber = -1;
1646

    
1647
        if(params.get("docid") == null){
1648
            out.println("<?xml version=\"1.0\"?>");
1649
            out.println("<error>");
1650
            out.println("Docid not specified");
1651
            out.println("</error>");
1652
            logMetacat.error("Docid not specified");
1653
            return;
1654
        }
1655
        
1656
        if(!MetaCatUtil.canInsertOrUpdate(user, groups)){
1657
        	out.println("<?xml version=\"1.0\"?>");
1658
            out.println("<error>");
1659
            out.println("User '" + user + "' not allowed to insert and update");
1660
            out.println("</error>");
1661
            logMetacat.error("User '" + user + "' not allowed to insert and update");
1662
            return;
1663
        }
1664

    
1665
        try {
1666
            // Get the document indicated
1667
            String[] doctext = (String[]) params.get("doctext");
1668
            String pub = null;
1669
            if (params.containsKey("public")) {
1670
                pub = ((String[]) params.get("public"))[0];
1671
            }
1672

    
1673
            StringReader dtd = null;
1674
            if (params.containsKey("dtdtext")) {
1675
                String[] dtdtext = (String[]) params.get("dtdtext");
1676
                try {
1677
                    if (!dtdtext[0].equals("")) {
1678
                        dtd = new StringReader(dtdtext[0]);
1679
                    }
1680
                } catch (NullPointerException npe) {
1681
                }
1682
            }
1683

    
1684
            if(doctext == null){
1685
                out.println("<?xml version=\"1.0\"?>");
1686
                out.println("<error>");
1687
                out.println("Document text not submitted");
1688
                out.println("</error>");
1689
                return;
1690
            }
1691

    
1692
            StringReader xml = new StringReader(doctext[0]);
1693
            boolean validate = false;
1694
            DocumentImplWrapper documentWrapper = null;
1695
            try {
1696
                // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ...
1697
                // >
1698
                // in order to decide whether to use validation parser
1699
                validate = needDTDValidation(xml);
1700
                if (validate) {
1701
                    // set a dtd base validation parser
1702
                    String rule = DocumentImpl.DTD;
1703
                    documentWrapper = new DocumentImplWrapper(rule, validate);
1704
                } else {
1705

    
1706
                    String namespace = findNamespace(xml);
1707
                    
1708
                	if (namespace != null) {
1709
                		if (namespace.compareTo(DocumentImpl.EML2_0_0NAMESPACE) == 0
1710
                				|| namespace.compareTo(
1711
                				DocumentImpl.EML2_0_1NAMESPACE) == 0) {
1712
                			// set eml2 base	 validation parser
1713
                			String rule = DocumentImpl.EML200;
1714
                			// using emlparser to check id validation
1715
                			EMLParser parser = new EMLParser(doctext[0]);
1716
                			documentWrapper = new DocumentImplWrapper(rule, true);
1717
                		} else if (namespace.compareTo(
1718
                                DocumentImpl.EML2_1_0NAMESPACE) == 0) {
1719
                			// set eml2 base validation parser
1720
                			String rule = DocumentImpl.EML210;
1721
                			// using emlparser to check id validation
1722
                			EMLParser parser = new EMLParser(doctext[0]);
1723
                			documentWrapper = new DocumentImplWrapper(rule, true);
1724
                		} else {
1725
                			// set schema base validation parser
1726
                			String rule = DocumentImpl.SCHEMA;
1727
                			documentWrapper = new DocumentImplWrapper(rule, true);
1728
                		}
1729
                	} else {
1730
                		documentWrapper = new DocumentImplWrapper("", false);
1731
                	}
1732
                }
1733

    
1734
                String[] action = (String[]) params.get("action");
1735
                String[] docid = (String[]) params.get("docid");
1736
                String newdocid = null;
1737

    
1738
                String doAction = null;
1739
                if (action[0].equals("insert")) {
1740
                    doAction = "INSERT";
1741
                } else if (action[0].equals("update")) {
1742
                    doAction = "UPDATE";
1743
                }
1744

    
1745
                try {
1746
                    // get a connection from the pool
1747
                    dbConn = DBConnectionPool
1748
                            .getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1749
                    serialNumber = dbConn.getCheckOutSerialNumber();
1750

    
1751
                    // write the document to the database
1752
                    try {
1753
                        String accNumber = docid[0];
1754
                        logMetacat.debug("" + doAction + " "
1755
                                + accNumber + "...");
1756
                        if (accNumber.equals("")) {
1757
                            accNumber = null;
1758
                        }
1759
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1760
                                doAction, accNumber, user, groups);
1761
                        EventLog.getInstance().log(request.getRemoteAddr(),
1762
                                user, accNumber, action[0]);
1763
                    } catch (NullPointerException npe) {
1764
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1765
                                doAction, null, user, groups);
1766
                        EventLog.getInstance().log(request.getRemoteAddr(),
1767
                                user, "", action[0]);
1768
                    }
1769
                }
1770
                finally {
1771
                    // Return db connection
1772
                    DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1773
                }
1774

    
1775
                // set content type and other response header fields first
1776
                //response.setContentType("text/xml");
1777
                out.println("<?xml version=\"1.0\"?>");
1778
                out.println("<success>");
1779
                out.println("<docid>" + newdocid + "</docid>");
1780
                out.println("</success>");
1781

    
1782
            } catch (NullPointerException npe) {
1783
                //response.setContentType("text/xml");
1784
                out.println("<?xml version=\"1.0\"?>");
1785
                out.println("<error>");
1786
                out.println(npe.getMessage());
1787
                out.println("</error>");
1788
                logMetacat.warn("Error in writing eml document to the database" + npe.getMessage());
1789
                npe.printStackTrace();
1790
            }
1791
        } catch (Exception e) {
1792
            //response.setContentType("text/xml");
1793
            out.println("<?xml version=\"1.0\"?>");
1794
            out.println("<error>");
1795
            out.println(e.getMessage());
1796
            out.println("</error>");
1797
            logMetacat.warn("Error in writing eml document to the database" + e.getMessage());
1798
            e.printStackTrace();
1799
        }
1800
    }
1801

    
1802
    /**
1803
     * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... > in
1804
     * order to decide whether to use validation parser
1805
     */
1806
    private static boolean needDTDValidation(StringReader xmlreader)
1807
            throws IOException
1808
    {
1809
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1810
        StringBuffer cbuff = new StringBuffer();
1811
        java.util.Stack st = new java.util.Stack();
1812
        boolean validate = false;
1813
        int c;
1814
        int inx;
1815

    
1816
        // read from the stream until find the keywords
1817
        while ((st.empty() || st.size() < 4) && ((c = xmlreader.read()) != -1)) {
1818
            cbuff.append((char) c);
1819

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

    
1844
        // close the stream
1845
        xmlreader.reset();
1846

    
1847
        // check the stack whether it contains the keywords:
1848
        // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1849
        if (st.size() == 4) {
1850
            if (((String) st.pop()).equals(">")
1851
                    && (((String) st.peek()).equals("PUBLIC") | ((String) st
1852
                            .pop()).equals("SYSTEM"))
1853
                    && ((String) st.pop()).equals("<!DOCTYPE")) {
1854
                validate = true;
1855
            }
1856
        }
1857

    
1858
        logMetacat.info("Validation for dtd is " + validate);
1859
        return validate;
1860
    }
1861

    
1862
    // END OF INSERT/UPDATE SECTION
1863

    
1864
    /* check if the xml string contains key words to specify schema loocation */
1865
    private String findNamespace(StringReader xml) throws IOException
1866
    {
1867
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1868
        String namespace = null;
1869

    
1870
        String eml2_0_0NameSpace = DocumentImpl.EML2_0_0NAMESPACE;
1871
        String eml2_0_1NameSpace = DocumentImpl.EML2_0_1NAMESPACE;
1872
        String eml2_1_0NameSpace = DocumentImpl.EML2_1_0NAMESPACE;
1873

    
1874
        if (xml == null) {
1875
            logMetacat.debug("Validation for schema is "
1876
                    + namespace);
1877
            return namespace;
1878
        }
1879
        String targetLine = getSchemaLine(xml);
1880

    
1881
        if (targetLine != null) {
1882

    
1883
        	// find if the root element has prefix
1884
        	String prefix = getPrefix(targetLine);
1885
        	logMetacat.info("prefix is:" + prefix);
1886
        	int startIndex = 0;
1887
        	
1888
        	
1889
        	if(prefix != null)
1890
        	{
1891
        		// if prefix found then look for xmlns:prefix
1892
        		// element to find the ns 
1893
        		String namespaceWithPrefix = NAMESPACEKEYWORD 
1894
        					+ ":" + prefix;
1895
        		startIndex = targetLine.indexOf(namespaceWithPrefix);
1896
            	logMetacat.debug("namespaceWithPrefix is:" + namespaceWithPrefix+":");
1897
            	logMetacat.debug("startIndex is:" + startIndex);
1898
        		
1899
        	} else {
1900
        		// if prefix not found then look for xmlns
1901
        		// attribute to find the ns 
1902
        		startIndex = targetLine.indexOf(NAMESPACEKEYWORD);
1903
            	logMetacat.debug("startIndex is:" + startIndex);
1904
        	}
1905
        		
1906
            int start = 1;
1907
            int end = 1;
1908
            String namespaceString = null;
1909
            int count = 0;
1910
            if (startIndex != -1) {
1911
                for (int i = startIndex; i < targetLine.length(); i++) {
1912
                    if (targetLine.charAt(i) == '"') {
1913
                        count++;
1914
                    }
1915
                    if (targetLine.charAt(i) == '"' && count == 1) {
1916
                        start = i;
1917
                    }
1918
                    if (targetLine.charAt(i) == '"' && count == 2) {
1919
                        end = i;
1920
                        break;
1921
                    }
1922
                }
1923
            } 
1924
            // else: xmlns not found. namespace = null will be returned
1925

    
1926
         	logMetacat.debug("targetLine is " + targetLine);
1927
         	logMetacat.debug("start is " + end);
1928
         	logMetacat.debug("end is " + end);
1929
           
1930
            if(start < end){
1931
            	namespaceString = targetLine.substring(start + 1, end);
1932
            	logMetacat.debug("namespaceString is " + namespaceString);
1933
            }
1934
            logMetacat.debug("namespace in xml is: "
1935
                    + namespaceString);
1936
            if(namespaceString != null){
1937
            	if (namespaceString.indexOf(eml2_0_0NameSpace) != -1) {
1938
            		namespace = eml2_0_0NameSpace;
1939
            	} else if (namespaceString.indexOf(eml2_0_1NameSpace) != -1) {
1940
            		namespace = eml2_0_1NameSpace;
1941
            	} else if (namespaceString.indexOf(eml2_1_0NameSpace) != -1) {
1942
            		namespace = eml2_1_0NameSpace;
1943
            	} else {
1944
            		namespace = namespaceString;
1945
            	}
1946
            }
1947
        }
1948

    
1949
        logMetacat.debug("Validation for eml is " + namespace);
1950

    
1951
        return namespace;
1952

    
1953
    }
1954

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

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

    
2008
    private String getPrefix(String schemaLine)
2009
    {
2010
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2011
    	String prefix = null;
2012
    	String rootElement = schemaLine.substring(0, schemaLine.indexOf(" "));
2013
        logMetacat.debug("rootElement:" + rootElement);
2014
        
2015
        if(rootElement.indexOf(":") > 0){
2016
        	prefix = rootElement.substring(rootElement.indexOf(":") + 1,
2017
        			rootElement.length());
2018
        } 
2019
        return prefix.trim();
2020
    }
2021

    
2022
    /**
2023
     * Handle the database delete request and delete an XML document from the
2024
     * database connection
2025
     */
2026
    private void handleDeleteAction(PrintWriter out, Hashtable params,
2027
            HttpServletRequest request, HttpServletResponse response,
2028
            String user, String[] groups)
2029
    {
2030
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2031
        String[] docid = (String[]) params.get("docid");
2032

    
2033
        if(docid == null){
2034
          response.setContentType("text/xml");
2035
          out.println("<?xml version=\"1.0\"?>");
2036
          out.println("<error>");
2037
          out.println("Docid not specified.");
2038
          out.println("</error>");
2039
          logMetacat.error("Docid not specified for the document to be deleted.");
2040
        } else {
2041

    
2042
            // delete the document from the database
2043
            try {
2044

    
2045
                try {
2046
                    // null means notify server is null
2047
                    DocumentImpl.delete(docid[0], user, groups, null);
2048
                    EventLog.getInstance().log(request.getRemoteAddr(),
2049
                                               user, docid[0], "delete");
2050
                    response.setContentType("text/xml");
2051
                    out.println("<?xml version=\"1.0\"?>");
2052
                    out.println("<success>");
2053
                    out.println("Document deleted.");
2054
                    out.println("</success>");
2055
                    logMetacat.info("Document deleted.");
2056
                }
2057
                catch (AccessionNumberException ane) {
2058
                    response.setContentType("text/xml");
2059
                    out.println("<?xml version=\"1.0\"?>");
2060
                    out.println("<error>");
2061
                    //out.println("Error deleting document!!!");
2062
                    out.println(ane.getMessage());
2063
                    out.println("</error>");
2064
                    logMetacat.error("Document could not be deleted: " 
2065
                    		+ ane.getMessage());
2066
                }
2067
            }
2068
            catch (Exception e) {
2069
                response.setContentType("text/xml");
2070
                out.println("<?xml version=\"1.0\"?>");
2071
                out.println("<error>");
2072
                out.println(e.getMessage());
2073
                out.println("</error>");
2074
                logMetacat.error("Document could not be deleted: " 
2075
                		+ e.getMessage());
2076
            }
2077
        }
2078
    }
2079

    
2080
    /**
2081
     * Handle the validation request and return the results to the requestor
2082
     */
2083
    private void handleValidateAction(PrintWriter out, Hashtable params)
2084
    {
2085

    
2086
        // Get the document indicated
2087
        String valtext = null;
2088
        DBConnection dbConn = null;
2089
        int serialNumber = -1;
2090

    
2091
        try {
2092
            valtext = ((String[]) params.get("valtext"))[0];
2093
        } catch (Exception nullpe) {
2094

    
2095
            String docid = null;
2096
            try {
2097
                // Find the document id number
2098
                docid = ((String[]) params.get("docid"))[0];
2099

    
2100
                // Get the document indicated from the db
2101
                DocumentImpl xmldoc = new DocumentImpl(docid);
2102
                valtext = xmldoc.toString();
2103

    
2104
            } catch (NullPointerException npe) {
2105

    
2106
                out.println("<error>Error getting document ID: " + docid
2107
                        + "</error>");
2108
                //if ( conn != null ) { util.returnConnection(conn); }
2109
                return;
2110
            } catch (Exception e) {
2111

    
2112
                out.println(e.getMessage());
2113
            }
2114
        }
2115

    
2116
        try {
2117
            // get a connection from the pool
2118
            dbConn = DBConnectionPool
2119
                    .getDBConnection("MetaCatServlet.handleValidateAction");
2120
            serialNumber = dbConn.getCheckOutSerialNumber();
2121
            DBValidate valobj = new DBValidate(dbConn);
2122
            boolean valid = valobj.validateString(valtext);
2123

    
2124
            // set content type and other response header fields first
2125

    
2126
            out.println(valobj.returnErrors());
2127

    
2128
        } catch (NullPointerException npe2) {
2129
            // set content type and other response header fields first
2130

    
2131
            out.println("<error>Error validating document.</error>");
2132
        } catch (Exception e) {
2133

    
2134
            out.println(e.getMessage());
2135
        } finally {
2136
            // Return db connection
2137
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2138
        }
2139
    }
2140

    
2141
    /**
2142
     * Handle "getrevsionanddoctype" action Given a docid, return it's current
2143
     * revision and doctype from data base The output is String look like
2144
     * "rev;doctype"
2145
     */
2146
    private void handleGetRevisionAndDocTypeAction(PrintWriter out,
2147
            Hashtable params)
2148
    {
2149
        // To store doc parameter
2150
        String[] docs = new String[10];
2151
        // Store a single doc id
2152
        String givenDocId = null;
2153
        // Get docid from parameters
2154
        if (params.containsKey("docid")) {
2155
            docs = (String[]) params.get("docid");
2156
        }
2157
        // Get first docid form string array
2158
        givenDocId = docs[0];
2159

    
2160
        try {
2161
            // Make sure there is a docid
2162
            if (givenDocId == null || givenDocId.equals("")) { throw new Exception(
2163
                    "User didn't specify docid!"); }//if
2164

    
2165
            // Create a DBUtil object
2166
            DBUtil dbutil = new DBUtil();
2167
            // Get a rev and doctype
2168
            String revAndDocType = dbutil
2169
                    .getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
2170
            out.println(revAndDocType);
2171

    
2172
        } catch (Exception e) {
2173
            // Handle exception
2174
            out.println("<?xml version=\"1.0\"?>");
2175
            out.println("<error>");
2176
            out.println(e.getMessage());
2177
            out.println("</error>");
2178
        }
2179

    
2180
    }
2181

    
2182
    /**
2183
     * Handle "getaccesscontrol" action. Read Access Control List from db
2184
     * connection in XML format
2185
     */
2186
    private void handleGetAccessControlAction(PrintWriter out,
2187
            Hashtable params, HttpServletResponse response, String username,
2188
            String[] groupnames)
2189
    {
2190
        DBConnection dbConn = null;
2191
        int serialNumber = -1;
2192
        String docid = ((String[]) params.get("docid"))[0];
2193

    
2194
        try {
2195

    
2196
            // get connection from the pool
2197
            dbConn = DBConnectionPool
2198
                    .getDBConnection("MetaCatServlet.handleGetAccessControlAction");
2199
            serialNumber = dbConn.getCheckOutSerialNumber();
2200
            AccessControlList aclobj = new AccessControlList(dbConn);
2201
            String acltext = aclobj.getACL(docid, username, groupnames);
2202
            out.println(acltext);
2203

    
2204
        } catch (Exception e) {
2205
            out.println("<?xml version=\"1.0\"?>");
2206
            out.println("<error>");
2207
            out.println(e.getMessage());
2208
            out.println("</error>");
2209
        } finally {
2210
            // Retrun db connection to pool
2211
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2212
        }
2213
    }
2214

    
2215
    /**
2216
     * Handle the "getprincipals" action. Read all principals from
2217
     * authentication scheme in XML format
2218
     */
2219
    private void handleGetPrincipalsAction(PrintWriter out, String user,
2220
            String password)
2221
    {
2222
        try {
2223
            AuthSession auth = new AuthSession();
2224
            String principals = auth.getPrincipals(user, password);
2225
            out.println(principals);
2226

    
2227
        } catch (Exception e) {
2228
            out.println("<?xml version=\"1.0\"?>");
2229
            out.println("<error>");
2230
            out.println(e.getMessage());
2231
            out.println("</error>");
2232
        }
2233
    }
2234

    
2235
    /**
2236
     * Handle "getdoctypes" action. Read all doctypes from db connection in XML
2237
     * format
2238
     */
2239
    private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
2240
            HttpServletResponse response)
2241
    {
2242
        try {
2243
            DBUtil dbutil = new DBUtil();
2244
            String doctypes = dbutil.readDoctypes();
2245
            out.println(doctypes);
2246
        } catch (Exception e) {
2247
            out.println("<?xml version=\"1.0\"?>");
2248
            out.println("<error>");
2249
            out.println(e.getMessage());
2250
            out.println("</error>");
2251
        }
2252
    }
2253

    
2254
    /**
2255
     * Handle the "getdtdschema" action. Read DTD or Schema file for a given
2256
     * doctype from Metacat catalog system
2257
     */
2258
    private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
2259
            HttpServletResponse response)
2260
    {
2261

    
2262
        String doctype = null;
2263
        String[] doctypeArr = (String[]) params.get("doctype");
2264

    
2265
        // get only the first doctype specified in the list of doctypes
2266
        // it could be done for all doctypes in that list
2267
        if (doctypeArr != null) {
2268
            doctype = ((String[]) params.get("doctype"))[0];
2269
        }
2270

    
2271
        try {
2272
            DBUtil dbutil = new DBUtil();
2273
            String dtdschema = dbutil.readDTDSchema(doctype);
2274
            out.println(dtdschema);
2275

    
2276
        } catch (Exception e) {
2277
            out.println("<?xml version=\"1.0\"?>");
2278
            out.println("<error>");
2279
            out.println(e.getMessage());
2280
            out.println("</error>");
2281
        }
2282

    
2283
    }
2284

    
2285
    /**
2286
     * Handle the "getlastdocid" action. Get the latest docid with rev number
2287
     * from db connection in XML format
2288
     */
2289
    private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
2290
            HttpServletResponse response)
2291
    {
2292

    
2293
        String scope = ((String[]) params.get("scope"))[0];
2294
        if (scope == null) {
2295
            scope = ((String[]) params.get("username"))[0];
2296
        }
2297

    
2298
        try {
2299

    
2300
            DBUtil dbutil = new DBUtil();
2301
            String lastDocid = dbutil.getMaxDocid(scope);
2302
            out.println("<?xml version=\"1.0\"?>");
2303
            out.println("<lastDocid>");
2304
            out.println("  <scope>" + scope + "</scope>");
2305
            out.println("  <docid>" + lastDocid + "</docid>");
2306
            out.println("</lastDocid>");
2307

    
2308
        } catch (Exception e) {
2309
            out.println("<?xml version=\"1.0\"?>");
2310
            out.println("<error>");
2311
            out.println(e.getMessage());
2312
            out.println("</error>");
2313
        }
2314
    }
2315

    
2316
    /**
2317
     * Print a report from the event log based on filter parameters passed in
2318
     * from the web.
2319
     *
2320
     * @param params the parameters from the web request
2321
     * @param request the http request object for getting request details
2322
     * @param response the http response object for writing output
2323
     */
2324
    private void handleGetLogAction(Hashtable params, HttpServletRequest request,
2325
            HttpServletResponse response, String username, String[] groups)
2326
    {
2327
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2328
        try {
2329
            response.setContentType("text/xml");
2330
            PrintWriter out = response.getWriter();
2331

    
2332
            // Check that the user is authenticated as an administrator account
2333
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2334
                out.print("<error>");
2335
                out.print("The user \"" + username +
2336
                        "\" is not authorized for this action.");
2337
                out.print("</error>");
2338
                return;
2339
            }
2340

    
2341
            // Get all of the parameters in the correct formats
2342
            String[] ipAddress = (String[])params.get("ipaddress");
2343
            String[] principal = (String[])params.get("principal");
2344
            String[] docid = (String[])params.get("docid");
2345
            String[] event = (String[])params.get("event");
2346
            String[] startArray = (String[]) params.get("start");
2347
            String[] endArray = (String[]) params.get("end");
2348
            String start = null;
2349
            String end = null;
2350
            if (startArray != null) {
2351
                start = startArray[0];
2352
            }
2353
            if (endArray != null) {
2354
                end = endArray[0];
2355
            }
2356
            Timestamp startDate = null;
2357
            Timestamp endDate = null;
2358
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2359
            try {
2360
                if (start != null) {
2361
                    startDate = new Timestamp((format.parse(start)).getTime());
2362
                }
2363
                if (end != null) {
2364
                    endDate = new Timestamp((format.parse(end)).getTime());
2365
                }
2366
            } catch (ParseException e) {
2367
                System.out.println("Failed to created Timestamp from input.");
2368
            }
2369

    
2370
            // Request the report by passing the filter parameters
2371
            out.println(EventLog.getInstance().getReport(ipAddress, principal,
2372
                    docid, event, startDate, endDate));
2373
            out.close();
2374
        } catch (IOException e) {
2375
            logMetacat.error(
2376
                    "Could not open http response for writing: " + e.getMessage());
2377
        }
2378
    }
2379

    
2380
    /**
2381
     * Rebuild the index for one or more documents. If the docid parameter is
2382
     * provided, rebuild for just that one document or list of documents. If
2383
     * not, then rebuild the index for all documents in the xml_documents
2384
     * table.
2385
     *
2386
     * @param params the parameters from the web request
2387
     * @param request the http request object for getting request details
2388
     * @param response the http response object for writing output
2389
     * @param username the username of the authenticated user
2390
     */
2391
    private void handleBuildIndexAction(Hashtable params,
2392
            HttpServletRequest request, HttpServletResponse response,
2393
            String username, String[] groups)
2394
    {
2395
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2396
        
2397
        // Get all of the parameters in the correct formats
2398
        String[] docid = (String[])params.get("docid");
2399

    
2400
        // Rebuild the indices for appropriate documents
2401
        try {
2402
            response.setContentType("text/xml");
2403
            PrintWriter out = response.getWriter();
2404

    
2405
            // Check that the user is authenticated as an administrator account
2406
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2407
                out.print("<error>");
2408
                out.print("The user \"" + username +
2409
                        "\" is not authorized for this action.");
2410
                out.print("</error>");
2411
                return;
2412
            }
2413

    
2414
            // Process the documents
2415
            out.println("<success>");
2416
            if (docid == null || docid.length == 0) {
2417
                // Process all of the documents
2418
                try {
2419
                    Vector documents = getDocumentList();
2420
                    Iterator it = documents.iterator();
2421
                    while (it.hasNext()) {
2422
                        String id = (String) it.next();
2423
                        buildDocumentIndex(id, out);
2424
                    }
2425
                } catch (SQLException se) {
2426
                    out.print("<error>");
2427
                    out.print(se.getMessage());
2428
                    out.println("</error>");
2429
                }
2430
            } else {
2431
                // Only process the requested documents
2432
                for (int i = 0; i < docid.length; i++) {
2433
                    buildDocumentIndex(docid[i], out);
2434
                }
2435
            }
2436
            out.println("</success>");
2437
            out.close();
2438
        } catch (IOException e) {
2439
            logMetacat.error(
2440
                    "Could not open http response for writing: "
2441
                    + e.getMessage());
2442
        }
2443
    }
2444

    
2445
    /**
2446
     * Build the index for one document by reading the document and
2447
     * calling its buildIndex() method.
2448
     *
2449
     * @param docid the document (with revision) to rebuild
2450
     * @param out the PrintWriter to which output is printed
2451
     */
2452
    private void buildDocumentIndex(String docid, PrintWriter out)
2453
    {
2454
        try {
2455
            DocumentImpl doc = new DocumentImpl(docid, false);
2456
            doc.buildIndex();
2457
            out.print("<docid>" + docid);
2458
            out.println("</docid>");
2459
        } catch (McdbException me) {
2460
            out.print("<error>");
2461
            out.print(me.getMessage());
2462
            out.println("</error>");
2463
        }
2464
    }
2465

    
2466
    /**
2467
     * Handle documents passed to metacat that are encoded using the
2468
     * "multipart/form-data" mime type. This is typically used for uploading
2469
     * data files which may be binary and large.
2470
     */
2471
    private void handleMultipartForm(HttpServletRequest request,
2472
            HttpServletResponse response)
2473
    {
2474
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2475
        PrintWriter out = null;
2476
        String action = null;
2477

    
2478
        // Parse the multipart form, and save the parameters in a Hashtable and
2479
        // save the FileParts in a hashtable
2480

    
2481
        Hashtable params = new Hashtable();
2482
        Hashtable fileList = new Hashtable();
2483
        int sizeLimit = (new Integer(MetaCatUtil.getOption("datafilesizelimit")))
2484
                .intValue();
2485
        logMetacat.info(
2486
                "The size limit of uploaded data files is: " + sizeLimit);
2487

    
2488
        try {
2489
            MultipartParser mp = new MultipartParser(request,
2490
                    sizeLimit * 1024 * 1024);
2491
            Part part;
2492
            while ((part = mp.readNextPart()) != null) {
2493
                String name = part.getName();
2494

    
2495
                if (part.isParam()) {
2496
                    // it's a parameter part
2497
                    ParamPart paramPart = (ParamPart) part;
2498
                    String value = paramPart.getStringValue();
2499
                    params.put(name, value);
2500
                    if (name.equals("action")) {
2501
                        action = value;
2502
                    }
2503
                } else if (part.isFile()) {
2504
                    // it's a file part
2505
                    FilePart filePart = (FilePart) part;
2506
                    fileList.put(name, filePart);
2507

    
2508
                    // Stop once the first file part is found, otherwise going
2509
                    // onto the
2510
                    // next part prevents access to the file contents. So...for
2511
                    // upload
2512
                    // to work, the datafile must be the last part
2513
                    break;
2514
                }
2515
            }
2516
        } catch (IOException ioe) {
2517
            try {
2518
                out = response.getWriter();
2519
            } catch (IOException ioe2) {
2520
                logMetacat.fatal("Fatal Error: couldn't get response output stream.");
2521
            }
2522
            out.println("<?xml version=\"1.0\"?>");
2523
            out.println("<error>");
2524
            out.println("Error: problem reading multipart data.");
2525
            out.println("</error>");
2526
        }
2527

    
2528
        // Get the session information
2529
        String username = null;
2530
        String password = null;
2531
        String[] groupnames = null;
2532
        String sess_id = null;
2533

    
2534
        // be aware of session expiration on every request
2535
        HttpSession sess = request.getSession(true);
2536
        if (sess.isNew()) {
2537
            // session expired or has not been stored b/w user requests
2538
            username = "public";
2539
            sess.setAttribute("username", username);
2540
        } else {
2541
            username = (String) sess.getAttribute("username");
2542
            password = (String) sess.getAttribute("password");
2543
            groupnames = (String[]) sess.getAttribute("groupnames");
2544
            try {
2545
                sess_id = (String) sess.getId();
2546
            } catch (IllegalStateException ise) {
2547
                System.out
2548
                        .println("error in  handleMultipartForm: this shouldn't "
2549
                                + "happen: the session should be valid: "
2550
                                + ise.getMessage());
2551
            }
2552
        }
2553

    
2554
        // Get the out stream
2555
        try {
2556
            out = response.getWriter();
2557
        } catch (IOException ioe2) {
2558
            logMetacat.error("Fatal Error: couldn't get response "
2559
                    + "output stream.");
2560
        }
2561

    
2562
        if (action.equals("upload")) {
2563
            if (username != null && !username.equals("public")) {
2564
                handleUploadAction(request, out, params, fileList, username,
2565
                        groupnames);
2566
            } else {
2567

    
2568
                out.println("<?xml version=\"1.0\"?>");
2569
                out.println("<error>");
2570
                out.println("Permission denied for " + action);
2571
                out.println("</error>");
2572
            }
2573
        } else {
2574
            /*
2575
             * try { out = response.getWriter(); } catch (IOException ioe2) {
2576
             * System.err.println("Fatal Error: couldn't get response output
2577
             * stream.");
2578
             */
2579
            out.println("<?xml version=\"1.0\"?>");
2580
            out.println("<error>");
2581
            out.println(
2582
                    "Error: action not registered.  Please report this error.");
2583
            out.println("</error>");
2584
        }
2585
        out.close();
2586
    }
2587

    
2588
    /**
2589
     * Handle the upload action by saving the attached file to disk and
2590
     * registering it in the Metacat db
2591
     */
2592
    private void handleUploadAction(HttpServletRequest request,
2593
            PrintWriter out, Hashtable params, Hashtable fileList,
2594
            String username, String[] groupnames)
2595
    {
2596
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2597
        //PrintWriter out = null;
2598
        //Connection conn = null;
2599
        String action = null;
2600
        String docid = null;
2601

    
2602
        /*
2603
         * response.setContentType("text/xml"); try { out =
2604
         * response.getWriter(); } catch (IOException ioe2) {
2605
         * System.err.println("Fatal Error: couldn't get response output
2606
         * stream.");
2607
         */
2608

    
2609
        if (params.containsKey("docid")) {
2610
            docid = (String) params.get("docid");
2611
        }
2612

    
2613
        // Make sure we have a docid and datafile
2614
        if (docid != null && fileList.containsKey("datafile")) {
2615
            logMetacat.info("Uploading data docid: " + docid);
2616
            // Get a reference to the file part of the form
2617
            FilePart filePart = (FilePart) fileList.get("datafile");
2618
            String fileName = filePart.getFileName();
2619
            logMetacat.info("Uploading filename: " + fileName);
2620
            // Check if the right file existed in the uploaded data
2621
            if (fileName != null) {
2622

    
2623
                try {
2624
                    //logMetacat.info("Upload datafile " + docid
2625
                    // +"...", 10);
2626
                    //If document get lock data file grant
2627
                    if (DocumentImpl.getDataFileLockGrant(docid)) {
2628
                        // Save the data file to disk using "docid" as the name
2629
                        String datafilepath = MetaCatUtil.getOption("datafilepath");
2630
                        File dataDirectory = new File(datafilepath);
2631
                        dataDirectory.mkdirs();
2632
                        File newFile = null;
2633
                        long size = 0;
2634
                        try
2635
                        {
2636
                          newFile = new File(dataDirectory, docid);
2637
                          size = filePart.writeTo(newFile);
2638
                        
2639
//                        register the file in the database (which generates
2640
                          // an exception
2641
                          //if the docid is not acceptable or other untoward
2642
                          // things happen
2643
                          DocumentImpl.registerDocument(fileName, "BIN", docid,
2644
                                username, groupnames);
2645
                        }
2646
                        catch (Exception ee)
2647
                        {
2648
                           //detelte the file to create
2649
                            newFile.delete();
2650
                            throw ee;
2651
                        }
2652

    
2653
                        EventLog.getInstance().log(request.getRemoteAddr(),
2654
                                username, docid, "upload");
2655
                        // Force replication this data file
2656
                        // To data file, "insert" and update is same
2657
                        // The fourth parameter is null. Because it is
2658
                        // notification server
2659
                        // and this method is in MetaCatServerlet. It is
2660
                        // original command,
2661
                        // not get force replication info from another metacat
2662
                        ForceReplicationHandler frh = new ForceReplicationHandler(
2663
                                docid, "insert", false, null);
2664

    
2665
                        // set content type and other response header fields
2666
                        // first
2667
                        out.println("<?xml version=\"1.0\"?>");
2668
                        out.println("<success>");
2669
                        out.println("<docid>" + docid + "</docid>");
2670
                        out.println("<size>" + size + "</size>");
2671
                        out.println("</success>");
2672
                    }
2673

    
2674
                } catch (Exception e) {
2675
                    
2676
                    out.println("<?xml version=\"1.0\"?>");
2677
                    out.println("<error>");
2678
                    out.println(e.getMessage());
2679
                    out.println("</error>");
2680
                }
2681
            } else {
2682
                // the field did not contain a file
2683
                out.println("<?xml version=\"1.0\"?>");
2684
                out.println("<error>");
2685
                out.println("The uploaded data did not contain a valid file.");
2686
                out.println("</error>");
2687
            }
2688
        } else {
2689
            // Error bcse docid missing or file missing
2690
            out.println("<?xml version=\"1.0\"?>");
2691
            out.println("<error>");
2692
            out.println("The uploaded data did not contain a valid docid "
2693
                    + "or valid file.");
2694
            out.println("</error>");
2695
        }
2696
    }
2697

    
2698
    /*
2699
     * A method to handle set access action
2700
     */
2701
    private void handleSetAccessAction(PrintWriter out, Hashtable params,
2702
            String username)
2703
    {
2704
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2705
        String[] docList = null;
2706
        String[] principalList = null;
2707
        String[] permissionList = null;
2708
        String[] permTypeList = null;
2709
        String[] permOrderList = null;
2710
        String permission = null;
2711
        String permType = null;
2712
        String permOrder = null;
2713
        Vector errorList = new Vector();
2714
        String error = null;
2715
        Vector successList = new Vector();
2716
        String success = null;
2717

    
2718
        // Get parameters
2719
        if (params.containsKey("docid")) {
2720
            docList = (String[]) params.get("docid");
2721
        }
2722
        if (params.containsKey("principal")) {
2723
            principalList = (String[]) params.get("principal");
2724
        }
2725
        if (params.containsKey("permission")) {
2726
            permissionList = (String[]) params.get("permission");
2727

    
2728
        }
2729
        if (params.containsKey("permType")) {
2730
            permTypeList = (String[]) params.get("permType");
2731

    
2732
        }
2733
        if (params.containsKey("permOrder")) {
2734
            permOrderList = (String[]) params.get("permOrder");
2735

    
2736
        }
2737

    
2738
        // Make sure the parameter is not null
2739
        if (docList == null || principalList == null || permTypeList == null
2740
                || permissionList == null) {
2741
            error = "Please check your parameter list, it should look like: "
2742
                    + "?action=setaccess&docid=pipeline.1.1&principal=public"
2743
                    + "&permission=read&permType=allow&permOrder=allowFirst";
2744
            errorList.addElement(error);
2745
            outputResponse(successList, errorList, out);
2746
            return;
2747
        }
2748

    
2749
        // Only select first element for permission, type and order
2750
        permission = permissionList[0];
2751
        permType = permTypeList[0];
2752
        if (permOrderList != null) {
2753
            permOrder = permOrderList[0];
2754
        }
2755

    
2756
        // Get package doctype set
2757
        Vector packageSet = MetaCatUtil.getOptionList(MetaCatUtil
2758
                .getOption("packagedoctypeset"));
2759
        //debug
2760
        if (packageSet != null) {
2761
            for (int i = 0; i < packageSet.size(); i++) {
2762
                logMetacat.debug("doctype in package set: "
2763
                        + (String) packageSet.elementAt(i));
2764
            }
2765
        }
2766

    
2767
        // handle every accessionNumber
2768
        for (int i = 0; i < docList.length; i++) {
2769
            String accessionNumber = docList[i];
2770
            String owner = null;
2771
            String publicId = null;
2772
            // Get document owner and public id
2773
            try {
2774
                owner = getFieldValueForDoc(accessionNumber, "user_owner");
2775
                publicId = getFieldValueForDoc(accessionNumber, "doctype");
2776
            } catch (Exception e) {
2777
                logMetacat.error("Error in handleSetAccessAction: "
2778
                        + e.getMessage());
2779
                error = "Error in set access control for document - "
2780
                        + accessionNumber + e.getMessage();
2781
                errorList.addElement(error);
2782
                continue;
2783
            }
2784
            //check if user is the owner. Only owner can do owner
2785
            if (username == null || owner == null || !username.equals(owner)) {
2786
                error = "User - " + username
2787
                        + " does not have permission to set "
2788
                        + "access control for docid - " + accessionNumber;
2789
                errorList.addElement(error);
2790
                continue;
2791
            }
2792

    
2793
            // If docid publicid is BIN data file or other beta4, 6 package
2794
            // document
2795
            // we could not do set access control. Because we don't want
2796
            // inconsistent
2797
            // to its access docuemnt
2798
            if (publicId != null && packageSet != null
2799
                    && packageSet.contains(publicId)) {
2800
                error = "Could not set access control to document "
2801
                        + accessionNumber
2802
                        + "because it is in a pakcage and it has a access file for it";
2803
                errorList.addElement(error);
2804
                continue;
2805
            }
2806

    
2807
            // for every principle
2808
            for (int j = 0; j < principalList.length; j++) {
2809
                String principal = principalList[j];
2810
                try {
2811
                    //insert permission
2812
                    AccessControlForSingleFile accessControl = new AccessControlForSingleFile(
2813
                            accessionNumber, principal, permission, permType,
2814
                            permOrder);
2815
                    accessControl.insertPermissions();
2816
                    success = "Set access control to document "
2817
                            + accessionNumber + " successfully";
2818
                    successList.addElement(success);
2819
                } catch (Exception ee) {
2820
                    logMetacat.error(
2821
                            "Erorr in handleSetAccessAction2: "
2822
                                    + ee.getMessage());
2823
                    error = "Faild to set access control for document "
2824
                            + accessionNumber + " because " + ee.getMessage();
2825
                    errorList.addElement(error);
2826
                    continue;
2827
                }
2828
            }
2829
        }
2830
        outputResponse(successList, errorList, out);
2831
    }
2832

    
2833
    /*
2834
     * A method try to determin a docid's public id, if couldn't find null will
2835
     * be returned.
2836
     */
2837
    private String getFieldValueForDoc(String accessionNumber, String fieldName)
2838
            throws Exception
2839
    {
2840
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2841
        if (accessionNumber == null || accessionNumber.equals("")
2842
                || fieldName == null || fieldName.equals("")) { throw new Exception(
2843
                "Docid or field name was not specified"); }
2844

    
2845
        PreparedStatement pstmt = null;
2846
        ResultSet rs = null;
2847
        String fieldValue = null;
2848
        String docId = null;
2849
        DBConnection conn = null;
2850
        int serialNumber = -1;
2851

    
2852
        // get rid of revision if access number has
2853
        docId = MetaCatUtil.getDocIdFromString(accessionNumber);
2854
        try {
2855
            //check out DBConnection
2856
            conn = DBConnectionPool
2857
                    .getDBConnection("MetaCatServlet.getPublicIdForDoc");
2858
            serialNumber = conn.getCheckOutSerialNumber();
2859
            pstmt = conn.prepareStatement("SELECT " + fieldName
2860
                    + " FROM xml_documents " + "WHERE docid = ? ");
2861

    
2862
            pstmt.setString(1, docId);
2863
            pstmt.execute();
2864
            rs = pstmt.getResultSet();
2865
            boolean hasRow = rs.next();
2866
            int perm = 0;
2867
            if (hasRow) {
2868
                fieldValue = rs.getString(1);
2869
            } else {
2870
                throw new Exception("Could not find document: "
2871
                        + accessionNumber);
2872
            }
2873
        } catch (Exception e) {
2874
            logMetacat.error(
2875
                    "Exception in MetacatServlet.getPublicIdForDoc: "
2876
                            + e.getMessage());
2877
            throw e;
2878
        } finally {
2879
            try {
2880
                rs.close();
2881
                pstmt.close();
2882

    
2883
            } finally {
2884
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2885
            }
2886
        }
2887
        return fieldValue;
2888
    }
2889

    
2890
    /*
2891
     * Get the list of documents from the database and return the list in an
2892
     * Vector of identifiers.
2893
     *
2894
     * @ returns the array of identifiers
2895
     */
2896
    private Vector getDocumentList() throws SQLException
2897
    {
2898
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2899
        Vector docList = new Vector();
2900
        PreparedStatement pstmt = null;
2901
        ResultSet rs = null;
2902
        DBConnection conn = null;
2903
        int serialNumber = -1;
2904

    
2905
        try {
2906
            //check out DBConnection
2907
            conn = DBConnectionPool
2908
                    .getDBConnection("MetaCatServlet.getDocumentList");
2909
            serialNumber = conn.getCheckOutSerialNumber();
2910
            pstmt = conn.prepareStatement("SELECT docid, rev"
2911
                    + " FROM xml_documents ");
2912
            pstmt.execute();
2913
            rs = pstmt.getResultSet();
2914
            while (rs.next()) {
2915
                String docid = rs.getString(1);
2916
                String rev = rs.getString(2);
2917
                docList.add(docid + "." + rev);
2918
            }
2919
        } catch (SQLException e) {
2920
            logMetacat.error(
2921
                    "Exception in MetacatServlet.getDocumentList: "
2922
                            + e.getMessage());
2923
            throw e;
2924
        } finally {
2925
            try {
2926
                rs.close();
2927
                pstmt.close();
2928

    
2929
            } catch (SQLException se) {
2930
                logMetacat.error(
2931
                    "Exception in MetacatServlet.getDocumentList: "
2932
                            + se.getMessage());
2933
                throw se;
2934
            } finally {
2935
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2936
            }
2937
        }
2938
        return docList;
2939
    }
2940

    
2941
    /*
2942
     * A method to output setAccess action result
2943
     */
2944
    private void outputResponse(Vector successList, Vector errorList,
2945
            PrintWriter out)
2946
    {
2947
        boolean error = false;
2948
        boolean success = false;
2949
        // Output prolog
2950
        out.println(PROLOG);
2951
        // output success message
2952
        if (successList != null) {
2953
            for (int i = 0; i < successList.size(); i++) {
2954
                out.println(SUCCESS);
2955
                out.println((String) successList.elementAt(i));
2956
                out.println(SUCCESSCLOSE);
2957
                success = true;
2958
            }
2959
        }
2960
        // output error message
2961
        if (errorList != null) {
2962
            for (int i = 0; i < errorList.size(); i++) {
2963
                out.println(ERROR);
2964
                out.println((String) errorList.elementAt(i));
2965
                out.println(ERRORCLOSE);
2966
                error = true;
2967
            }
2968
        }
2969

    
2970
        // if no error and no success info, send a error that nothing happened
2971
        if (!error && !success) {
2972
            out.println(ERROR);
2973
            out.println("Nothing happend for setaccess action");
2974
            out.println(ERRORCLOSE);
2975
        }
2976
    }
2977
    
2978
    /**
2979
     * Method to get session table which store the session info
2980
     * @return
2981
     */
2982
    public static Hashtable getSessionHash()
2983
    {
2984
        return sessionHash;
2985
    }
2986
    
2987
    /*
2988
     * If the given docid only have one seperter, we need 
2989
     * append rev for it. The rev come from xml_documents
2990
     */
2991
    private static String appendRev(String docid) throws Exception
2992
    {
2993
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2994
        String newAccNum = null;
2995
        String separator = MetaCatUtil.getOption("accNumSeparator");
2996
        int firstIndex = docid.indexOf(separator);
2997
        int lastIndex = docid.lastIndexOf(separator);
2998
        if (firstIndex == lastIndex)
2999
        {
3000
            
3001
           //only one seperater
3002
            int rev = DBUtil.getLatestRevisionInDocumentTable(docid);
3003
            if (rev == -1)
3004
            {
3005
                throw new Exception("the requested docid '"
3006
                        + docid+ "' does not exist");
3007
            }
3008
            else
3009
            {
3010
                newAccNum = docid+ separator+ rev;
3011
            }
3012
        }
3013
        else
3014
        {
3015
            // in other suituation we don't change the docid
3016
            newAccNum = docid;
3017
        }
3018
        //logMetacat.debug("The docid will be read is "+newAccNum);
3019
        return newAccNum;
3020
    }
3021
}
(43-43/64)