Project

General

Profile

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