Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2010 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author: jones $'
7
 *     '$Date: 2010-02-03 17:58:12 -0900 (Wed, 03 Feb 2010) $'
8
 * '$Revision: 5211 $'
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 */
24

    
25
package edu.ucsb.nceas.metacat;
26

    
27
import java.io.BufferedInputStream;
28
import java.io.File;
29
import java.io.FileInputStream;
30
import java.io.FileReader;
31
import java.io.IOException;
32
import java.io.OutputStreamWriter;
33
import java.io.PrintWriter;
34
import java.io.StringReader;
35
import java.io.Writer;
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.HashMap;
46
import java.util.Hashtable;
47
import java.util.Iterator;
48
import java.util.Map;
49
import java.util.Timer;
50
import java.util.Vector;
51
import java.util.zip.ZipEntry;
52
import java.util.zip.ZipOutputStream;
53

    
54
import javax.servlet.ServletContext;
55
import javax.servlet.ServletOutputStream;
56
import javax.servlet.http.HttpServletRequest;
57
import javax.servlet.http.HttpServletResponse;
58
import javax.servlet.http.HttpSession;
59

    
60
import org.apache.log4j.Logger;
61
import org.ecoinformatics.eml.EMLParser;
62

    
63
import au.com.bytecode.opencsv.CSVWriter;
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.metacat.accesscontrol.AccessControlException;
71
import edu.ucsb.nceas.metacat.accesscontrol.AccessControlForSingleFile;
72
import edu.ucsb.nceas.metacat.accesscontrol.AccessControlInterface;
73
import edu.ucsb.nceas.metacat.cart.CartManager;
74
import edu.ucsb.nceas.metacat.database.DBConnection;
75
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
76
import edu.ucsb.nceas.metacat.dataquery.DataQuery;
77
import edu.ucsb.nceas.metacat.properties.PropertyService;
78
import edu.ucsb.nceas.metacat.replication.ForceReplicationHandler;
79
import edu.ucsb.nceas.metacat.service.SessionService;
80
import edu.ucsb.nceas.metacat.service.XMLSchemaService;
81
import edu.ucsb.nceas.metacat.shared.MetacatUtilException;
82
import edu.ucsb.nceas.metacat.shared.ServiceException;
83
import edu.ucsb.nceas.metacat.spatial.SpatialHarvester;
84
import edu.ucsb.nceas.metacat.spatial.SpatialQuery;
85
import edu.ucsb.nceas.metacat.util.AuthUtil;
86
import edu.ucsb.nceas.metacat.util.DocumentUtil;
87
import edu.ucsb.nceas.metacat.util.MetacatUtil;
88
import edu.ucsb.nceas.metacat.util.RequestUtil;
89
import edu.ucsb.nceas.metacat.util.SystemUtil;
90
import edu.ucsb.nceas.utilities.FileUtil;
91
import edu.ucsb.nceas.utilities.LSIDUtil;
92
import edu.ucsb.nceas.utilities.ParseLSIDException;
93
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
94

    
95
/**
96
 * General entry point for the Metacat server which is called from various 
97
 * mechanisms such as the standard MetacatServlet class and the various web
98
 * service servlets such as RestServlet class.  All application logic should be
99
 * encapsulated in this class, and the calling classes should only contain
100
 * parameter marshaling and demarshaling code, delegating all else to this
101
 * MetacatHandler instance.
102
 * @author Matthew Jones
103
 */
104
public class MetacatHandler {
105

    
106
    private static boolean _sitemapScheduled = false;
107

    
108
    // Constants -- these should be final in a servlet    
109
    private static final String PROLOG = "<?xml version=\"1.0\"?>";
110
    private static final String SUCCESS = "<success>";
111
    private static final String SUCCESSCLOSE = "</success>";
112
    private static final String ERROR = "<error>";
113
    private static final String ERRORCLOSE = "</error>";
114
    
115
    private ServletContext servletContext;
116
	private Timer timer;
117
	
118
    public MetacatHandler(ServletContext servletContext, Timer timer) {
119
    	this.servletContext = servletContext;
120
    	this.timer = timer;
121
    }
122
    
123
    
124
    protected void handleDataquery(
125
            Hashtable<String, String[]> params,
126
            HttpServletResponse response,
127
            String sessionId) throws PropertyNotFoundException, IOException {
128
        
129
        DataQuery dq = null;
130
        if (sessionId != null) {
131
            dq = new DataQuery(sessionId);
132
        }
133
        else {
134
            dq = new DataQuery();
135
        }
136
        
137
        String dataqueryXML = (params.get("dataquery"))[0];
138

    
139
        ResultSet rs = null;
140
        try {
141
            rs = dq.executeQuery(dataqueryXML);
142
        } catch (Exception e) {
143
            //probably need to do something here
144
            e.printStackTrace();
145
            return;
146
        }
147
        
148
        //process the result set
149
        String qformat = "csv";
150
        String[] temp = params.get("qformat");
151
        if (temp != null && temp.length > 0) {
152
            qformat = temp[0];
153
        }
154
        String fileName = "query-results." + qformat;
155
        
156
        //get the results as csv file
157
        if (qformat != null && qformat.equalsIgnoreCase("csv")) {
158
            response.setContentType("text/csv");
159
            //response.setContentType("application/csv");
160
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
161
            
162
            Writer writer = new OutputStreamWriter(response.getOutputStream());
163
            CSVWriter csv = new CSVWriter(writer, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER);
164
            try {
165
                
166
                csv.writeAll(rs, true);
167
                
168
                csv.flush();
169
                response.flushBuffer();
170
                
171
                rs.close();
172
                
173
            } catch (SQLException e) {
174
                e.printStackTrace();
175
            }
176
            
177
            return;
178
        }
179
        
180
    }
181
    
182
    protected void handleEditCart(
183
            Hashtable<String, String[]> params,
184
            HttpServletResponse response,
185
            String sessionId) throws PropertyNotFoundException, IOException {
186
        
187
        CartManager cm = null;
188
        if (sessionId != null) {
189
            cm = new CartManager(sessionId);
190
        }
191
        else {
192
            cm = new CartManager();
193
        }
194
        
195
        String editOperation = (params.get("operation"))[0];
196
        
197
        String[] docids = params.get("docid");
198
        String[] field = params.get("field");
199
        String[] path = params.get("path");
200
        
201
        Map<String,String> fields = null;
202
        if (field != null && path != null) {
203
            fields = new HashMap<String,String>();
204
            fields.put(field[0], path[0]);
205
        }
206
        
207
        //TODO handle attribute map (metadata fields)
208
        cm.editCart(editOperation, docids, fields);
209
        
210
    }
211
    
212
    // ///////////////////////////// METACAT SPATIAL ///////////////////////////
213
    
214
    /**
215
     * handles all spatial queries -- these queries may include any of the
216
     * queries supported by the WFS / WMS standards
217
     * 
218
     * handleSQuery(out, params, response, username, groupnames, sess_id);
219
     */
220
    protected void handleSpatialQuery(PrintWriter out, Hashtable<String, String[]> params,
221
            HttpServletResponse response,
222
            String username, String[] groupnames,
223
            String sess_id) throws PropertyNotFoundException {
224
        
225
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
226
        
227
        if ( !PropertyService.getProperty("spatial.runSpatialOption").equals("true") ) {
228
            response.setContentType("text/html");
229
            out.println("<html> Metacat Spatial Option is turned off </html>");
230
            out.close();
231
            return ;
232
        }
233
        
234
        /*
235
         * Perform spatial query against spatial cache
236
         */
237
        float _xmax = Float.valueOf( (params.get("xmax"))[0] ).floatValue();
238
        float _ymax = Float.valueOf( (params.get("ymax"))[0] ).floatValue();
239
        float _xmin = Float.valueOf( (params.get("xmin"))[0] ).floatValue();
240
        float _ymin = Float.valueOf( (params.get("ymin"))[0] ).floatValue();
241
        SpatialQuery sq = new SpatialQuery();
242
        Vector<String> docids = sq.filterByBbox( _xmin, _ymin, _xmax, _ymax );
243
        // logMetacat.info(" --- Spatial Query completed. Passing on the SQuery
244
        // handler");
245
        // logMetacat.warn("\n\n ******* after spatial query, we've got " +
246
        // docids.size() + " docids \n\n");
247
        
248
        /*
249
         * Create an array matching docids
250
         */
251
        String [] docidArray = new String[docids.size()];
252
        docids.toArray(docidArray);
253
        
254
        /*
255
         * Create squery string
256
         */
257
        String squery = DocumentIdQuery.createDocidQuery( docidArray );
258
        // logMetacat.info("-----------\n" + squery + "\n------------------");
259
        String[] queryArray = new String[1];
260
        queryArray[0] = squery;
261
        params.put("query", queryArray);
262
        
263
        /*
264
         * Determine qformat
265
         */
266
        String[] qformatArray = new String[1];
267
        try {
268
            String _skin = (params.get("skin"))[0];
269
            qformatArray[0] = _skin;
270
        } catch (java.lang.NullPointerException e) {
271
            // should be "default" but keep this for backwards compatibility
272
            // with knp site
273
            logMetacat.warn("MetaCatServlet.handleSpatialQuery - No SKIN specified for metacat actions=spatial_query... defaulting to 'knp' skin !\n");
274
            qformatArray[0] = "knp";
275
        }
276
        params.put("qformat", qformatArray);
277
        
278
        // change the action
279
        String[] actionArray = new String[1];
280
        actionArray[0] = "squery";
281
        params.put("action", actionArray);
282
        
283
        /*
284
         * Pass the docids to the DBQuery contructor
285
         */
286
        // This is a hack to get the empty result set to show...
287
        // Otherwise dbquery sees no docidOverrides and does a full % percent
288
        // query
289
        if (docids.size() == 0)
290
            docids.add("");
291
        
292
        DBQuery queryobj = new DBQuery(docids);
293
        queryobj.findDocuments(response, out, params, username, groupnames, sess_id);
294
        
295
    }
296
    
297
    // LOGIN & LOGOUT SECTION
298
    /**
299
     * Handle the login request. Create a new session object. Do user
300
     * authentication through the session.
301
     */
302
    public void handleLoginAction(PrintWriter out, Hashtable<String, String[]> params,
303
            HttpServletRequest request, HttpServletResponse response) {
304
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
305
        AuthSession sess = null;
306
        
307
        if(params.get("username") == null){
308
            response.setContentType("text/xml");
309
            out.println("<?xml version=\"1.0\"?>");
310
            out.println("<error>");
311
            out.println("Username not specified");
312
            out.println("</error>");
313
            return;
314
        }
315
        
316
        // }
317
        
318
        if(params.get("password") == null){
319
            response.setContentType("text/xml");
320
            out.println("<?xml version=\"1.0\"?>");
321
            out.println("<error>");
322
            out.println("Password not specified");
323
            out.println("</error>");
324
            return;
325
        }
326
        
327
        String un = (params.get("username"))[0];
328
        logMetacat.info("MetaCatServlet.handleLoginAction - user " + un + " is trying to login");
329
        String pw = (params.get("password"))[0];
330
        
331
        String qformat = "xml";
332
        if (params.get("qformat") != null) {
333
            qformat = (params.get("qformat"))[0];
334
        }
335
        
336
        try {
337
            sess = new AuthSession();
338
        } catch (Exception e) {
339
            String errorMsg = "MetacatServlet.handleLoginAction - Problem in MetacatServlet.handleLoginAction() authenicating session: "
340
                + e.getMessage();
341
            logMetacat.error(errorMsg);
342
            out.println(errorMsg);
343
            return;
344
        }
345
        boolean isValid = sess.authenticate(request, un, pw);
346
        
347
        //if it is authernticate is true, store the session
348
        if (isValid) {
349
            HttpSession session = sess.getSessions();
350
            String id = session.getId();
351
            
352
            logMetacat.debug("MetaCatServlet.handleLoginAction - Store session id " + id
353
                    + " which has username" + session.getAttribute("username")
354
                    + " into hash in login method");
355
            try {
356
                SessionService.registerSession(id, 
357
                        (String) session.getAttribute("username"), 
358
                        (String[]) session.getAttribute("groupnames"), 
359
                        (String) session.getAttribute("password"), 
360
                        (String) session.getAttribute("name"));
361
            } catch (ServiceException se) {
362
                String errorMsg = "MetacatServlet.handleLoginAction - service problem registering session: "
363
                        + se.getMessage();
364
                logMetacat.error("MetaCatServlet.handleLoginAction - " + errorMsg);
365
                out.println(errorMsg);
366
                return;
367
            }           
368
        }
369
                
370
        // format and transform the output
371
        if (qformat.equals("xml")) {
372
            response.setContentType("text/xml");
373
            out.println(sess.getMessage());
374
        } else {
375
            try {
376
                DBTransform trans = new DBTransform();
377
                response.setContentType("text/html");
378
                trans.transformXMLDocument(sess.getMessage(),
379
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
380
                        out, null, null);
381
            } catch (Exception e) {               
382
                logMetacat.error("MetaCatServlet.handleLoginAction - General error"
383
                        + e.getMessage());
384
            }
385
        }
386
    }
387
    
388
    /**
389
     * Handle the logout request. Close the connection.
390
     */
391
    public void handleLogoutAction(PrintWriter out, Hashtable<String, String[]> params,
392
            HttpServletRequest request, HttpServletResponse response) {
393
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
394
        String qformat = "xml";
395
        if(params.get("qformat") != null){
396
            qformat = params.get("qformat")[0];
397
        }
398
        
399
        // close the connection
400
        HttpSession sess = request.getSession(false);
401
        logMetacat.info("MetaCatServlet.handleLogoutAction - After get session in logout request");
402
        if (sess != null) {
403
            logMetacat.info("MetaCatServlet.handleLogoutAction - The session id " + sess.getId()
404
            + " will be invalidate in logout action");
405
            logMetacat.info("MetaCatServlet.handleLogoutAction - The session contains user "
406
                    + sess.getAttribute("username")
407
                    + " will be invalidate in logout action");
408
            sess.invalidate();
409
            SessionService.unRegisterSession(sess.getId());
410
        }
411
        
412
        // produce output
413
        StringBuffer output = new StringBuffer();
414
        output.append("<?xml version=\"1.0\"?>");
415
        output.append("<logout>");
416
        output.append("User logged out");
417
        output.append("</logout>");
418
        
419
        //format and transform the output
420
        if (qformat.equals("xml")) {
421
            response.setContentType("text/xml");
422
            out.println(output.toString());
423
        } else {
424
            try {
425
                DBTransform trans = new DBTransform();
426
                response.setContentType("text/html");
427
                trans.transformXMLDocument(output.toString(),
428
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
429
                        out, null, null);
430
            } catch (Exception e) {
431
                logMetacat.error(
432
                        "MetaCatServlet.handleLogoutAction - General error: "
433
                        + e.getMessage());
434
            }
435
        }
436
    }
437
    
438
    // END OF LOGIN & LOGOUT SECTION
439
    
440
    // SQUERY & QUERY SECTION
441
    /**
442
     * Retreive the squery xml, execute it and display it
443
     *
444
     * @param out the output stream to the client
445
     * @param params the Hashtable of parameters that should be included in the
446
     *            squery.
447
     * @param response the response object linked to the client
448
     * @param conn the database connection
449
     */
450
    protected void handleSQuery(PrintWriter out, Hashtable<String, String[]> params,
451
            HttpServletResponse response, String user, String[] groups,
452
            String sessionid) throws PropertyNotFoundException {
453
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
454
        long squeryWarnLimit = Long.parseLong(PropertyService.getProperty("database.squeryTimeWarnLimit"));
455
        
456
        long startTime = System.currentTimeMillis();
457
        DBQuery queryobj = new DBQuery();
458
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
459
        long outPutTime = System.currentTimeMillis();
460
        long runTime = outPutTime - startTime;
461

    
462
        if (runTime > squeryWarnLimit) {
463
            logMetacat.warn("MetaCatServlet.handleSQuery - Long running squery.  Total time: " + runTime + 
464
                    " ms, squery: " + ((String[])params.get("query"))[0]);
465
        }
466
        logMetacat.debug("MetaCatServlet.handleSQuery - squery: " + ((String[])params.get("query"))[0] + 
467
                " ran in " + runTime + " ms");
468
    }
469
    
470
    /**
471
     * Create the xml query, execute it and display the results.
472
     *
473
     * @param out the output stream to the client
474
     * @param params the Hashtable of parameters that should be included in the
475
     *            squery.
476
     * @param response the response object linked to the client
477
     */
478
    protected void handleQuery(PrintWriter out, Hashtable<String, String[]> params,
479
            HttpServletResponse response, String user, String[] groups,
480
            String sessionid) throws PropertyNotFoundException {
481
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
482
        long queryWarnLimit = Long.parseLong(PropertyService.getProperty("database.queryTimeWarnLimit"));
483
        
484
        //create the query and run it
485
        String xmlquery = DBQuery.createSQuery(params);
486
        String[] queryArray = new String[1];
487
        queryArray[0] = xmlquery;
488
        params.put("query", queryArray);
489
        long startTime = System.currentTimeMillis();
490
        DBQuery queryobj = new DBQuery();
491
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
492
        long outPutTime = System.currentTimeMillis();
493
        long runTime = outPutTime -startTime;
494

    
495
        if (runTime > queryWarnLimit) {
496
            logMetacat.warn("MetaCatServlet.handleQuery - Long running squery.  Total time: " + runTime + 
497
                    " ms, squery: " + ((String[])params.get("query"))[0]);
498
        }
499
        logMetacat.debug("MetaCatServlet.handleQuery - query: " + ((String[])params.get("query"))[0] + 
500
                " ran in " + runTime + " ms");
501
    }
502
    
503
    // END OF SQUERY & QUERY SECTION
504
    
505
    //Export section
506
    /**
507
     * Handle the "export" request of data package from Metacat in zip format
508
     *
509
     * @param params the Hashtable of HTTP request parameters
510
     * @param response the HTTP response object linked to the client
511
     * @param user the username sent the request
512
     * @param groups the user's groupnames
513
     */
514
    protected void handleExportAction(Hashtable<String, String[]> params,
515
            HttpServletResponse response,
516
            String user, String[] groups, String passWord) {
517
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
518
        // Output stream
519
        ServletOutputStream out = null;
520
        // Zip output stream
521
        ZipOutputStream zOut = null;
522
        DBQuery queryObj = null;
523
        
524
        String[] docs = new String[10];
525
        String docId = "";
526
        
527
        try {
528
            // read the params
529
            if (params.containsKey("docid")) {
530
                docs = params.get("docid");
531
            }
532
            // Create a DBuery to handle export
533
            queryObj = new DBQuery();
534
            // Get the docid
535
            docId = docs[0];
536
            // Make sure the client specify docid
537
            if (docId == null || docId.equals("")) {
538
                response.setContentType("text/xml"); //MIME type
539
                // Get a printwriter
540
                PrintWriter pw = response.getWriter();
541
                // Send back message
542
                pw.println("<?xml version=\"1.0\"?>");
543
                pw.println("<error>");
544
                pw.println("You didn't specify requested docid");
545
                pw.println("</error>");
546
                // Close printwriter
547
                pw.close();
548
                return;
549
            }
550
            // Get output stream
551
            out = response.getOutputStream();
552
            response.setContentType("application/zip"); //MIME type
553
            response.setHeader("Content-Disposition",
554
                    "attachment; filename="
555
                    + docId + ".zip"); // Set the name of the zip file
556
            
557
            zOut = new ZipOutputStream(out);
558
            zOut = queryObj
559
                    .getZippedPackage(docId, out, user, groups, passWord);
560
            zOut.finish(); //terminate the zip file
561
            zOut.close(); //close the zip stream
562
            
563
        } catch (Exception e) {
564
            try {
565
                response.setContentType("text/xml"); //MIME type
566
                // Send error message back
567
                if (out != null) {
568
                    PrintWriter pw = new PrintWriter(out);
569
                    pw.println("<?xml version=\"1.0\"?>");
570
                    pw.println("<error>");
571
                    pw.println(e.getMessage());
572
                    pw.println("</error>");
573
                    // Close printwriter
574
                    pw.close();
575
                    // Close output stream
576
                    out.close();
577
                }
578
                // Close zip output stream
579
                if (zOut != null) {
580
                    zOut.close();
581
                }
582
            } catch (IOException ioe) {
583
                logMetacat.error("MetaCatServlet.handleExportAction - Problem with the servlet output: "
584
                        + ioe.getMessage());
585
            }
586
            
587
            logMetacat.error("MetaCatServlet.handleExportAction - General error: "
588
                    + e.getMessage());
589
            e.printStackTrace(System.out);
590
            
591
        }
592
        
593
    }
594
    
595
    /**
596
     * In eml2 document, the xml can have inline data and data was stripped off
597
     * and store in file system. This action can be used to read inline data
598
     * only
599
     *
600
     * @param params the Hashtable of HTTP request parameters
601
     * @param response the HTTP response object linked to the client
602
     * @param user the username sent the request
603
     * @param groups the user's groupnames
604
     */
605
    protected void handleReadInlineDataAction(Hashtable<String, String[]> params,
606
            HttpServletRequest request, HttpServletResponse response,
607
            String user, String passWord, String[] groups) {
608
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
609
        String[] docs = new String[10];
610
        String inlineDataId = null;
611
        String docId = "";
612
        ServletOutputStream out = null;
613
        
614
        try {
615
            // read the params
616
            if (params.containsKey("inlinedataid")) {
617
                docs = params.get("inlinedataid");
618
            }
619
            // Get the docid
620
            inlineDataId = docs[0];
621
            // Make sure the client specify docid
622
            if (inlineDataId == null || inlineDataId.equals("")) {
623
                throw new Exception("You didn't specify requested inlinedataid"); }
624
            
625
            // check for permission
626
            docId = 
627
                DocumentUtil.getDocIdWithoutRevFromInlineDataID(inlineDataId);
628
            PermissionController controller = new PermissionController(docId);
629
            // check top level read permission
630
            if (!controller.hasPermission(user, groups,
631
                    AccessControlInterface.READSTRING)) {
632
                throw new Exception("User " + user
633
                        + " doesn't have permission " + " to read document "
634
                        + docId);
635
            } else {
636
                //check data access level
637
                try {
638
                    Hashtable<String,String> unReadableInlineDataList =
639
                            PermissionController.getUnReadableInlineDataIdList(docId,
640
                            user, groups, false);
641
                    String inlineDataIdWithoutRev = DocumentUtil.getInlineDataIdWithoutRev(inlineDataId);
642
                    if (unReadableInlineDataList.containsValue(inlineDataIdWithoutRev)) {
643
                        throw new Exception("User " + user
644
                                + " doesn't have permission " + " to read inlinedata "
645
                                + inlineDataId);
646
                        
647
                    }//if
648
                }//try
649
                catch (Exception e) {
650
                    throw e;
651
                }//catch
652
            }//else
653
            
654
            // Get output stream
655
            out = response.getOutputStream();
656
            // read the inline data from the file
657
            String inlinePath = PropertyService.getProperty("application.inlinedatafilepath");
658
            File lineData = new File(inlinePath, inlineDataId);
659
            FileInputStream input = new FileInputStream(lineData);
660
            byte[] buffer = new byte[4 * 1024];
661
            int bytes = input.read(buffer);
662
            while (bytes != -1) {
663
                out.write(buffer, 0, bytes);
664
                bytes = input.read(buffer);
665
            }
666
            out.close();
667
            
668
            EventLog.getInstance().log(request.getRemoteAddr(), user,
669
                    inlineDataId, "readinlinedata");
670
        } catch (Exception e) {
671
            try {
672
                PrintWriter pw = null;
673
                // Send error message back
674
                if (out != null) {
675
                    pw = new PrintWriter(out);
676
                } else {
677
                    pw = response.getWriter();
678
                }
679
                pw.println("<?xml version=\"1.0\"?>");
680
                pw.println("<error>");
681
                pw.println(e.getMessage());
682
                pw.println("</error>");
683
                // Close printwriter
684
                pw.close();
685
                // Close output stream if out is not null
686
                if (out != null) {
687
                    out.close();
688
                }
689
            } catch (IOException ioe) {
690
                logMetacat.error("MetaCatServlet.handleReadInlineDataAction - Problem with the servlet output: "
691
                        + ioe.getMessage());
692
            }
693
            logMetacat.error("MetaCatServlet.handleReadInlineDataAction - General error: "
694
                    + e.getMessage());
695
        }
696
    }
697
    
698
    /**
699
     * Handle the "read" request of metadata/data files from Metacat or any
700
     * files from Internet; transformed metadata XML document into HTML
701
     * presentation if requested; zip files when more than one were requested.
702
     *
703
     * @param params the Hashtable of HTTP request parameters
704
     * @param request the HTTP request object linked to the client
705
     * @param response the HTTP response object linked to the client
706
     * @param user the username sent the request
707
     * @param groups the user's groupnames
708
     */
709
    public void handleReadAction(Hashtable<String, String[]> params, HttpServletRequest request,
710
            HttpServletResponse response, String user, String passWord,
711
            String[] groups) {
712
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
713
        ServletOutputStream out = null;
714
        ZipOutputStream zout = null;
715
        PrintWriter pw = null;
716
        boolean zip = false;
717
        boolean withInlineData = true;
718
        
719
        try {
720
            String[] docs = new String[0];
721
            String docid = "";
722
            String qformat = "";
723
            String abstrpath = null;
724
            
725
            // read the params
726
            if (params.containsKey("docid")) {
727
                docs = params.get("docid");
728
            }
729
            if (params.containsKey("qformat")) {
730
                qformat = params.get("qformat")[0];
731
            }
732
            // the param for only metadata (eml)
733
            // we don't support read a eml document without inline data now.
734
            /*if (params.containsKey("inlinedata")) {
735
             
736
                String inlineData = ((String[]) params.get("inlinedata"))[0];
737
                if (inlineData.equalsIgnoreCase("false")) {
738
                    withInlineData = false;
739
                }
740
            }*/
741
            if ((docs.length > 1) || qformat.equals("zip")) {
742
                zip = true;
743
                out = response.getOutputStream();
744
                response.setContentType("application/zip"); //MIME type
745
                zout = new ZipOutputStream(out);
746
            }
747
            // go through the list of docs to read
748
            for (int i = 0; i < docs.length; i++) {
749
                String providedFileName = null;
750
                if (params.containsKey(docs[i])) {
751
                    providedFileName = params.get(docs[i])[0];
752
                }
753
                try {
754
                    
755
                    URL murl = new URL(docs[i]);
756
                    Hashtable<String,String> murlQueryStr = MetacatUtil.parseQuery(
757
                            murl.getQuery());
758
                    // case docid="http://.../?docid=aaa"
759
                    // or docid="metacat://.../?docid=bbb"
760
                    if (murlQueryStr.containsKey("docid")) {
761
                        // get only docid, eliminate the rest
762
                        docid = murlQueryStr.get("docid");
763
                        if (zip) {
764
                            addDocToZip(request, docid, providedFileName, zout, user, groups);
765
                        } else {
766
                            readFromMetacat(request, response, docid, qformat,
767
                                    abstrpath, user, groups, zip, zout,
768
                                    withInlineData, params);
769
                        }
770
                        
771
                        // case docid="http://.../filename"
772
                    } else {
773
                        docid = docs[i];
774
                        if (zip) {
775
                            addDocToZip(request, docid, providedFileName, zout, user, groups);
776
                        } else {
777
                            readFromURLConnection(response, docid);
778
                        }
779
                    }
780
                    
781
                } catch (MalformedURLException mue) {
782
                    docid = docs[i];
783
                    if (zip) {
784
                        addDocToZip(request, docid, providedFileName, zout, user, groups);
785
                    } else {
786
                        readFromMetacat(request, response, docid, qformat,
787
                                abstrpath, user, groups, zip, zout,
788
                                withInlineData, params);
789
                    }
790
                }
791
            }
792
            
793
            if (zip) {
794
                zout.finish(); //terminate the zip file
795
                zout.close(); //close the zip stream
796
            }
797
            
798
        } catch (McdbDocNotFoundException notFoundE) {
799
            // To handle doc not found exception
800
            // the docid which didn't be found
801
            String notFoundDocId = notFoundE.getUnfoundDocId();
802
            String notFoundRevision = notFoundE.getUnfoundRevision();
803
            logMetacat.warn("MetaCatServlet.handleReadAction - Missed id: " + notFoundDocId);
804
            logMetacat.warn("MetaCatServlet.handleReadAction - Missed rev: " + notFoundRevision);
805
            try {
806
                // read docid from remote server
807
                readFromRemoteMetaCat(response, notFoundDocId,
808
                        notFoundRevision, user, passWord, out, zip, zout);
809
                // Close zout outputstream
810
                if (zout != null) {
811
                    zout.close();
812
                }
813
                // close output stream
814
                if (out != null) {
815
                    out.close();
816
                }
817
                
818
            } catch (Exception exc) {
819
                logMetacat.error("MetaCatServlet.handleReadAction - General error: "
820
                        + exc.getMessage());
821
                try {
822
                    if (out != null) {
823
                        response.setContentType("text/xml");
824
                        // Send back error message by printWriter
825
                        pw = new PrintWriter(out);
826
                        pw.println("<?xml version=\"1.0\"?>");
827
                        pw.println("<error>");
828
                        pw.println(notFoundE.getMessage());
829
                        pw.println("</error>");
830
                        pw.close();
831
                        out.close();
832
                        
833
                    } else {
834
                        response.setContentType("text/xml"); //MIME type
835
                        // Send back error message if out = null
836
                        if (pw == null) {
837
                            // If pw is null, open the respnose
838
                            pw = response.getWriter();
839
                        }
840
                        pw.println("<?xml version=\"1.0\"?>");
841
                        pw.println("<error>");
842
                        pw.println(notFoundE.getMessage());
843
                        pw.println("</error>");
844
                        pw.close();
845
                    }
846
                    // close zout
847
                    if (zout != null) {
848
                        zout.close();
849
                    }
850
                } catch (IOException ie) {
851
                    logMetacat.error("MetaCatServlet.handleReadAction - Problem with the servlet output: "
852
                            + ie.getMessage());
853
                }
854
            }
855
        } catch (Exception e) {
856
            try {
857
                
858
                if (out != null) {
859
                    response.setContentType("text/xml"); //MIME type
860
                    pw = new PrintWriter(out);
861
                    pw.println("<?xml version=\"1.0\"?>");
862
                    pw.println("<error>");
863
                    pw.println(e.getMessage());
864
                    pw.println("</error>");
865
                    pw.close();
866
                    out.close();
867
                } else {
868
                    response.setContentType("text/xml"); //MIME type
869
                    // Send back error message if out = null
870
                    if (pw == null) {
871
                        pw = response.getWriter();
872
                    }
873
                    pw.println("<?xml version=\"1.0\"?>");
874
                    pw.println("<error>");
875
                    pw.println(e.getMessage());
876
                    pw.println("</error>");
877
                    pw.close();
878
                    
879
                }
880
                // Close zip output stream
881
                if (zout != null) {
882
                    zout.close();
883
                }
884
                
885
            } catch (Exception e2) {
886
                logMetacat.error("MetaCatServlet.handleReadAction - Problem with the servlet output: "
887
                        + e2.getMessage());
888
                e2.printStackTrace(System.out);
889
                
890
            }
891
            
892
            logMetacat.error("MetaCatServlet.handleReadAction - General error: "
893
                    + e.getMessage());
894
            //e.printStackTrace(System.out);
895
        }
896
    }
897
    
898
    /** read metadata or data from Metacat
899
     */
900
    private void readFromMetacat(HttpServletRequest request,
901
            HttpServletResponse response, String docid, String qformat,
902
            String abstrpath, String user, String[] groups, boolean zip,
903
            ZipOutputStream zout, boolean withInlineData, Hashtable<String, String[]> params)
904
            throws ClassNotFoundException, IOException, SQLException,
905
            McdbException, Exception {
906
        
907
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
908
        try {
909
            
910
            if (docid.startsWith("urn:")) {
911
                docid = LSIDUtil.getDocId(docid, true);                 
912
            }
913
            
914
            // here is hack for handle docid=john.10(in order to tell mike.jim.10.1
915
            // mike.jim.10, we require to provide entire docid with rev). But
916
            // some old client they only provide docid without rev, so we need
917
            // to handle this suituation. First we will check how many
918
            // seperator here, if only one, we will append the rev in xml_documents
919
            // to the id.
920
            docid = appendRev(docid);
921
            
922
            DocumentImpl doc = new DocumentImpl(docid);
923
            
924
            //check the permission for read
925
            if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
926
                Exception e = new Exception("User " + user
927
                        + " does not have permission"
928
                        + " to read the document with the docid " + docid);
929
                
930
                throw e;
931
            }
932
            
933
            if (doc.getRootNodeID() == 0) {
934
                // this is data file
935
                String filepath = PropertyService.getProperty("application.datafilepath");
936
                if (!filepath.endsWith("/")) {
937
                    filepath += "/";
938
                }
939
                String filename = filepath + docid;
940
                FileInputStream fin = null;
941
                fin = new FileInputStream(filename);
942
                
943
                //MIME type
944
                String contentType = servletContext.getMimeType(filename);
945
                if (contentType == null) {
946
                    ContentTypeProvider provider = new ContentTypeProvider(
947
                            docid);
948
                    contentType = provider.getContentType();
949
                    logMetacat.info("MetaCatServlet.readFromMetacat - Final contenttype is: "
950
                            + contentType);
951
                }
952
                
953
                response.setContentType(contentType);
954
                // if we decide to use "application/octet-stream" for all data
955
                // returns
956
                // response.setContentType("application/octet-stream");
957

    
958
                // check for the existence of a metadatadocid parameter,
959
                // if this is sent, then send a filename which contains both
960
                // the metadata docid and the data docid, so the link with
961
                // metadata is explicitly encoded in the filename.
962
                String metadatadocid = null;
963
                Vector<String> nameparts = new Vector<String>();
964

    
965
                if(params.containsKey("metadatadocid")) {
966
                    metadatadocid = params.get("metadatadocid")[0];
967
                }
968
                if (metadatadocid != null && !metadatadocid.equals("")) {
969
                    nameparts.add(metadatadocid);
970
                }
971
                // we'll always have the docid, include it in the name
972
                String doctype = doc.getDoctype();
973
                                // TODO: fix this to lookup the associated FGDC metadata document,
974
                                // and grab the doctype tag for it.  These should be set to something 
975
                                // consistent, not 'metadata' as it stands...
976
                //if (!doctype.equals("metadata")) {
977
                //    nameparts.add(docid);
978
                //} 
979
                                nameparts.add(docid);
980
                // Set the name of the data file to the entity name plus docid,
981
                // or if that is unavailable, use the docid alone
982
                String docname = doc.getDocname();
983
                if (docname != null && !docname.equals("")) {
984
                    nameparts.add(docname); 
985
                }
986
                // combine the name elements with a dash, using a 'join' equivalent
987
                String outputname = null;
988
                String delimiter = "-";
989
                Iterator<String> iter = nameparts.iterator();
990
                StringBuffer buffer = new StringBuffer(iter.next());
991
                while (iter.hasNext()) buffer.append(delimiter).append(iter.next());
992
                outputname = buffer.toString();    
993
                
994
                response.setHeader("Content-Disposition",
995
                        "attachment; filename=\"" + outputname + "\"");
996
                
997
                try {
998
                    ServletOutputStream out = response.getOutputStream();
999
                    byte[] buf = new byte[4 * 1024]; // 4K buffer
1000
                    int b = fin.read(buf);
1001
                    while (b != -1) {
1002
                        out.write(buf, 0, b);
1003
                        b = fin.read(buf);
1004
                    }
1005
                } finally {
1006
                    if (fin != null) fin.close();
1007
                }
1008
                
1009
            } else {
1010
                // this is metadata doc
1011
                ServletOutputStream streamOut = response.getOutputStream();
1012
                if (qformat.equals("xml") || qformat.equals("")) {
1013
                    // if equals "", that means no qformat is specified. hence
1014
                    // by default the document should be returned in xml format
1015
                    // set content type first
1016
                    response.setContentType("text/xml"); //MIME type
1017
                    response.setHeader("Content-Disposition",
1018
                            "attachment; filename=" + docid + ".xml");
1019
                    
1020
                    // Try to get the metadata file from disk. If it isn't
1021
                    // found, create it from the db and write it to disk then.
1022
                    try {
1023
                        PrintWriter out = new PrintWriter(streamOut);
1024
                        doc.toXml(out, user, groups, withInlineData);               
1025
                    } catch (Exception e) {
1026
                        // any exceptions in reading the xml from disc, and we go back to the
1027
                        // old way of creating the xml directly.
1028
                        logMetacat.error("MetaCatServlet.readFromMetacat - could not read from document file " + docid 
1029
                                + ": " + e.getMessage());
1030
                        PrintWriter out = new PrintWriter(streamOut);
1031
                        doc.toXmlFromDb(out, user, groups, withInlineData);
1032
                    }
1033
                } else {
1034
                    // TODO MCD, this should read from disk as well?
1035
                    //*** This is a metadata doc, to be returned in a skin/custom format.
1036
                    //*** Add param to indicate if public has read access or not.
1037
                    if (!user.equals("public")) {
1038
                        if (DocumentImpl.hasReadPermission("public", null, docid))
1039
                            params.put("publicRead", new String[] {"true"});
1040
                        else
1041
                            params.put("publicRead", new String[] {"false"});
1042
                    }
1043
                    
1044
                    response.setContentType("text/html"); //MIME type
1045
                    PrintWriter out = new PrintWriter(streamOut);
1046
                    
1047
                    // Look up the document type
1048
                    String doctype = doc.getDoctype();
1049
                    // Transform the document to the new doctype
1050
                    DBTransform dbt = new DBTransform();
1051
                    dbt.transformXMLDocument(doc.toString(user, groups,
1052
                            withInlineData), doctype, "-//W3C//HTML//EN",
1053
                            qformat, out, params, null);
1054
                }
1055
                
1056
            }
1057
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1058
                    docid, "read");
1059
        } catch (Exception except) {
1060
            throw except;
1061
        }
1062
    }
1063
    
1064
    /**
1065
     * read data from URLConnection
1066
     */
1067
    private void readFromURLConnection(HttpServletResponse response,
1068
            String docid) throws IOException, MalformedURLException {
1069
        ServletOutputStream out = response.getOutputStream();
1070
        String contentType = servletContext.getMimeType(docid); //MIME type
1071
        if (contentType == null) {
1072
            if (docid.endsWith(".xml")) {
1073
                contentType = "text/xml";
1074
            } else if (docid.endsWith(".css")) {
1075
                contentType = "text/css";
1076
            } else if (docid.endsWith(".dtd")) {
1077
                contentType = "text/plain";
1078
            } else if (docid.endsWith(".xsd")) {
1079
                contentType = "text/xml";
1080
            } else if (docid.endsWith("/")) {
1081
                contentType = "text/html";
1082
            } else {
1083
                File f = new File(docid);
1084
                if (f.isDirectory()) {
1085
                    contentType = "text/html";
1086
                } else {
1087
                    contentType = "application/octet-stream";
1088
                }
1089
            }
1090
        }
1091
        response.setContentType(contentType);
1092
        // if we decide to use "application/octet-stream" for all data returns
1093
        // response.setContentType("application/octet-stream");
1094
        
1095
        // this is http url
1096
        URL url = new URL(docid);
1097
        BufferedInputStream bis = null;
1098
        try {
1099
            bis = new BufferedInputStream(url.openStream());
1100
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1101
            int b = bis.read(buf);
1102
            while (b != -1) {
1103
                out.write(buf, 0, b);
1104
                b = bis.read(buf);
1105
            }
1106
        } finally {
1107
            if (bis != null) bis.close();
1108
        }
1109
        
1110
    }
1111
    
1112
    /**
1113
     * read file/doc and write to ZipOutputStream
1114
     *
1115
     * @param docid
1116
     * @param zout
1117
     * @param user
1118
     * @param groups
1119
     * @throws ClassNotFoundException
1120
     * @throws IOException
1121
     * @throws SQLException
1122
     * @throws McdbException
1123
     * @throws Exception
1124
     */
1125
    private void addDocToZip(HttpServletRequest request, String docid, String providedFileName,
1126
            ZipOutputStream zout, String user, String[] groups) throws
1127
            ClassNotFoundException, IOException, SQLException, McdbException,
1128
            Exception {
1129
        byte[] bytestring = null;
1130
        ZipEntry zentry = null;
1131
        
1132
        try {
1133
            URL url = new URL(docid);
1134
            
1135
            // this http url; read from URLConnection; add to zip
1136
            //use provided file name if we have one
1137
            if (providedFileName != null && providedFileName.length() > 1) {
1138
                zentry = new ZipEntry(providedFileName);
1139
            }
1140
            else {
1141
                zentry = new ZipEntry(docid);
1142
            }
1143
            zout.putNextEntry(zentry);
1144
            BufferedInputStream bis = null;
1145
            try {
1146
                bis = new BufferedInputStream(url.openStream());
1147
                byte[] buf = new byte[4 * 1024]; // 4K buffer
1148
                int b = bis.read(buf);
1149
                while (b != -1) {
1150
                    zout.write(buf, 0, b);
1151
                    b = bis.read(buf);
1152
                }
1153
            } finally {
1154
                if (bis != null) bis.close();
1155
            }
1156
            zout.closeEntry();
1157
            
1158
        } catch (MalformedURLException mue) {
1159
            
1160
            // this is metacat doc (data file or metadata doc)
1161
            try {
1162
                DocumentImpl doc = new DocumentImpl(docid);
1163
                
1164
                //check the permission for read
1165
                if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1166
                    Exception e = new Exception("User " + user
1167
                            + " does not have "
1168
                            + "permission to read the document with the docid "
1169
                            + docid);
1170
                    throw e;
1171
                }
1172
                
1173
                if (doc.getRootNodeID() == 0) {
1174
                    // this is data file; add file to zip
1175
                    String filepath = PropertyService.getProperty("application.datafilepath");
1176
                    if (!filepath.endsWith("/")) {
1177
                        filepath += "/";
1178
                    }
1179
                    String filename = filepath + docid;
1180
                    FileInputStream fin = null;
1181
                    fin = new FileInputStream(filename);
1182
                    try {
1183
                        //use provided file name if we have one
1184
                        if (providedFileName != null && providedFileName.length() > 1) {
1185
                            zentry = new ZipEntry(providedFileName);
1186
                        }
1187
                        else {
1188
                            zentry = new ZipEntry(docid);
1189
                        }
1190
                        zout.putNextEntry(zentry);
1191
                        byte[] buf = new byte[4 * 1024]; // 4K buffer
1192
                        int b = fin.read(buf);
1193
                        while (b != -1) {
1194
                            zout.write(buf, 0, b);
1195
                            b = fin.read(buf);
1196
                        }
1197
                    } finally {
1198
                        if (fin != null) fin.close();
1199
                    }
1200
                    zout.closeEntry();
1201
                    
1202
                } else {
1203
                    // this is metadata doc; add doc to zip
1204
                    bytestring = doc.toString().getBytes();
1205
                    //use provided file name if given
1206
                    if (providedFileName != null && providedFileName.length() > 1) {
1207
                        zentry = new ZipEntry(providedFileName);
1208
                    }
1209
                    else {
1210
                        zentry = new ZipEntry(docid + ".xml");
1211
                    }
1212
                    zentry.setSize(bytestring.length);
1213
                    zout.putNextEntry(zentry);
1214
                    zout.write(bytestring, 0, bytestring.length);
1215
                    zout.closeEntry();
1216
                }
1217
                EventLog.getInstance().log(request.getRemoteAddr(), user,
1218
                        docid, "read");
1219
            } catch (Exception except) {
1220
                throw except;
1221
            }
1222
        }
1223
    }
1224
    
1225
    /**
1226
     * If metacat couldn't find a data file or document locally, it will read
1227
     * this docid from its home server. This is for the replication feature
1228
     */
1229
    private void readFromRemoteMetaCat(HttpServletResponse response,
1230
            String docid, String rev, String user, String password,
1231
            ServletOutputStream out, boolean zip, ZipOutputStream zout)
1232
            throws Exception {
1233
        // Create a object of RemoteDocument, "" is for zipEntryPath
1234
        RemoteDocument remoteDoc = new RemoteDocument(docid, rev, user,
1235
                password, "");
1236
        String docType = remoteDoc.getDocType();
1237
        // Only read data file
1238
        if (docType.equals("BIN")) {
1239
            // If it is zip format
1240
            if (zip) {
1241
                remoteDoc.readDocumentFromRemoteServerByZip(zout);
1242
            } else {
1243
                if (out == null) {
1244
                    out = response.getOutputStream();
1245
                }
1246
                response.setContentType("application/octet-stream");
1247
                remoteDoc.readDocumentFromRemoteServer(out);
1248
            }
1249
        } else {
1250
            throw new Exception("Docid: " + docid + "." + rev
1251
                    + " couldn't find");
1252
        }
1253
    }
1254
    
1255
    /**
1256
     * Handle the database putdocument request and write an XML document to the
1257
     * database connection
1258
     */
1259
    public void handleInsertOrUpdateAction(HttpServletRequest request,
1260
            HttpServletResponse response, PrintWriter out, Hashtable<String, String[]> params,
1261
            String user, String[] groups) {
1262
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1263
        DBConnection dbConn = null;
1264
        int serialNumber = -1;
1265
        String output = "";
1266
        String qformat = null;
1267
        if(params.containsKey("qformat"))
1268
        {
1269
          qformat = params.get("qformat")[0];
1270
        }
1271
        
1272
        if(params.get("docid") == null){
1273
            out.println("<?xml version=\"1.0\"?>");
1274
            out.println("<error>");
1275
            out.println("Docid not specified");
1276
            out.println("</error>");
1277
            logMetacat.error("MetaCatServlet.handleInsertOrUpdateAction - Docid not specified");
1278
            return;
1279
        }
1280
        
1281
        try {
1282
            if (!AuthUtil.canInsertOrUpdate(user, groups)) {
1283
                out.println("<?xml version=\"1.0\"?>");
1284
                out.println("<error>");
1285
                out.println("User '" + user + "' not allowed to insert and update");
1286
                out.println("</error>");
1287
                logMetacat.error("MetaCatServlet.handleInsertOrUpdateAction - User '" + user + "' not allowed to insert and update");
1288
                return;
1289
            }
1290
        } catch (MetacatUtilException ue) {
1291
            logMetacat.error("MetaCatServlet.handleInsertOrUpdateAction - Could not determine if user could insert or update: "
1292
                    + ue.getMessage());
1293
        }
1294
        
1295
        try {
1296
            // Get the document indicated
1297
            logMetacat.debug("MetaCatServlet.handleInsertOrUpdateAction - params: " + params.toString());
1298
            
1299
            String[] doctext = params.get("doctext");
1300
            String pub = null;
1301
            if (params.containsKey("public")) {
1302
                pub = params.get("public")[0];
1303
            }
1304
            
1305
            StringReader dtd = null;
1306
            if (params.containsKey("dtdtext")) {
1307
                String[] dtdtext = params.get("dtdtext");
1308
                try {
1309
                    if (!dtdtext[0].equals("")) {
1310
                        dtd = new StringReader(dtdtext[0]);
1311
                    }
1312
                } catch (NullPointerException npe) {
1313
                }
1314
            }
1315
            
1316
            if(doctext == null){
1317
                out.println("<?xml version=\"1.0\"?>");
1318
                out.println("<error>");
1319
                out.println("Document text not submitted");
1320
                out.println("</error>");
1321
                return;
1322
            }
1323
            
1324
            logMetacat.debug("MetaCatServlet.handleInsertOrUpdateAction - the xml document in metacat servlet (before parsing):\n" + doctext[0]);
1325
            StringReader xmlReader = new StringReader(doctext[0]);
1326
            boolean validate = false;
1327
            DocumentImplWrapper documentWrapper = null;
1328
            try {
1329
                // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ...
1330
                // >
1331
                // in order to decide whether to use validation parser
1332
                validate = needDTDValidation(xmlReader);
1333
                if (validate) {
1334
                    // set a dtd base validation parser
1335
                    String rule = DocumentImpl.DTD;
1336
                    documentWrapper = new DocumentImplWrapper(rule, validate);
1337
                } else {
1338
                    
1339
                    String namespace = XMLSchemaService.findDocumentNamespace(xmlReader);
1340
                    
1341
                    if (namespace != null) {
1342
                        if (namespace.compareTo(DocumentImpl.EML2_0_0NAMESPACE) == 0
1343
                                || namespace.compareTo(
1344
                                DocumentImpl.EML2_0_1NAMESPACE) == 0) {
1345
                            // set eml2 base     validation parser
1346
                            String rule = DocumentImpl.EML200;
1347
                            // using emlparser to check id validation
1348
                            @SuppressWarnings("unused")
1349
                            EMLParser parser = new EMLParser(doctext[0]);
1350
                            documentWrapper = new DocumentImplWrapper(rule, true);
1351
                        } else if (namespace.compareTo(
1352
                                DocumentImpl.EML2_1_0NAMESPACE) == 0) {
1353
                            // set eml2 base validation parser
1354
                            String rule = DocumentImpl.EML210;
1355
                            // using emlparser to check id validation
1356
                            @SuppressWarnings("unused")
1357
                            EMLParser parser = new EMLParser(doctext[0]);
1358
                            documentWrapper = new DocumentImplWrapper(rule, true);
1359
                        } else {
1360
                            // set schema base validation parser
1361
                            String rule = DocumentImpl.SCHEMA;
1362
                            documentWrapper = new DocumentImplWrapper(rule, true);
1363
                        }
1364
                    } else {
1365
                        documentWrapper = new DocumentImplWrapper("", false);
1366
                    }
1367
                }
1368
                
1369
                String[] action = params.get("action");
1370
                String[] docid = params.get("docid");
1371
                String newdocid = null;
1372
                
1373
                String doAction = null;
1374
                if (action[0].equals("insert") || action[0].equals("insertmultipart")) {
1375
                    doAction = "INSERT";
1376
                } else if (action[0].equals("update")) {
1377
                    doAction = "UPDATE";
1378
                }
1379
                
1380
                try {
1381
                    // get a connection from the pool
1382
                    dbConn = DBConnectionPool
1383
                            .getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1384
                    serialNumber = dbConn.getCheckOutSerialNumber();
1385
                    
1386
                    // write the document to the database and disk
1387
                    String accNumber = docid[0];
1388
                    logMetacat.debug("MetaCatServlet.handleInsertOrUpdateAction - " + doAction + " "
1389
                            + accNumber + "...");
1390
                    if (accNumber == null || accNumber.equals("")) {
1391
                        logMetacat.warn("MetaCatServlet.handleInsertOrUpdateAction - writing with null acnumber");
1392
                        newdocid = documentWrapper.write(dbConn, doctext[0], pub, dtd,
1393
                                doAction, null, user, groups);
1394
                        EventLog.getInstance().log(request.getRemoteAddr(),
1395
                                user, "", action[0]);
1396
                        } else {
1397
                            newdocid = documentWrapper.write(dbConn, doctext[0], pub, dtd,
1398
                                    doAction, accNumber, user, groups);
1399
                            
1400
                            EventLog.getInstance().log(request.getRemoteAddr(),
1401
                                    user, accNumber, action[0]);
1402
                        }
1403
                } finally {
1404
                    // Return db connection
1405
                    DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1406
                }
1407
                
1408
                // set content type and other response header fields first
1409
                //response.setContentType("text/xml");
1410
                output += "<?xml version=\"1.0\"?>";
1411
                output += "<success>";
1412
                output += "<docid>" + newdocid + "</docid>";
1413
                output += "</success>";
1414
                
1415
            } catch (NullPointerException npe) {
1416
                //response.setContentType("text/xml");
1417
                output += "<?xml version=\"1.0\"?>";
1418
                output += "<error>";
1419
                output += npe.getMessage();
1420
                output += "</error>";
1421
                logMetacat.warn("MetaCatServlet.handleInsertOrUpdateAction - Null pointer error when writing eml document to the database: " + npe.getMessage());
1422
                npe.printStackTrace();
1423
            }
1424
        } catch (Exception e) {
1425
            //response.setContentType("text/xml");
1426
            output += "<?xml version=\"1.0\"?>";
1427
            output += "<error>";
1428
            output += e.getMessage();
1429
            output += "</error>";
1430
            logMetacat.warn("MetaCatServlet.handleInsertOrUpdateAction - General error when writing eml document to the database: " + e.getMessage());
1431
            e.printStackTrace();
1432
        }
1433
        
1434
        if (qformat == null || qformat.equals("xml")) {
1435
            response.setContentType("text/xml");
1436
            out.println(output);
1437
        } else {
1438
            try {
1439
                DBTransform trans = new DBTransform();
1440
                response.setContentType("text/html");
1441
                trans.transformXMLDocument(output,
1442
                        "message", "-//W3C//HTML//EN", qformat,
1443
                        out, null, null);
1444
            } catch (Exception e) {
1445
                
1446
                logMetacat.error("MetaCatServlet.handleInsertOrUpdateAction - General error: "
1447
                        + e.getMessage());
1448
            }
1449
        }
1450
    }
1451
    
1452
    /**
1453
     * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... > in
1454
     * order to decide whether to use validation parser
1455
     */
1456
    private static boolean needDTDValidation(StringReader xmlreader)
1457
    throws IOException {
1458
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1459
        StringBuffer cbuff = new StringBuffer();
1460
        java.util.Stack<String> st = new java.util.Stack<String>();
1461
        boolean validate = false;
1462
        boolean commented = false;
1463
        int c;
1464
        int inx;
1465
        
1466
        // read from the stream until find the keywords
1467
        while ((st.empty() || st.size() < 4) && ((c = xmlreader.read()) != -1)) {
1468
            cbuff.append((char) c);
1469
            
1470
            if ((inx = cbuff.toString().indexOf("<!--")) != -1) {
1471
                commented = true;
1472
            }
1473
            
1474
            // "<!DOCTYPE" keyword is found; put it in the stack
1475
            if ((inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1) {
1476
                cbuff = new StringBuffer();
1477
                st.push("<!DOCTYPE");
1478
            }
1479
            // "PUBLIC" keyword is found; put it in the stack
1480
            if ((inx = cbuff.toString().indexOf("PUBLIC")) != -1) {
1481
                cbuff = new StringBuffer();
1482
                st.push("PUBLIC");
1483
            }
1484
            // "SYSTEM" keyword is found; put it in the stack
1485
            if ((inx = cbuff.toString().indexOf("SYSTEM")) != -1) {
1486
                cbuff = new StringBuffer();
1487
                st.push("SYSTEM");
1488
            }
1489
            // ">" character is found; put it in the stack
1490
            // ">" is found twice: fisrt from <?xml ...?>
1491
            // and second from <!DOCTYPE ... >
1492
            if ((inx = cbuff.toString().indexOf(">")) != -1) {
1493
                cbuff = new StringBuffer();
1494
                st.push(">");
1495
            }
1496
        }
1497
        
1498
        // close the stream
1499
        xmlreader.reset();
1500
        
1501
        // check the stack whether it contains the keywords:
1502
        // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1503
        if (st.size() == 4) {
1504
            if ((st.pop()).equals(">")
1505
            && ((st.peek()).equals("PUBLIC") | (st.pop()).equals("SYSTEM"))
1506
                    && (st.pop()).equals("<!DOCTYPE")) {
1507
                validate = true && !commented;
1508
            }
1509
        }
1510
        
1511
        logMetacat.info("MetaCatServlet.needDTDValidation - Validation for dtd is " + validate);
1512
        return validate;
1513
    }
1514
    
1515
    // END OF INSERT/UPDATE SECTION
1516
    
1517
    /**
1518
     * Handle the database delete request and delete an XML document from the
1519
     * database connection
1520
     */
1521
    public void handleDeleteAction(PrintWriter out, Hashtable<String, String[]> params,
1522
            HttpServletRequest request, HttpServletResponse response,
1523
            String user, String[] groups) {
1524
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1525
        String[] docid = params.get("docid");
1526
        
1527
        if(docid == null){
1528
            response.setContentType("text/xml");
1529
            out.println("<?xml version=\"1.0\"?>");
1530
            out.println("<error>");
1531
            out.println("Docid not specified.");
1532
            out.println("</error>");
1533
            logMetacat.error("MetaCatServlet.handleDeleteAction - Docid not specified for the document to be deleted.");
1534
        } else {
1535
            
1536
            // delete the document from the database
1537
            try {
1538
                
1539
                try {
1540
                    // null means notify server is null
1541
                    DocumentImpl.delete(docid[0], user, groups, null);
1542
                    EventLog.getInstance().log(request.getRemoteAddr(),
1543
                            user, docid[0], "delete");
1544
                    response.setContentType("text/xml");
1545
                    out.println("<?xml version=\"1.0\"?>");
1546
                    out.println("<success>");
1547
                    out.println("Document deleted.");
1548
                    out.println("</success>");
1549
                    logMetacat.info("MetaCatServlet.handleDeleteAction - Document deleted.");
1550
                    
1551
                    // Delete from spatial cache if runningSpatialOption
1552
                    if ( PropertyService.getProperty("spatial.runSpatialOption").equals("true") ) {
1553
                        SpatialHarvester sh = new SpatialHarvester();
1554
                        sh.addToDeleteQue( DocumentUtil.getSmartDocId( docid[0] ) );
1555
                        sh.destroy();
1556
                    }
1557
                    
1558
                } catch (AccessionNumberException ane) {
1559
                    response.setContentType("text/xml");
1560
                    out.println("<?xml version=\"1.0\"?>");
1561
                    out.println("<error>");
1562
                    //out.println("Error deleting document!!!");
1563
                    out.println(ane.getMessage());
1564
                    out.println("</error>");
1565
                    logMetacat.error("MetaCatServlet.handleDeleteAction - Document could not be deleted: "
1566
                            + ane.getMessage());
1567
                }
1568
            } catch (Exception e) {
1569
                response.setContentType("text/xml");
1570
                out.println("<?xml version=\"1.0\"?>");
1571
                out.println("<error>");
1572
                out.println(e.getMessage());
1573
                out.println("</error>");
1574
                logMetacat.error("MetaCatServlet.handleDeleteAction - Document could not be deleted: "
1575
                        + e.getMessage());
1576
            }
1577
        }
1578
    }
1579
    
1580
    /**
1581
     * Handle the validation request and return the results to the requestor
1582
     */
1583
    protected void handleValidateAction(PrintWriter out, Hashtable<String, String[]> params) {
1584
        
1585
        // Get the document indicated
1586
        String valtext = null;
1587
        DBConnection dbConn = null;
1588
        int serialNumber = -1;
1589
        
1590
        try {
1591
            valtext = params.get("valtext")[0];
1592
        } catch (Exception nullpe) {
1593
            
1594
            String docid = null;
1595
            try {
1596
                // Find the document id number
1597
                docid = params.get("docid")[0];
1598
                
1599
                // Get the document indicated from the db
1600
                DocumentImpl xmldoc = new DocumentImpl(docid);
1601
                valtext = xmldoc.toString();
1602
                
1603
            } catch (NullPointerException npe) {
1604
                
1605
                out.println("<error>Error getting document ID: " + docid
1606
                        + "</error>");
1607
                //if ( conn != null ) { util.returnConnection(conn); }
1608
                return;
1609
            } catch (Exception e) {
1610
                
1611
                out.println(e.getMessage());
1612
            }
1613
        }
1614
        
1615
        try {
1616
            // get a connection from the pool
1617
            dbConn = DBConnectionPool
1618
                    .getDBConnection("MetaCatServlet.handleValidateAction");
1619
            serialNumber = dbConn.getCheckOutSerialNumber();
1620
            DBValidate valobj = new DBValidate(dbConn);
1621
//            boolean valid = valobj.validateString(valtext);
1622
            
1623
            // set content type and other response header fields first
1624
            
1625
            out.println(valobj.returnErrors());
1626
            
1627
        } catch (NullPointerException npe2) {
1628
            // set content type and other response header fields first
1629
            
1630
            out.println("<error>Error validating document.</error>");
1631
        } catch (Exception e) {
1632
            
1633
            out.println(e.getMessage());
1634
        } finally {
1635
            // Return db connection
1636
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1637
        }
1638
    }
1639
    
1640
    /**
1641
     * Handle "getrevsionanddoctype" action Given a docid, return it's current
1642
     * revision and doctype from data base The output is String look like
1643
     * "rev;doctype"
1644
     */
1645
    protected void handleGetRevisionAndDocTypeAction(PrintWriter out,
1646
            Hashtable<String, String[]> params) {
1647
        // To store doc parameter
1648
        String[] docs = new String[10];
1649
        // Store a single doc id
1650
        String givenDocId = null;
1651
        // Get docid from parameters
1652
        if (params.containsKey("docid")) {
1653
            docs = params.get("docid");
1654
        }
1655
        // Get first docid form string array
1656
        givenDocId = docs[0];
1657
        
1658
        try {
1659
            // Make sure there is a docid
1660
            if (givenDocId == null || givenDocId.equals("")) { throw new Exception(
1661
                    "User didn't specify docid!"); }//if
1662
            
1663
            // Create a DBUtil object
1664
            DBUtil dbutil = new DBUtil();
1665
            // Get a rev and doctype
1666
            String revAndDocType = dbutil
1667
                    .getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
1668
            out.println(revAndDocType);
1669
            
1670
        } catch (Exception e) {
1671
            // Handle exception
1672
            out.println("<?xml version=\"1.0\"?>");
1673
            out.println("<error>");
1674
            out.println(e.getMessage());
1675
            out.println("</error>");
1676
        }
1677
        
1678
    }
1679
    
1680
    /**
1681
     * Handle "getaccesscontrol" action. Read Access Control List from db
1682
     * connection in XML format
1683
     */
1684
    protected void handleGetAccessControlAction(PrintWriter out,
1685
            Hashtable<String,String[]> params, HttpServletResponse response, String username,
1686
            String[] groupnames) {
1687
        
1688
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1689

    
1690
        String docid = params.get("docid")[0];
1691
        if (docid.startsWith("urn:")) {
1692
            try {
1693
                String actualDocId = LSIDUtil.getDocId(docid, false);
1694
                docid = actualDocId;
1695
            } catch (ParseLSIDException ple) {
1696
                logMetacat.error("MetaCatServlet.handleGetAccessControlAction - MetaCatServlet.handleGetAccessControlAction - " +
1697
                        "could not parse lsid: " + docid + " : " + ple.getMessage());               
1698
            }
1699
        }
1700
        
1701
        String qformat = "xml";
1702
        if (params.get("qformat") != null) {
1703
            qformat = (params.get("qformat"))[0];
1704
        }
1705
        
1706
        try {
1707
            AccessControlForSingleFile acfsf = new AccessControlForSingleFile(docid);
1708
            String acltext = acfsf.getACL(username, groupnames);
1709
            if (qformat.equals("xml")) {
1710
                response.setContentType("text/xml");
1711
                out.println(acltext);
1712
            } else {
1713
                DBTransform trans = new DBTransform();
1714
                response.setContentType("text/html");
1715
                trans.transformXMLDocument(acltext,"-//NCEAS//getaccesscontrol//EN", 
1716
                    "-//W3C//HTML//EN", qformat, out, params, null);              
1717
            }            
1718
        } catch (Exception e) {
1719
            out.println("<?xml version=\"1.0\"?>");
1720
            out.println("<error>");
1721
            out.println(e.getMessage());
1722
            out.println("</error>");
1723
        } 
1724
//        finally {
1725
//            // Retrun db connection to pool
1726
//            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1727
//        }
1728
    }
1729
    
1730
    /**
1731
     * Handle the "getprincipals" action. Read all principals from
1732
     * authentication scheme in XML format
1733
     */
1734
    protected void handleGetPrincipalsAction(PrintWriter out, String user,
1735
            String password) {
1736
        try {
1737
            AuthSession auth = new AuthSession();
1738
            String principals = auth.getPrincipals(user, password);
1739
            out.println(principals);
1740
            
1741
        } catch (Exception e) {
1742
            out.println("<?xml version=\"1.0\"?>");
1743
            out.println("<error>");
1744
            out.println(e.getMessage());
1745
            out.println("</error>");
1746
        }
1747
    }
1748
    
1749
    /**
1750
     * Handle "getdoctypes" action. Read all doctypes from db connection in XML
1751
     * format
1752
     */
1753
    protected void handleGetDoctypesAction(PrintWriter out, Hashtable<String, String[]> params,
1754
            HttpServletResponse response) {
1755
        try {
1756
            DBUtil dbutil = new DBUtil();
1757
            String doctypes = dbutil.readDoctypes();
1758
            out.println(doctypes);
1759
        } catch (Exception e) {
1760
            out.println("<?xml version=\"1.0\"?>");
1761
            out.println("<error>");
1762
            out.println(e.getMessage());
1763
            out.println("</error>");
1764
        }
1765
    }
1766
    
1767
    /**
1768
     * Handle the "getdtdschema" action. Read DTD or Schema file for a given
1769
     * doctype from Metacat catalog system
1770
     */
1771
    protected void handleGetDTDSchemaAction(PrintWriter out, Hashtable<String, String[]> params,
1772
            HttpServletResponse response) {
1773
        
1774
        String doctype = null;
1775
        String[] doctypeArr = params.get("doctype");
1776
        
1777
        // get only the first doctype specified in the list of doctypes
1778
        // it could be done for all doctypes in that list
1779
        if (doctypeArr != null) {
1780
            doctype = params.get("doctype")[0];
1781
        }
1782
        
1783
        try {
1784
            DBUtil dbutil = new DBUtil();
1785
            String dtdschema = dbutil.readDTDSchema(doctype);
1786
            out.println(dtdschema);
1787
            
1788
        } catch (Exception e) {
1789
            out.println("<?xml version=\"1.0\"?>");
1790
            out.println("<error>");
1791
            out.println(e.getMessage());
1792
            out.println("</error>");
1793
        }
1794
        
1795
    }
1796
    
1797
    /**
1798
     * Check if the document is registered in either the xml_documents or xml_revisions table
1799
     * @param out the writer to write the xml results to
1800
     * @param params request parameters
1801
     * @param response the http servlet response
1802
     */
1803
    public void handleIdIsRegisteredAction(PrintWriter out, Hashtable<String, String[]> params,
1804
            HttpServletResponse response) {
1805
        String id = null;
1806
        boolean exists = false;
1807
        if(params.get("docid") != null) {
1808
            id = params.get("docid")[0];
1809
        }
1810
        
1811
        try {
1812
            DBUtil dbutil = new DBUtil();
1813
            exists = dbutil.idExists(id);
1814
        } catch (Exception e) {
1815
            out.println("<?xml version=\"1.0\"?>");
1816
            out.println("<error>");
1817
            out.println(e.getMessage());
1818
            out.println("</error>");
1819
        }
1820
        
1821
        out.println("<?xml version=\"1.0\"?>");
1822
        out.println("<isRegistered>");
1823
        out.println("<docid>" + id + "</docid>");
1824
        out.println("<exists>" + exists + "</exists>");
1825
        out.println("</isRegistered>");
1826
    }
1827
    
1828
    /**
1829
     * Handle the "getalldocids" action. return a list of all docids registered
1830
     * in the system
1831
     */
1832
    public void handleGetAllDocidsAction(PrintWriter out, Hashtable<String, String[]> params,
1833
            HttpServletResponse response) {
1834
        String scope = null;
1835
        if(params.get("scope") != null) {
1836
            scope = params.get("scope")[0];
1837
        }
1838
        
1839
        try {
1840
            DBUtil dbutil = new DBUtil();
1841
            Vector<String> docids = dbutil.getAllDocids(scope);
1842
            out.println("<?xml version=\"1.0\"?>");
1843
            out.println("<idList>");
1844
            out.println("  <scope>" + scope + "</scope>");
1845
            for(int i=0; i<docids.size(); i++) {
1846
                String docid = docids.elementAt(i);
1847
                out.println("  <docid>" + docid + "</docid>");
1848
            }
1849
            out.println("</idList>");
1850
            
1851
        } catch (Exception e) {
1852
            out.println("<?xml version=\"1.0\"?>");
1853
            out.println("<error>");
1854
            out.println(e.getMessage());
1855
            out.println("</error>");
1856
        }
1857
    }
1858
    
1859
    /**
1860
     * Handle the "getlastdocid" action. Get the latest docid with rev number
1861
     * from db connection in XML format
1862
     */
1863
    public void handleGetMaxDocidAction(PrintWriter out, Hashtable<String, String[]> params,
1864
            HttpServletResponse response) {
1865
        
1866
        String scope = params.get("scope")[0];
1867
        if (scope == null) {
1868
            scope = params.get("username")[0];
1869
        }
1870
        
1871
        try {
1872
            
1873
            DBUtil dbutil = new DBUtil();
1874
            String lastDocid = dbutil.getMaxDocid(scope);
1875
            out.println("<?xml version=\"1.0\"?>");
1876
            out.println("<lastDocid>");
1877
            out.println("  <scope>" + scope + "</scope>");
1878
            out.println("  <docid>" + lastDocid + "</docid>");
1879
            out.println("</lastDocid>");
1880
            
1881
        } catch (Exception e) {
1882
            out.println("<?xml version=\"1.0\"?>");
1883
            out.println("<error>");
1884
            out.println(e.getMessage());
1885
            out.println("</error>");
1886
        }
1887
    }
1888
    
1889
    /**
1890
     * Print a report from the event log based on filter parameters passed in
1891
     * from the web.
1892
     *
1893
     * @param params the parameters from the web request
1894
     * @param request the http request object for getting request details
1895
     * @param response the http response object for writing output
1896
     */
1897
    protected void handleGetLogAction(Hashtable<String, String[]> params, HttpServletRequest request,
1898
            HttpServletResponse response, String username, String[] groups) {
1899
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1900
        try {
1901
            response.setContentType("text/xml");
1902
            PrintWriter out = response.getWriter();
1903
            
1904
            // Check that the user is authenticated as an administrator account
1905
            if (!AuthUtil.isAdministrator(username, groups)) {
1906
                out.print("<error>");
1907
                out.print("The user \"" + username +
1908
                        "\" is not authorized for this action.");
1909
                out.print("</error>");
1910
                return;
1911
            }
1912
            
1913
            // Get all of the parameters in the correct formats
1914
            String[] ipAddress = params.get("ipaddress");
1915
            String[] principal = params.get("principal");
1916
            String[] docid = params.get("docid");
1917
            String[] event = params.get("event");
1918
            String[] startArray = params.get("start");
1919
            String[] endArray = params.get("end");
1920
            String start = null;
1921
            String end = null;
1922
            if (startArray != null) {
1923
                start = startArray[0];
1924
            }
1925
            if (endArray != null) {
1926
                end = endArray[0];
1927
            }
1928
            Timestamp startDate = null;
1929
            Timestamp endDate = null;
1930
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
1931
            try {
1932
                if (start != null) {
1933
                    startDate = new Timestamp((format.parse(start)).getTime());
1934
                }
1935
                if (end != null) {
1936
                    endDate = new Timestamp((format.parse(end)).getTime());
1937
                }
1938
            } catch (ParseException e) {
1939
                logMetacat.error("MetaCatServlet.handleGetLogAction - Failed to created Timestamp from input.");
1940
            }
1941
            
1942
            // Request the report by passing the filter parameters
1943
            out.println(EventLog.getInstance().getReport(ipAddress, principal,
1944
                    docid, event, startDate, endDate));
1945
            out.close();
1946
        } catch (IOException e) {
1947
            logMetacat.error("MetaCatServlet.handleGetLogAction - Could not open http response for writing: "
1948
                    + e.getMessage());
1949
        } catch (MetacatUtilException ue) {
1950
            logMetacat.error("MetaCatServlet.handleGetLogAction - Could not determine if user is administrator: "
1951
                    + ue.getMessage());
1952
        }
1953
    }
1954
    
1955
    /**
1956
     * Rebuild the index for one or more documents. If the docid parameter is
1957
     * provided, rebuild for just that one document or list of documents. If
1958
     * not, then rebuild the index for all documents in the xml_documents table.
1959
     * 
1960
     * @param params
1961
     *            the parameters from the web request
1962
     * @param request
1963
     *            the http request object for getting request details
1964
     * @param response
1965
     *            the http response object for writing output
1966
     * @param username
1967
     *            the username of the authenticated user
1968
     */
1969
    protected void handleBuildIndexAction(Hashtable<String, String[]> params,
1970
            HttpServletRequest request, HttpServletResponse response,
1971
            String username, String[] groups) {
1972
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1973
        
1974
        // Get all of the parameters in the correct formats
1975
        String[] docid = params.get("docid");
1976
        
1977
        // Rebuild the indices for appropriate documents
1978
        try {
1979
            response.setContentType("text/xml");
1980
            PrintWriter out = response.getWriter();
1981
            
1982
            // Check that the user is authenticated as an administrator account
1983
            if (!AuthUtil.isAdministrator(username, groups)) {
1984
                out.print("<error>");
1985
                out.print("The user \"" + username +
1986
                        "\" is not authorized for this action.");
1987
                out.print("</error>");
1988
                return;
1989
            }
1990
            
1991
            // Process the documents
1992
            out.println("<success>");
1993
            if (docid == null || docid.length == 0) {
1994
                // Process all of the documents
1995
                try {
1996
                    Vector<String> documents = getDocumentList();
1997
                    Iterator<String> it = documents.iterator();
1998
                    while (it.hasNext()) {
1999
                        String id = it.next();
2000
                        buildDocumentIndex(id, out);
2001
                    }
2002
                } catch (SQLException se) {
2003
                    out.print("<error>");
2004
                    out.print(se.getMessage());
2005
                    out.println("</error>");
2006
                }
2007
            } else {
2008
                // Only process the requested documents
2009
                for (int i = 0; i < docid.length; i++) {
2010
                    buildDocumentIndex(docid[i], out);
2011
                }
2012
            }
2013
            out.println("</success>");
2014
            out.close();
2015
        } catch (IOException e) {
2016
            logMetacat.error("MetaCatServlet.handleBuildIndexAction - Could not open http response for writing: "
2017
                    + e.getMessage());
2018
        } catch (MetacatUtilException ue) {
2019
            logMetacat.error("MetaCatServlet.handleBuildIndexAction - Could not determine if user is administrator: "
2020
                    + ue.getMessage());
2021
        }
2022
    }
2023
    
2024
    /**
2025
     * Build the index for one document by reading the document and
2026
     * calling its buildIndex() method.
2027
     *
2028
     * @param docid the document (with revision) to rebuild
2029
     * @param out the PrintWriter to which output is printed
2030
     */
2031
    private void buildDocumentIndex(String docid, PrintWriter out) {
2032
        try {
2033
            DocumentImpl doc = new DocumentImpl(docid, false);
2034
            doc.buildIndex();
2035
            out.print("<docid>" + docid);
2036
            out.println("</docid>");
2037
        } catch (McdbException me) {
2038
            out.print("<error>");
2039
            out.print(me.getMessage());
2040
            out.println("</error>");
2041
        }
2042
    }
2043
    
2044
    /**
2045
     * Handle documents passed to metacat that are encoded using the
2046
     * "multipart/form-data" mime type. This is typically used for uploading
2047
     * data files which may be binary and large.
2048
     */
2049
    protected void handleMultipartForm(HttpServletRequest request,
2050
            HttpServletResponse response) {
2051
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2052
        PrintWriter out = null;
2053
        String action = null;
2054
        
2055
        // Parse the multipart form, and save the parameters in a Hashtable and
2056
        // save the FileParts in a hashtable
2057
        
2058
        Hashtable<String,String[]> params = new Hashtable<String,String[]>();
2059
        Hashtable<String,String> fileList = new Hashtable<String,String>();
2060
        int sizeLimit = 1000;
2061
        try {
2062
            sizeLimit = 
2063
                (new Integer(PropertyService.getProperty("replication.datafilesizelimit"))).intValue();
2064
        } catch (PropertyNotFoundException pnfe) {
2065
            logMetacat.error("MetaCatServlet.handleMultipartForm - Could not determine data file size limit.  Using 1000. " 
2066
                    + pnfe.getMessage());
2067
        }
2068
        logMetacat.debug("MetaCatServlet.handleMultipartForm - The size limit of uploaded data files is: " + sizeLimit);
2069
        
2070
        try {
2071
            MultipartParser mp = new MultipartParser(request,
2072
                    sizeLimit * 1024 * 1024);
2073
            Part part;
2074
            
2075
            while ((part = mp.readNextPart()) != null) {
2076
                String name = part.getName();
2077
                
2078
                if (part.isParam()) {
2079
                    // it's a parameter part
2080
                    ParamPart paramPart = (ParamPart) part;
2081
                    String[] values = new String[1];
2082
                    values[0] = paramPart.getStringValue();
2083
                    params.put(name, values);
2084
                    if (name.equals("action")) {
2085
                        action = values[0];
2086
                    }
2087
                } else if (part.isFile()) {
2088
                    // it's a file part
2089
                    FilePart filePart = (FilePart) part;
2090
                    String fileName = filePart.getFileName();
2091
                    String fileTempLocation;
2092
                    
2093
                    // the filePart will be clobbered on the next loop, save to disk
2094
                    fileTempLocation = MetacatUtil.writeTempUploadFile(filePart, fileName);
2095
                    fileList.put(name, fileTempLocation);
2096
                    fileList.put("filename", fileName);
2097
                    fileList.put("name", fileTempLocation);
2098
                } else {
2099
                    logMetacat.info("MetaCatServlet.handleMultipartForm - Upload name '" + name + "' was empty.");
2100
                }
2101
            }
2102
        } catch (IOException ioe) {
2103
            try {
2104
                out = response.getWriter();
2105
            } catch (IOException ioe2) {
2106
                logMetacat.fatal("MetaCatServlet.handleMultipartForm - Fatal Error: couldn't get response output stream.");
2107
            }
2108
            out.println("<?xml version=\"1.0\"?>");
2109
            out.println("<error>");
2110
            out.println("Error: problem reading multipart data: " + ioe.getMessage());
2111
            out.println("</error>");
2112
            out.close();
2113
            return;
2114
        }
2115
        
2116
        // Get the session information
2117
        String username = null;
2118
        String password = null;
2119
        String[] groupnames = null;
2120
        String sess_id = null;
2121
        
2122
        // be aware of session expiration on every request
2123
        HttpSession sess = request.getSession(true);
2124
        if (sess.isNew()) {
2125
            // session expired or has not been stored b/w user requests
2126
            username = "public";
2127
            sess.setAttribute("username", username);
2128
        } else {
2129
            username = (String) sess.getAttribute("username");
2130
            password = (String) sess.getAttribute("password");
2131
            groupnames = (String[]) sess.getAttribute("groupnames");
2132
            try {
2133
                sess_id = (String) sess.getId();
2134
            } catch (IllegalStateException ise) {
2135
                System.out
2136
                        .println("error in  handleMultipartForm: this shouldn't "
2137
                        + "happen: the session should be valid: "
2138
                        + ise.getMessage());
2139
            }
2140
        }
2141
        
2142
        // Get the out stream
2143
        try {
2144
            out = response.getWriter();
2145
        } catch (IOException ioe2) {
2146
            logMetacat.error("MetaCatServlet.handleMultipartForm - Fatal Error: couldn't get response "
2147
                    + "output stream.");
2148
        }
2149
        
2150
        if (action.equals("upload")) {
2151
            if (username != null && !username.equals("public")) {
2152
                handleUploadAction(request, out, params, fileList, username,
2153
                        groupnames, response);
2154
            } else {                
2155
                out.println("<?xml version=\"1.0\"?>");
2156
                out.println("<error>");
2157
                out.println("Permission denied for " + action);
2158
                out.println("</error>");
2159
            }
2160
        } else if(action.equals("insertmultipart")) {
2161
          if (username != null && !username.equals("public")) {
2162
            logMetacat.debug("MetaCatServlet.handleMultipartForm - handling multipart insert");
2163
              handleInsertMultipartAction(request, response,
2164
                            out, params, fileList, username, groupnames);
2165
          } else {
2166
              out.println("<?xml version=\"1.0\"?>");
2167
              out.println("<error>");
2168
              out.println("Permission denied for " + action);
2169
              out.println("</error>");
2170
          }
2171
        } else {
2172
            /*
2173
             * try { out = response.getWriter(); } catch (IOException ioe2) {
2174
             * System.err.println("Fatal Error: couldn't get response output
2175
             * stream.");
2176
             */
2177
            out.println("<?xml version=\"1.0\"?>");
2178
            out.println("<error>");
2179
            out.println("Error: action not registered.  Please report this error.");
2180
            out.println("</error>");
2181
        }
2182
        out.close();
2183
    }
2184
    
2185
    /**
2186
     * Handle the upload action by saving the attached file to disk and
2187
     * registering it in the Metacat db
2188
     */
2189
    private void handleInsertMultipartAction(HttpServletRequest request, 
2190
            HttpServletResponse response,
2191
            PrintWriter out, Hashtable<String,String[]> params, Hashtable<String,String> fileList,
2192
            String username, String[] groupnames)
2193
    {
2194
      Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2195
      String action = null;
2196
      String docid = null;
2197
      String qformat = null;
2198
      String output = "";
2199
      
2200
      /*
2201
       * response.setContentType("text/xml"); try { out =
2202
       * response.getWriter(); } catch (IOException ioe2) {
2203
       * System.err.println("Fatal Error: couldn't get response output
2204
       * stream.");
2205
       */
2206
      
2207
      if (params.containsKey("docid")) 
2208
      {
2209
          docid = params.get("docid")[0];
2210
      }
2211
      
2212
      if(params.containsKey("qformat")) 
2213
      {
2214
          qformat = params.get("qformat")[0];
2215
      }
2216
      
2217
      // Make sure we have a docid and datafile
2218
      if (docid != null && fileList.containsKey("datafile")) 
2219
      {
2220
        logMetacat.info("MetaCatServlet.handleInsertMultipartAction - Uploading data docid: " + docid);
2221
        // Get a reference to the file part of the form
2222
        //FilePart filePart = (FilePart) fileList.get("datafile");
2223
        String fileName = fileList.get("filename");
2224
        logMetacat.debug("MetaCatServlet.handleInsertMultipartAction - Uploading filename: " + fileName);
2225
        // Check if the right file existed in the uploaded data
2226
        if (fileName != null) 
2227
        {
2228
              
2229
          try 
2230
          {
2231
              //logMetacat.info("Upload datafile " + docid
2232
              // +"...", 10);
2233
              //If document get lock data file grant
2234
            if (DocumentImpl.getDataFileLockGrant(docid)) 
2235
            {
2236
              // Save the data file to disk using "docid" as the name
2237
              String datafilepath = PropertyService.getProperty("application.datafilepath");
2238
              File dataDirectory = new File(datafilepath);
2239
              dataDirectory.mkdirs();
2240
              File newFile = null;
2241
    //          File tempFile = null;
2242
              String tempFileName = fileList.get("name");
2243
              String newFileName = dataDirectory + File.separator + docid;
2244
              long size = 0;
2245
              boolean fileExists = false;
2246
                      
2247
              try 
2248
              {
2249
                newFile = new File(newFileName);
2250
                fileExists = newFile.exists();
2251
                logMetacat.info("MetaCatServlet.handleInsertMultipartAction - new file status is: " + fileExists);
2252
                if(fileExists)
2253
                {
2254
                  newFile.delete();
2255
                  newFile.createNewFile();
2256
                  fileExists = false;
2257
                }
2258
                
2259
                if ( fileExists == false ) 
2260
                {
2261
                    // copy file to desired output location
2262
                    try 
2263
                    {
2264
                        MetacatUtil.copyFile(tempFileName, newFileName);
2265
                    } 
2266
                    catch (IOException ioe) 
2267
                    {
2268
                        logMetacat.error("MetaCatServlet.handleInsertMultipartAction - IO Exception copying file: " +
2269
                                ioe.getMessage());
2270
                    }
2271
                    size = newFile.length();
2272
                    if (size == 0) 
2273
                    {
2274
                        throw new IOException("MetaCatServlet.handleInsertMultipartAction - Uploaded file is 0 bytes!");
2275
                    }
2276
                }
2277
                logMetacat.info("MetaCatServlet.handleInsertMultipartAction - Uploading the following to Metacat:" +
2278
                        fileName + ", " + docid + ", " +
2279
                        username + ", " + groupnames);
2280
                FileReader fr = new FileReader(newFile);
2281
                
2282
                char[] c = new char[1024];
2283
                int numread = fr.read(c, 0, 1024);
2284
                StringBuffer sb = new StringBuffer();
2285
                while(numread != -1)
2286
                {
2287
                  sb.append(c, 0, numread);
2288
                  numread = fr.read(c, 0, 1024);
2289
                }
2290
                
2291
                Enumeration<String> keys = params.keys();
2292
                while(keys.hasMoreElements())
2293
                { //convert the params to arrays
2294
                  String key = keys.nextElement();
2295
                  String[] paramValue = params.get(key);
2296
                  String[] s = new String[1];
2297
                  s[0] = paramValue[0];
2298
                  params.put(key, s);
2299
                }
2300
                //add the doctext to the params
2301
                String doctext = sb.toString();
2302
                String[] doctextArr = new String[1];
2303
                doctextArr[0] = doctext;
2304
                params.put("doctext", doctextArr);
2305
                //call the insert routine
2306
                handleInsertOrUpdateAction(request, response, out, 
2307
                          params, username, groupnames);
2308
              }
2309
              catch(Exception e)
2310
              {
2311
                throw e;
2312
              }
2313
            }
2314
          }
2315
          catch(Exception e)
2316
          {
2317
              logMetacat.error("MetaCatServlet.handleInsertMultipartAction - error uploading text file via multipart: " + e.getMessage());
2318
              e.printStackTrace();
2319
          }
2320
        }
2321
      }
2322
    }
2323
    
2324
    /**
2325
     * Handle the upload action by saving the attached file to disk and
2326
     * registering it in the Metacat db
2327
     */
2328
    private void handleUploadAction(HttpServletRequest request,
2329
            PrintWriter out, Hashtable<String, String[]> params, Hashtable<String,String> fileList,
2330
            String username, String[] groupnames, HttpServletResponse response) {
2331
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2332
        //PrintWriter out = null;
2333
        //Connection conn = null;
2334
//        String action = null;
2335
        String docid = null;
2336
        String qformat = null;
2337
        String output = "";
2338
        
2339
        /*
2340
         * response.setContentType("text/xml"); try { out =
2341
         * response.getWriter(); } catch (IOException ioe2) {
2342
         * System.err.println("Fatal Error: couldn't get response output
2343
         * stream.");
2344
         */
2345
        
2346
        if (params.containsKey("docid")) {
2347
            docid = params.get("docid")[0];
2348
        }
2349
        
2350
        if(params.containsKey("qformat")) {
2351
            qformat = params.get("qformat")[0];
2352
        }
2353
        
2354
        // Make sure we have a docid and datafile
2355
        if (docid != null && fileList.containsKey("datafile")) {
2356
            logMetacat.info("MetaCatServlet.handleUploadAction - Uploading data docid: " + docid);
2357
            // Get a reference to the file part of the form
2358
            //FilePart filePart = (FilePart) fileList.get("datafile");
2359
            String fileName = fileList.get("filename");
2360
            logMetacat.info("MetaCatServlet.handleUploadAction - Uploading filename: " + fileName);
2361
            // Check if the right file existed in the uploaded data
2362
            if (fileName != null) {
2363
                
2364
                try {
2365
                    //logMetacat.info("Upload datafile " + docid
2366
                    // +"...", 10);
2367
                    //If document get lock data file grant
2368
                    if (DocumentImpl.getDataFileLockGrant(docid)) {
2369
                        // Save the data file to disk using "docid" as the name
2370
                        String datafilepath = PropertyService.getProperty("application.datafilepath");
2371
                        File dataDirectory = new File(datafilepath);
2372
                        dataDirectory.mkdirs();
2373
                        File newFile = null;
2374
    //                    File tempFile = null;
2375
                        String tempFileName = fileList.get("name");
2376
                        String newFileName = dataDirectory + File.separator + docid;
2377
                        long size = 0;
2378
                        boolean fileExists = false;
2379
                        
2380
                        try {
2381
                            newFile = new File(newFileName);
2382
                            fileExists = newFile.exists();
2383
                            logMetacat.info("MetaCatServlet.handleUploadAction - new file status is: " + fileExists);
2384
                            if ( fileExists == false ) {
2385
                                // copy file to desired output location
2386
                                try {
2387
                                    MetacatUtil.copyFile(tempFileName, newFileName);
2388
                                } catch (IOException ioe) {
2389
                                    logMetacat.error("IO Exception copying file: " +
2390
                                            ioe.getMessage());
2391
                                }
2392
                                size = newFile.length();
2393
                                if (size == 0) {
2394
                                    throw new IOException("Uploaded file is 0 bytes!");
2395
                                }
2396
                            }
2397
                            logMetacat.info("MetaCatServlet.handleUploadAction - Uploading the following to Metacat:" +
2398
                                    fileName + ", " + docid + ", " +
2399
                                    username + ", " + groupnames);
2400
                            //register the file in the database (which generates
2401
                            // an exception
2402
                            //if the docid is not acceptable or other untoward
2403
                            // things happen
2404
                            DocumentImpl.registerDocument(fileName, "BIN", docid,
2405
                                    username, groupnames);
2406
                        } catch (Exception ee) {
2407
                            //delete the file to create
2408
                            // if the revision already exists, don't delete
2409
                            // the file
2410
                            if ( fileExists == false ) {
2411
                                newFile.delete();
2412
                            }
2413
                            logMetacat.info("MetaCatServlet.handleUploadAction - in Exception: fileExists is " + fileExists);
2414
                            logMetacat.error("MetaCatServlet.handleUploadAction - Upload Error: " + ee.getMessage());
2415
                            throw ee;
2416
                        }
2417
                        
2418
                        EventLog.getInstance().log(request.getRemoteAddr(),
2419
                                username, docid, "upload");
2420
                        // Force replication this data file
2421
                        // To data file, "insert" and update is same
2422
                        // The fourth parameter is null. Because it is
2423
                        // notification server
2424
                        // and this method is in MetaCatServerlet. It is
2425
                        // original command,
2426
                        // not get force replication info from another metacat
2427
                        ForceReplicationHandler frh = new ForceReplicationHandler(
2428
                                docid, "insert", false, null);
2429
                        logMetacat.debug("MetaCatServlet.handleUploadAction - ForceReplicationHandler created: " + frh.toString());
2430
                        
2431
                        // set content type and other response header fields
2432
                        // first
2433
                        output += "<?xml version=\"1.0\"?>";
2434
                        output += "<success>";
2435
                        output += "<docid>" + docid + "</docid>";
2436
                        output += "<size>" + size + "</size>";
2437
                        output += "</success>";
2438
                    }
2439
                    
2440
                } catch (Exception e) {
2441
                    
2442
                    output += "<?xml version=\"1.0\"?>";
2443
                    output += "<error>";
2444
                    output += e.getMessage();
2445
                    output += "</error>";
2446
                }
2447
            } else {
2448
                // the field did not contain a file
2449
                output += "<?xml version=\"1.0\"?>";
2450
                output += "<error>";
2451
                output += "The uploaded data did not contain a valid file.";
2452
                output += "</error>";
2453
            }
2454
        } else {
2455
            // Error bcse docid missing or file missing
2456
            output += "<?xml version=\"1.0\"?>";
2457
            output += "<error>";
2458
            output += "The uploaded data did not contain a valid docid "
2459
                    + "or valid file.";
2460
            output += "</error>";
2461
        }
2462
        
2463
        if (qformat == null || qformat.equals("xml")) {
2464
            response.setContentType("text/xml");
2465
            out.println(output);
2466
        } else {
2467
            try {
2468
                DBTransform trans = new DBTransform();
2469
                response.setContentType("text/html");
2470
                trans.transformXMLDocument(output,
2471
                        "message", "-//W3C//HTML//EN", qformat,
2472
                        out, null, null);
2473
            } catch (Exception e) {
2474
                
2475
                logMetacat.error("MetaCatServlet.handleUploadAction - General error: "
2476
                        + e.getMessage());
2477
            }
2478
        }
2479
    }
2480
    
2481
    /*
2482
     * A method to handle set access action
2483
     */
2484
    protected void handleSetAccessAction(PrintWriter out, Hashtable<String, String[]> params,
2485
            String username, HttpServletRequest request, HttpServletResponse response) {
2486
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2487

    
2488
        String permission = null;
2489
        String permType = null;
2490
        String permOrder = null;
2491
        Vector<String> errorList = new Vector<String>();
2492
        String error = null;
2493
        Vector<String> successList = new Vector<String>();
2494
        String success = null;
2495
        boolean isEmlPkgMember = false;
2496
        
2497
        String[] docList = params.get("docid");
2498
        String[] principalList = params.get("principal");
2499
        String[] permissionList = params.get("permission");
2500
        String[] permTypeList = params.get("permType");
2501
        String[] permOrderList = params.get("permOrder");
2502
        String[] qformatList = params.get("qformat");
2503
        String[] accessBlock = params.get("accessBlock");
2504
        
2505
        if(accessBlock != null) {
2506
            if (docList == null) {
2507
                errorList.addElement("MetaCatServlet.handleSetAccessAction - Doc id missing.  Please check your parameter list, it should look like: "
2508
                    + "?action=setaccess&docid=<doc_id>&accessBlock=<access_section>");
2509
                outputResponse(successList, errorList, out);
2510
                return;
2511
            }
2512
            
2513
            try {
2514
                AccessControlForSingleFile accessControl = 
2515
                    new AccessControlForSingleFile(docList[0]);
2516
                accessControl.insertPermissions(accessBlock[0]);
2517
                successList.addElement("MetaCatServlet.handleSetAccessAction - successfully replaced access block for doc id: " + docList[0]);
2518
            } catch(AccessControlException ace) {
2519
                errorList.addElement("MetaCatServlet.handleSetAccessAction - access control error when setting " + 
2520
                    "access block: " + ace.getMessage());
2521
            } 
2522
            outputResponse(successList, errorList, out);
2523
            return;
2524
        }
2525
        
2526
        // Make sure the parameter is not null
2527
        if (docList == null || principalList == null || permTypeList == null
2528
                || permissionList == null) {
2529
            error = "MetaCatServlet.handleSetAccessAction - Please check your parameter list, it should look like: "
2530
                    + "?action=setaccess&docid=pipeline.1.1&principal=public"
2531
                    + "&permission=read&permType=allow&permOrder=allowFirst";
2532
            errorList.addElement(error);
2533
            outputResponse(successList, errorList, out);
2534
            return;
2535
        }
2536
        
2537
        // Only select first element for permission, type and order
2538
        permission = permissionList[0];
2539
        permType = permTypeList[0];
2540
        if (permOrderList != null) {
2541
            permOrder = permOrderList[0];
2542
        }
2543
        
2544
        // Get package doctype set
2545
        Vector<String> packageSet = null;
2546
        try {
2547
            packageSet = 
2548
                MetacatUtil.getOptionList(PropertyService.getProperty("xml.packagedoctypeset"));
2549
        } catch (PropertyNotFoundException pnfe) {
2550
            logMetacat.error("MetaCatServlet.handleSetAccessAction - Could not find package doctype set.  Setting to null: " 
2551
                    + pnfe.getMessage());
2552
        }
2553
        //debug
2554
        if (packageSet != null) {
2555
            for (int i = 0; i < packageSet.size(); i++) {
2556
                logMetacat.debug("MetaCatServlet.handleSetAccessAction - doctype in package set: "
2557
                        + packageSet.elementAt(i));
2558
            }
2559
        }
2560
        
2561
        // handle every accessionNumber
2562
        for (int i = 0; i < docList.length; i++) {
2563
            String docid = docList[i];
2564
            if (docid.startsWith("urn:")) {
2565
                try {
2566
                    String actualDocId = LSIDUtil.getDocId(docid, false);
2567
                    docid = actualDocId;
2568
                } catch (ParseLSIDException ple) {
2569
                    logMetacat.error("MetaCatServlet.handleSetAccessAction - " +
2570
                            "could not parse lsid: " + docid + " : " + ple.getMessage());               
2571
                }
2572
            }
2573
            
2574
            String accessionNumber = docid;
2575
            String owner = null;
2576
            String publicId = null;
2577
            // Get document owner and public id
2578
            try {
2579
                owner = getFieldValueForDoc(accessionNumber, "user_owner");
2580
                publicId = getFieldValueForDoc(accessionNumber, "doctype");
2581
            } catch (Exception e) {
2582
                logMetacat.error("MetaCatServlet.handleSetAccessAction - Error in handleSetAccessAction: "
2583
                        + e.getMessage());
2584
                error = "Error in set access control for document - " + accessionNumber + e.getMessage();
2585
                errorList.addElement(error);
2586
                continue;
2587
            }
2588
            //check if user is the owner. Only owner can do owner
2589
            if (username == null || owner == null || !username.equals(owner)) {
2590
                error = "User - " + username + " does not have permission to set "
2591
                        + "access control for docid - " + accessionNumber;
2592
                errorList.addElement(error);
2593
                continue;
2594
            }
2595
            
2596
            //*** Find out if the document is a Member of an EML package.
2597
            //*** (for efficiency, only check if it isn't already true
2598
            //*** for the case of multiple files).
2599
            if (isEmlPkgMember == false)
2600
                isEmlPkgMember = (DBUtil.findDataSetDocIdForGivenDocument(accessionNumber) != null);
2601
            
2602
            // If docid publicid is BIN data file or other beta4, 6 package document
2603
            // we could not do set access control. Because we don't want inconsistent
2604
            // to its access docuemnt
2605
            if (publicId != null && packageSet != null
2606
                    && packageSet.contains(publicId) && isEmlPkgMember) {
2607
                error = "Could not set access control to document " + accessionNumber
2608
                        + "because it is in a pakcage and it has a access file for it";
2609
                errorList.addElement(error);
2610
                continue;
2611
            }
2612
            
2613
            // for every principle
2614
            for (int j = 0; j < principalList.length; j++) {
2615
                String principal = principalList[j];
2616
                try {
2617
                    //insert permission
2618
                    AccessControlForSingleFile accessControl = 
2619
                        new AccessControlForSingleFile(accessionNumber);
2620
                    accessControl.insertPermissions(principal, Long.valueOf(permission), permType, permOrder);
2621
                } catch (Exception ee) {
2622
                    logMetacat.error("MetaCatServlet.handleSetAccessAction - Error inserting permission: "
2623
                            + ee.getMessage());
2624
                    error = "Failed to set access control for document "
2625
                            + accessionNumber + " because " + ee.getMessage();
2626
                    errorList.addElement(error);
2627
                    continue;
2628
                }
2629
            }
2630
            
2631
            //force replication when this action is called
2632
            boolean isXml = true;
2633
            if (publicId.equalsIgnoreCase("BIN")) {
2634
                isXml = false;
2635
            }
2636
            ForceReplicationHandler frh = 
2637
                new ForceReplicationHandler(accessionNumber, isXml, null);
2638
            logMetacat.debug("MetaCatServlet.handleSetAccessAction - ForceReplicationHandler created: " + frh.toString());
2639
            
2640
        }
2641
        successList.addElement("MetaCatServlet.handleSetAccessAction - successfully added individual access for doc id: " + docList[0]);
2642
        
2643
        if (params.get("forwardto")  != null) {
2644
            try {
2645
                RequestUtil.forwardRequest(request, response, params);
2646
            } catch (MetacatUtilException mue) {
2647
                logMetacat.error("metaCatServlet.handleSetAccessAction - could not forward " +
2648
                        "request. Sending output to response writer");
2649
                outputResponse(successList, errorList, out);
2650
            }               
2651
        } else {
2652
            outputResponse(successList, errorList, out);
2653
        }
2654
    }
2655
    
2656
    /*
2657
     * A method try to determin a docid's public id, if couldn't find null will
2658
     * be returned.
2659
     */
2660
    private String getFieldValueForDoc(String accessionNumber, String fieldName)
2661
    throws Exception {
2662
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2663
        if (accessionNumber == null || accessionNumber.equals("")
2664
        || fieldName == null || fieldName.equals("")) { throw new Exception(
2665
                "Docid or field name was not specified"); }
2666
        
2667
        PreparedStatement pstmt = null;
2668
        ResultSet rs = null;
2669
        String fieldValue = null;
2670
        String docId = null;
2671
        DBConnection conn = null;
2672
        int serialNumber = -1;
2673
        
2674
        // get rid of revision if access number has
2675
        docId = DocumentUtil.getDocIdFromString(accessionNumber);
2676
        try {
2677
            //check out DBConnection
2678
            conn = DBConnectionPool
2679
                    .getDBConnection("MetaCatServlet.getPublicIdForDoc");
2680
            serialNumber = conn.getCheckOutSerialNumber();
2681
            pstmt = conn.prepareStatement("SELECT " + fieldName
2682
                    + " FROM xml_documents " + "WHERE docid = ? ");
2683
            
2684
            pstmt.setString(1, docId);
2685
            pstmt.execute();
2686
            rs = pstmt.getResultSet();
2687
            boolean hasRow = rs.next();
2688
        //    int perm = 0;
2689
            if (hasRow) {
2690
                fieldValue = rs.getString(1);
2691
            } else {
2692
                throw new Exception("Could not find document: "
2693
                        + accessionNumber);
2694
            }
2695
        } catch (Exception e) {
2696
            logMetacat.error("MetaCatServlet.getFieldValueForDoc - General error: "
2697
                    + e.getMessage());
2698
            throw e;
2699
        } finally {
2700
            try {
2701
                rs.close();
2702
                pstmt.close();
2703
                
2704
            } finally {
2705
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2706
            }
2707
        }
2708
        return fieldValue;
2709
    }
2710
    
2711
    /*
2712
     * Get the list of documents from the database and return the list in an
2713
     * Vector of identifiers.
2714
     *
2715
     * @ returns the array of identifiers
2716
     */
2717
    private Vector<String> getDocumentList() throws SQLException {
2718
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2719
        Vector<String> docList = new Vector<String>();
2720
        PreparedStatement pstmt = null;
2721
        ResultSet rs = null;
2722
        DBConnection conn = null;
2723
        int serialNumber = -1;
2724
        
2725
        try {
2726
            //check out DBConnection
2727
            conn = DBConnectionPool
2728
                    .getDBConnection("MetaCatServlet.getDocumentList");
2729
            serialNumber = conn.getCheckOutSerialNumber();
2730
            pstmt = conn.prepareStatement("SELECT docid, rev"
2731
                    + " FROM xml_documents ");
2732
            pstmt.execute();
2733
            rs = pstmt.getResultSet();
2734
            while (rs.next()) {
2735
                String docid = rs.getString(1);
2736
                String rev = rs.getString(2);
2737
                docList.add(docid + "." + rev);
2738
            }
2739
        } catch (SQLException e) {
2740
            logMetacat.error("MetaCatServlet.getDocumentList - General exception: "
2741
                    + e.getMessage());
2742
            throw e;
2743
        } finally {
2744
            try {
2745
                rs.close();
2746
                pstmt.close();
2747
                
2748
            } catch (SQLException se) {
2749
                logMetacat.error("MetaCatServlet.getDocumentList - General exception: "
2750
                        + se.getMessage());
2751
                throw se;
2752
            } finally {
2753
                DBConnectionPool.returnDBConnection(conn, serialNumber);
2754
            }
2755
        }
2756
        return docList;
2757
    }
2758
    
2759
    /*
2760
     * A method to output setAccess action result
2761
     */
2762
    private void outputResponse(Vector<String> successList, Vector<String> errorList,
2763
            PrintWriter out) {
2764
        boolean error = false;
2765
        boolean success = false;
2766
        // Output prolog
2767
        out.println(PROLOG);
2768
        // output success message
2769
        if (successList != null) {
2770
            for (int i = 0; i < successList.size(); i++) {
2771
                out.println(SUCCESS);
2772
                out.println(successList.elementAt(i));
2773
                out.println(SUCCESSCLOSE);
2774
                success = true;
2775
            }
2776
        }
2777
        // output error message
2778
        if (errorList != null) {
2779
            for (int i = 0; i < errorList.size(); i++) {
2780
                out.println(ERROR);
2781
                out.println(errorList.elementAt(i));
2782
                out.println(ERRORCLOSE);
2783
                error = true;
2784
            }
2785
        }
2786
        
2787
        // if no error and no success info, send a error that nothing happened
2788
        if (!error && !success) {
2789
            out.println(ERROR);
2790
            out.println("Nothing happend for setaccess action");
2791
            out.println(ERRORCLOSE);
2792
        }
2793
    }
2794
    
2795
    /*
2796
     * If the given docid only have one seperter, we need
2797
     * append rev for it. The rev come from xml_documents
2798
     */
2799
    private static String appendRev(String docid) throws Exception {
2800
//        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2801
        String newAccNum = null;
2802
        String separator = PropertyService.getProperty("document.accNumSeparator");
2803
        int firstIndex = docid.indexOf(separator);
2804
        int lastIndex = docid.lastIndexOf(separator);
2805
        if (firstIndex == lastIndex) {
2806
            
2807
            //only one seperater
2808
            int rev = DBUtil.getLatestRevisionInDocumentTable(docid);
2809
            if (rev == -1) {
2810
                throw new Exception("the requested docid '"
2811
                        + docid+ "' does not exist");
2812
            } else {
2813
                newAccNum = docid+ separator+ rev;
2814
            }
2815
        } else {
2816
            // in other suituation we don't change the docid
2817
            newAccNum = docid;
2818
        }
2819
        //logMetacat.debug("The docid will be read is "+newAccNum);
2820
        return newAccNum;
2821
    }
2822
    
2823
    /**
2824
     * Schedule the sitemap generator to run periodically and update all
2825
     * of the sitemap files for search indexing engines.
2826
     *
2827
     * @param request a servlet request, from which we determine the context
2828
     */
2829
    protected void scheduleSitemapGeneration(HttpServletRequest request) {
2830
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2831
        if (!_sitemapScheduled) {
2832
            String directoryName = null;
2833
            String skin = null;
2834
            long sitemapInterval = 0;
2835
            
2836
            try {
2837
                directoryName = SystemUtil.getContextDir() + FileUtil.getFS() + "sitemaps";
2838
                skin = PropertyService.getProperty("application.default-style");
2839
                sitemapInterval = 
2840
                    Integer.parseInt(PropertyService.getProperty("sitemap.interval"));
2841
            } catch (PropertyNotFoundException pnfe) {
2842
                logMetacat.error("MetaCatServlet.scheduleSitemapGeneration - Could not run site map generation because property " 
2843
                        + "could not be found: " + pnfe.getMessage());
2844
            }
2845
            
2846
            File directory = new File(directoryName);
2847
            directory.mkdirs();
2848
            String urlRoot = request.getRequestURL().toString();
2849
            Sitemap smap = new Sitemap(directory, urlRoot, skin);
2850
            long firstDelay = 60*1000;   // 60 seconds delay
2851
            timer.schedule(smap, firstDelay, sitemapInterval);
2852
            _sitemapScheduled = true;
2853
        }
2854
    }
2855

    
2856
    /**
2857
     * @param sitemapScheduled toggle the _sitemapScheduled flag
2858
     */
2859
    public static void set_sitemapScheduled(boolean sitemapScheduled) {
2860
        _sitemapScheduled = sitemapScheduled;
2861
    }
2862

    
2863
}
(43-43/62)