Project

General

Profile

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

    
28
package edu.ucsb.nceas.metacat;
29

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

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

    
63
import org.apache.log4j.Logger;
64
import org.apache.log4j.PropertyConfigurator;
65
import org.ecoinformatics.eml.EMLParser;
66

    
67
import com.oreilly.servlet.multipart.FilePart;
68
import com.oreilly.servlet.multipart.MultipartParser;
69
import com.oreilly.servlet.multipart.ParamPart;
70
import com.oreilly.servlet.multipart.Part;
71

    
72
import edu.ucsb.nceas.utilities.Options;
73
import edu.ucsb.nceas.metacat.spatial.MetacatSpatialQuery;
74
import edu.ucsb.nceas.metacat.spatial.MetacatSpatialDocument;
75
import edu.ucsb.nceas.metacat.spatial.MetacatSpatialDataset;
76
import edu.ucsb.nceas.metacat.spatial.MetacatSpatialConstants;
77

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

    
150
            // Initialize the properties file for our options
151
            String dirPath = context.getRealPath(CONFIG_DIR);
152
            File propertyFile = new File(dirPath, CONFIG_NAME);
153

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

    
168
            MetaCatUtil util = new MetaCatUtil();
169
            
170
            //initialize DBConnection pool
171
            DBConnectionPool connPool = DBConnectionPool.getInstance();
172
            
173
            // Index the paths specified in the metacat.properties
174
            checkIndexPaths();
175

    
176
            // initiate the indexing Queue
177
            IndexingQueue.getInstance();
178
            
179
            // start the IndexingThread if indexingTimerTaskTime more than 0. 
180
            // It will index all the documents not yet indexed in the database             
181
            int indexingTimerTaskTime = Integer.parseInt(MetaCatUtil.getOption("indexingTimerTaskTime"));
182
            if(indexingTimerTaskTime > 0){
183
            	timer = new Timer();
184
            	timer.schedule(new IndexingTimerTask(), 0, indexingTimerTaskTime);
185
            }
186
            
187
            // read the config files: 
188
            Vector skins = MetaCatUtil.getOptionList(MetaCatUtil.getOption("skinconfigfiles"));
189
            String skinName, skinDirPath = null;
190
            File skinPropertyFile = null;
191
           
192
            for (int i = 0; i < skins.size(); i++) {
193
            	skinName = (String) skins.elementAt(i);
194
                skinDirPath = context.getRealPath(CONFIG_DIR + "/skin.configs/" + skinName);
195
                skinPropertyFile = new File(skinDirPath, skinName + ".properties"); 
196
                Properties skinOption = null;
197
                try	{
198
                	skinOption = new Properties();
199
                    FileInputStream fis = new FileInputStream(skinPropertyFile);
200
                    skinOption.load(fis);
201
                    fis.close();
202
                } catch (IOException ioe) {
203
                    Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
204
                    logMetacat.error("Error in loading options for skin " + "skinName" +" : "
205
                            + ioe.getMessage());
206
                }                
207
                MetaCatUtil.skinconfigs.put(skinName, skinOption);
208
            }
209

    
210

    
211
	if (MetacatSpatialConstants.runSpatialOption == true ) {	    
212
        
213
	    // create a spatial index of the database
214
            MetacatSpatialConstants.setServerContext(MetaCatUtil.getOption("server"));
215
            MetacatSpatialQuery  _spatialQuery = new MetacatSpatialQuery();
216
            
217
            // issue the query  -- using the geographic bounds of the Earth
218
            MetacatSpatialDataset _data = _spatialQuery.queryDatasetByCartesianBounds(-180, -90, 180, 90);
219
            
220
            // write the data to the appropriate theme 
221
            _data.writeMetacatSpatialCache();
222
	 
223
	}
224
           
225
           
226
            MetaCatUtil.printMessage("Metacat (" + Version.getVersion()
227
                               + ") initialized.");
228

    
229
        } catch (ServletException ex) {
230
            throw ex;
231
        } catch (SQLException e) {
232
            Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
233
            logMetacat.error("Error in MetacatServlet.init: "
234
                    + e.getMessage());
235
        }
236
    }
237

    
238
    /**
239
     * Close all db connections from the pool
240
     */
241
    public void destroy()
242
    {
243
        // Close all db connection
244
        System.out.println("Destroying MetacatServlet");
245
        timer.cancel();
246
        IndexingQueue.getInstance().setMetacatRunning(false);
247
        DBConnectionPool.release();
248
    }
249

    
250
    /** Handle "GET" method requests from HTTP clients */
251
    public void doGet(HttpServletRequest request, HttpServletResponse response)
252
            throws ServletException, IOException
253
    {
254

    
255
        // Process the data and send back the response
256
        handleGetOrPost(request, response);
257
    }
258

    
259
    /** Handle "POST" method requests from HTTP clients */
260
    public void doPost(HttpServletRequest request, HttpServletResponse response)
261
            throws ServletException, IOException
262
    {
263

    
264
        // Process the data and send back the response
265
        handleGetOrPost(request, response);
266
    }
267

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

    
406
    /**
407
     * Control servlet response depending on the action parameter specified
408
     */
409
    private void handleGetOrPost(HttpServletRequest request,
410
            HttpServletResponse response) throws ServletException, IOException
411
    {
412
        MetaCatUtil util = new MetaCatUtil();
413
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
414
        
415
        /*
416
         * logMetacat.debug("Connection pool size: "
417
         * +connPool.getSizeOfDBConnectionPool(),10);
418
         * logMetacat.debug("Free DBConnection number: "
419
         */
420
        //If all DBConnection in the pool are free and DBConnection pool
421
        //size is greater than initial value, shrink the connection pool
422
        //size to initial value
423
        DBConnectionPool.shrinkDBConnectionPoolSize();
424

    
425
        //Debug message to print out the method which have a busy DBConnection
426
        try {
427
            DBConnectionPool pool = DBConnectionPool.getInstance();
428
            pool.printMethodNameHavingBusyDBConnection();
429
        } catch (SQLException e) {
430
            logMetacat.error("Error in MetacatServlet.handleGetOrPost: "
431
                    + e.getMessage());
432
            e.printStackTrace();
433
        }
434

    
435
        String ctype = request.getContentType();
436
        if (ctype != null && ctype.startsWith("multipart/form-data")) {
437
            handleMultipartForm(request, response);
438
        } else {
439

    
440
            String name = null;
441
            String[] value = null;
442
            String[] docid = new String[3];
443
            Hashtable params = new Hashtable();
444
            Enumeration paramlist = request.getParameterNames();
445

    
446
            while (paramlist.hasMoreElements()) {
447

    
448
                name = (String) paramlist.nextElement();
449
                value = request.getParameterValues(name);
450

    
451
                // Decode the docid and mouse click information
452
                if (name.endsWith(".y")) {
453
                    docid[0] = name.substring(0, name.length() - 2);
454
                    params.put("docid", docid);
455
                    name = "ypos";
456
                }
457
                if (name.endsWith(".x")) {
458
                    name = "xpos";
459
                }
460

    
461
                params.put(name, value);
462
            }
463

    
464
            //handle param is emptpy
465
            if (params.isEmpty() || params == null) { return; }
466

    
467
            //if the user clicked on the input images, decode which image
468
            //was clicked then set the action.
469
            if(params.get("action") == null){
470
                PrintWriter out = response.getWriter();
471
                response.setContentType("text/xml");
472
                out.println("<?xml version=\"1.0\"?>");
473
                out.println("<error>");
474
                out.println("Action not specified");
475
                out.println("</error>");
476
                out.close();
477
                return;
478
            }
479

    
480
            String action = ((String[]) params.get("action"))[0];
481
            logMetacat.info("Action is: " + action);
482

    
483
            // This block handles session management for the servlet
484
            // by looking up the current session information for all actions
485
            // other than "login" and "logout"
486
            String username = null;
487
            String password = null;
488
            String[] groupnames = null;
489
            String sess_id = null;
490
            name = null;
491
            
492
            // handle login action
493
            if (action.equals("login")) {
494
                PrintWriter out = response.getWriter();
495
                handleLoginAction(out, params, request, response);
496
                out.close();
497
        
498
                // handle logout action
499
            }   else if (action.equals("logout")) {
500
                PrintWriter out = response.getWriter();
501
                handleLogoutAction(out, params, request, response);
502
                out.close();
503

    
504
                // handle shrink DBConnection request
505
            } else if (action.equals("shrink")) {
506
                PrintWriter out = response.getWriter();
507
                boolean success = false;
508
                //If all DBConnection in the pool are free and DBConnection
509
                // pool
510
                //size is greater than initial value, shrink the connection
511
                // pool
512
                //size to initial value
513
                success = DBConnectionPool.shrinkConnectionPoolSize();
514
                if (success) {
515
                    //if successfully shrink the pool size to initial value
516
                    out.println("DBConnection Pool shrunk successfully.");
517
                }//if
518
                else {
519
                    out.println("DBConnection pool not shrunk successfully.");
520
                }
521
                //close out put
522
                out.close();
523

    
524
                // aware of session expiration on every request
525
            } else {
526
                HttpSession sess = request.getSession(true);
527
                if (sess.isNew() && !params.containsKey("sessionid")) {
528
                    // session expired or has not been stored b/w user requests
529
                    logMetacat.info(
530
                            "The session is new or no sessionid is assigned. The user is public");
531
                    username = "public";
532
                    sess.setAttribute("username", username);
533
                } else {
534
                    logMetacat.info("The session is either old or "
535
                            + "has sessionid parameter");
536
                    try {
537
                        if (params.containsKey("sessionid")) {
538
                            sess_id = ((String[]) params.get("sessionid"))[0];
539
                            logMetacat.info("in has sessionid "
540
                                    + sess_id);
541
                            if (sessionHash.containsKey(sess_id)) {
542
                                logMetacat.info("find the id "
543
                                        + sess_id + " in hash table");
544
                                sess = (HttpSession) sessionHash.get(sess_id);
545
                            }
546
                        } else {
547
                            // we already store the session in login, so we
548
                            // don't need here
549
                            /*
550
                             * logMetacat.info("in no sessionid
551
                             * parameter ", 40); sess_id =
552
                             * (String)sess.getId();
553
                             * logMetacat.info("storing the session id "
554
                             * + sess_id + " which has username " +
555
                             * sess.getAttribute("username") + " into session
556
                             * hash in handleGetOrPost method", 35);
557
                             */
558
                        }
559
                    } catch (IllegalStateException ise) {
560
                        logMetacat.error(
561
                                "Error in handleGetOrPost: this shouldn't "
562
                                + "happen: the session should be valid: "
563
                                + ise.getMessage());
564
                    }
565

    
566
                    username = (String) sess.getAttribute("username");
567
                    logMetacat.info("The user name from session is: "
568
                            + username);
569
                    password = (String) sess.getAttribute("password");
570
                    groupnames = (String[]) sess.getAttribute("groupnames");
571
                    name = (String) sess.getAttribute("name");
572
                }
573

    
574
                //make user user username should be public
575
                if (username == null || (username.trim().equals(""))) {
576
                    username = "public";
577
                }
578
                logMetacat.info("The user is : " + username);
579
            }
580
            // Now that we know the session is valid, we can delegate the
581
            // request
582
            // to a particular action handler
583
            if (action.equals("query")) {
584
                PrintWriter out = response.getWriter();
585
                handleQuery(out, params, response, username, groupnames,
586
                        sess_id);
587
                out.close();
588
            } else if (action.equals("squery")) {
589
                PrintWriter out = response.getWriter();
590
                if (params.containsKey("query")) {
591
                    handleSQuery(out, params, response, username, groupnames,
592
                            sess_id);
593
                    out.close();
594
                } else {
595
                    out.println(
596
                            "Illegal action squery without \"query\" parameter");
597
                    out.close();
598
                }
599
            } else if ( action.trim().equals("spatial_query")) {
600

    
601
              logMetacat.debug("******************* SPATIAL QUERY ********************");
602
              PrintWriter out = response.getWriter();
603
              handleSpatialQuery(out, params, response, username, groupnames, sess_id);
604
              out.close();
605
            
606
            } else if (action.equals("export")) {
607

    
608
                handleExportAction(params, response, username,
609
                        groupnames, password);
610
            } else if (action.equals("read")) {
611
                handleReadAction(params, request, response, username, password,
612
                        groupnames);
613
            } else if (action.equals("readinlinedata")) {
614
                handleReadInlineDataAction(params, request, response, username,
615
                        password, groupnames);
616
            } else if (action.equals("insert") || action.equals("update")) {
617
                PrintWriter out = response.getWriter();
618
                if ((username != null) && !username.equals("public")) {
619
                    handleInsertOrUpdateAction(request, response,
620
                            out, params, username, groupnames);
621
                } else {
622
                    response.setContentType("text/xml");
623
                    out.println("<?xml version=\"1.0\"?>");
624
                    out.println("<error>");
625
                    out.println("Permission denied for user " + username + " "
626
                            + action);
627
                    out.println("</error>");
628
                }
629
                out.close();
630
            } else if (action.equals("delete")) {
631
                PrintWriter out = response.getWriter();
632
                if ((username != null) && !username.equals("public")) {
633
                    handleDeleteAction(out, params, request, response, username,
634
                            groupnames);
635
                } else {
636
                    response.setContentType("text/xml");
637
                    out.println("<?xml version=\"1.0\"?>");
638
                    out.println("<error>");
639
                    out.println("Permission denied for " + action);
640
                    out.println("</error>");
641
                }
642
                out.close();
643
            } else if (action.equals("validate")) {
644
                PrintWriter out = response.getWriter();
645
                handleValidateAction(out, params);
646
                out.close();
647
            } else if (action.equals("setaccess")) {
648
                PrintWriter out = response.getWriter();
649
                handleSetAccessAction(out, params, username);
650
                out.close();
651
            } else if (action.equals("getaccesscontrol")) {
652
                PrintWriter out = response.getWriter();
653
                handleGetAccessControlAction(out, params, response, username,
654
                        groupnames);
655
                out.close();
656
            } else if (action.equals("getprincipals")) {
657
                PrintWriter out = response.getWriter();
658
                handleGetPrincipalsAction(out, username, password);
659
                out.close();
660
            } else if (action.equals("getdoctypes")) {
661
                PrintWriter out = response.getWriter();
662
                handleGetDoctypesAction(out, params, response);
663
                out.close();
664
            } else if (action.equals("getdtdschema")) {
665
                PrintWriter out = response.getWriter();
666
                handleGetDTDSchemaAction(out, params, response);
667
                out.close();
668
            } else if (action.equals("getlastdocid")) {
669
                PrintWriter out = response.getWriter();
670
                handleGetMaxDocidAction(out, params, response);
671
                out.close();
672
            } else if (action.equals("getrevisionanddoctype")) {
673
                PrintWriter out = response.getWriter();
674
                handleGetRevisionAndDocTypeAction(out, params);
675
                out.close();
676
            } else if (action.equals("getversion")) {
677
                response.setContentType("text/xml");
678
                PrintWriter out = response.getWriter();
679
                out.println(Version.getVersionAsXml());
680
                out.close();
681
            } else if (action.equals("getlog")) {
682
                handleGetLogAction(params, request, response, username, groupnames);
683
            } else if (action.equals("getloggedinuserinfo")) {
684
                PrintWriter out = response.getWriter();
685
                response.setContentType("text/xml");
686
                out.println("<?xml version=\"1.0\"?>");
687
                out.println("\n<user>\n");
688
                out.println("\n<username>\n");
689
                out.println(username);
690
                out.println("\n</username>\n");
691
                if(name!=null){
692
                	out.println("\n<name>\n");
693
                	out.println(name);
694
                	out.println("\n</name>\n");
695
                }
696
                if(MetaCatUtil.isAdministrator(username, groupnames)){
697
                	out.println("<isAdministrator></isAdministrator>\n");	
698
                }
699
                if(MetaCatUtil.isModerator(username, groupnames)){
700
                	out.println("<isModerator></isModerator>\n");	
701
                }
702
                out.println("\n</user>\n");
703
                out.close();
704
            } else if (action.equals("buildindex")) {
705
                handleBuildIndexAction(params, request, response, username, groupnames);
706
            } else if (action.equals("login") || action.equals("logout")) {
707
                /*
708
            } else if (action.equals("protocoltest")) {
709
                String testURL = "metacat://dev.nceas.ucsb.edu/NCEAS.897766.9";
710
                try {
711
                    testURL = ((String[]) params.get("url"))[0];
712
                } catch (Throwable t) {
713
                }
714
                String phandler = System
715
                        .getProperty("java.protocol.handler.pkgs");
716
                response.setContentType("text/html");
717
                PrintWriter out = response.getWriter();
718
                out.println("<body bgcolor=\"white\">");
719
                out.println("<p>Handler property: <code>" + phandler
720
                        + "</code></p>");
721
                out.println("<p>Starting test for:<br>");
722
                out.println("    " + testURL + "</p>");
723
                try {
724
                    URL u = new URL(testURL);
725
                    out.println("<pre>");
726
                    out.println("Protocol: " + u.getProtocol());
727
                    out.println("    Host: " + u.getHost());
728
                    out.println("    Port: " + u.getPort());
729
                    out.println("    Path: " + u.getPath());
730
                    out.println("     Ref: " + u.getRef());
731
                    String pquery = u.getQuery();
732
                    out.println("   Query: " + pquery);
733
                    out.println("  Params: ");
734
                    if (pquery != null) {
735
                        Hashtable qparams = MetaCatUtil.parseQuery(u.getQuery());
736
                        for (Enumeration en = qparams.keys(); en
737
                                .hasMoreElements();) {
738
                            String pname = (String) en.nextElement();
739
                            String pvalue = (String) qparams.get(pname);
740
                            out.println("    " + pname + ": " + pvalue);
741
                        }
742
                    }
743
                    out.println("</pre>");
744
                    out.println("</body>");
745
                    out.close();
746
                } catch (MalformedURLException mue) {
747
                    System.out.println(
748
                            "bad url from MetacatServlet.handleGetOrPost");
749
                    out.println(mue.getMessage());
750
                    mue.printStackTrace(out);
751
                    out.close();
752
                }
753
                */
754
            } else {
755
                PrintWriter out = response.getWriter();
756
                out.println("<?xml version=\"1.0\"?>");
757
                out.println("<error>");
758
                out.println(
759
                     "Error: action not registered.  Please report this error.");
760
                out.println("</error>");
761
                out.close();
762
            }
763

    
764
            //util.closeConnections();
765
            // Close the stream to the client
766
            //out.close();
767
        }
768
    }
769

    
770
    /////////////////////////////// METACAT SPATIAL ///////////////////////////
771

    
772
    /**
773
     * handles all spatial queries -- these queries may include any of the 
774
     * queries supported by the WFS / WMS standards
775
     * 
776
     * handleSQuery(out, params, response, username, groupnames,
777
     *                        sess_id);
778
     */
779
    private void handleSpatialQuery(PrintWriter out, Hashtable params, 
780
                                    HttpServletResponse response,
781
                                    String username, String[] groupnames, 
782
                                    String sess_id) {
783
      
784
      Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
785
      //MBJDELETED MetacatSpatialQuery _spatialQuery = new MetacatSpatialQuery();
786

    
787
	if (MetacatSpatialConstants.runSpatialOption == false ) {
788
        	response.setContentType("text/html");
789
        	out.println("<html> Metacat Spatial Option is turned off <html>");
790
        	out.close();
791
		return ;
792
	}		
793
      
794
      MetacatSpatialQuery _spatialQuery = new MetacatSpatialQuery();
795
      
796
      
797
      // switch -- html/xml print
798
      //MBJDELETED boolean printXML = false; 
799
      
800
      // get the spatial parameters
801
      logMetacat.debug("params: " +  params);
802
      //String _xmax =  (String)params.get("XMAX");
803
      float _xmax = Float.parseFloat( ((String[]) params.get("XMAX"))[0] );
804
      float _ymax = Float.parseFloat( ((String[]) params.get("YMAX"))[0] );
805
      float _xmin = Float.parseFloat( ((String[]) params.get("XMIN"))[0] );
806
      float _ymin = Float.parseFloat( ((String[]) params.get("YMIN"))[0] );
807
      logMetacat.debug("\nxmax: " + _xmax + " \nymax:" + _ymax +
808
                      "\nxmin: " + _xmin + "\nymin: " + _ymin);
809

    
810

    
811

    
812
      // issue the Spatial query 
813
      //MBJ DELETED MetacatSpatialDataset _data =  
814
        //MBJ DELETED _spatialQuery.queryDatasetByCartesianBounds(_xmin, _ymin, _xmax, _ymax);
815

    
816
      // report the number of documents returned:
817
      //MBJ DELETED logMetacat.warn("\nThe number of documents in the BBOX query: " 
818
              //MBJ DELETED + _data.size()+" the doc. list: '" + _data.toTXT().trim()+"'" );
819
     
820
/* MBJ DELETED -- using Metacat query instead
821
if (  _data.size() > 0) { 
822
      logMetacat.warn("\nThe number of documents in the BBOX query: " 
823
              + _data.size()+" the doc. list: '" + _data.toTXT().trim()+"'" );
824
     
825
      
826
      // create an s-query
827
      String[] queryArray = new String[1];
828
      queryArray[0] = DocumentIdQuery.createDocidQuery(_data.getDocidList());
829
      params.put("query", queryArray);
830
      
831
      // qformat        
832
      String[] qformatArray = new String[1];
833
      qformatArray[0] = "knp";
834
      params.put("qformat", qformatArray);
835

    
836
      // change the action 
837
      String[] actionArray = new String[1];
838
      actionArray[0] = "squery";
839
      params.put("action", actionArray);
840

    
841
      // return the list of docs and point at the spatial theme 
842
      if ( printXML) {
843
        response.setContentType("text/xml");
844
        out.println(_data.toXML() ); // write the data as xml
845
        out.close();
846
      } else {
847
        logMetacat.warn("username: " + username+"\nsession: "+sess_id);
848
        handleSQuery(out, params, response, username, groupnames, sess_id);  
849
      }
850
} else {
851
        response.setContentType("text/html");
852
        out.println("<html>No Datasets Selected <html>");
853
        out.close();
854
}
855
*/
856
      	// create an s-query
857
        String spatialQuery = createSpatialQuery(_xmax, _ymax, _xmin, _ymin);
858
      	String[] queryArray = new String[1];
859
      	queryArray[0] = spatialQuery;
860
      	params.put("query", queryArray);
861
      	
862
      	// qformat        
863
      	String[] qformatArray = new String[1];
864
      	qformatArray[0] = "knp";
865
      	params.put("qformat", qformatArray);
866
	
867
      	// change the action 
868
      	String[] actionArray = new String[1];
869
      	actionArray[0] = "squery";
870
      	params.put("action", actionArray);
871

    
872
        handleSQuery(out, params, response, username, groupnames, sess_id);  
873
    }
874

    
875
    /**
876
     * Create a metacat squery for spatial data coordinates.
877
     */
878
    private String createSpatialQuery(float _xmin, float _ymin, float _xmax, float _ymax) {
879
	StringBuffer sb = new StringBuffer();
880
	    
881
	sb.append("<pathquery version=\"1.2\">");
882
	sb.append("<querytitle>Untitled-Search-3</querytitle>");
883
	sb.append("<returndoctype>-//ecoinformatics.org//eml-dataset-2.0.0beta4//EN</returndoctype>");
884
	sb.append("<returndoctype>-//ecoinformatics.org//eml-dataset-2.0.0beta6//EN</returndoctype>");
885
	sb.append("<returndoctype>-//NCEAS//eml-dataset-2.0//EN</returndoctype>");
886
	sb.append("<returndoctype>-//NCEAS//resource//EN</returndoctype>");
887
	sb.append("<returndoctype>eml://ecoinformatics.org/eml-2.0.0</returndoctype>");
888
	sb.append("<returndoctype>eml://ecoinformatics.org/eml-2.0.1</returndoctype>");
889
	sb.append("<returndoctype>metadata</returndoctype>");
890
	sb.append("<returnfield>dataset/title</returnfield>");
891
	sb.append("<returnfield>originator/individualName/surName</returnfield>");
892
	sb.append("<returnfield>originator/individualName/givenName</returnfield>");
893
	sb.append("<returnfield>originator/organizationName</returnfield>");
894
	sb.append("<returnfield>creator/individualName/surName</returnfield>");
895
	sb.append("<returnfield>creator/individualName/givenName</returnfield>");
896
	sb.append("<returnfield>creator/organizationName</returnfield>");
897
	sb.append("<returnfield>keyword</returnfield>");
898
	sb.append("<returnfield>entityName</returnfield>");
899
	sb.append("<returnfield>idinfo/citation/citeinfo/title</returnfield>");
900
	sb.append("<returnfield>idinfo/citation/citeinfo/origin</returnfield>");
901
	sb.append("<returnfield>idinfo/keywords/theme/themekey</returnfield>");
902
	sb.append("<querygroup operator=\"INTERSECT\">");
903
	sb.append("<queryterm searchmode=\"less-than\" casesensitive=\"false\">");
904
	sb.append("<value>" + _ymin + "</value>");
905
	sb.append("<pathexpr>northBoundingCoordinate</pathexpr>");
906
	sb.append("</queryterm>");
907
	sb.append("<queryterm searchmode=\"greater-than\" casesensitive=\"false\">");
908
	sb.append("<value>" + _ymax + "</value>");
909
	sb.append("<pathexpr>northBoundingCoordinate</pathexpr>");
910
	sb.append("</queryterm>");
911
	sb.append("<queryterm searchmode=\"less-than\" casesensitive=\"false\">");
912
	sb.append("<value>" + _xmin + "</value>");
913
	sb.append("<pathexpr>westBoundingCoordinate</pathexpr>");
914
	sb.append("</queryterm>");
915
	sb.append("<queryterm searchmode=\"greater-than\" casesensitive=\"false\">");
916
	sb.append("<value>" + _xmax + "</value>");
917
	sb.append("<pathexpr>westBoundingCoordinate</pathexpr>");
918
	sb.append("</queryterm>");
919
	sb.append("</querygroup>");
920
	sb.append("</pathquery>");
921

    
922
	return sb.toString();
923
    }
924

    
925
    // LOGIN & LOGOUT SECTION
926
    /**
927
     * Handle the login request. Create a new session object. Do user
928
     * authentication through the session.
929
     */
930
    private void handleLoginAction(PrintWriter out, Hashtable params,
931
            HttpServletRequest request, HttpServletResponse response)
932
    {
933
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
934
        AuthSession sess = null;
935

    
936
        if(params.get("username") == null){
937
            response.setContentType("text/xml");
938
            out.println("<?xml version=\"1.0\"?>");
939
            out.println("<error>");
940
            out.println("Username not specified");
941
            out.println("</error>");
942
            return;
943
        }
944

    
945
        //}
946

    
947
        if(params.get("password") == null){
948
            response.setContentType("text/xml");
949
            out.println("<?xml version=\"1.0\"?>");
950
            out.println("<error>");
951
            out.println("Password not specified");
952
            out.println("</error>");
953
            return;
954
        }
955

    
956
        String un = ((String[]) params.get("username"))[0];
957
        logMetacat.info("user " + un + " is trying to login");
958
        String pw = ((String[]) params.get("password"))[0];
959

    
960
        String qformat = "xml";
961
        if(params.get("qformat") != null){
962
            qformat = ((String[]) params.get("qformat"))[0];
963
        }
964

    
965
        try {
966
            sess = new AuthSession();
967
        } catch (Exception e) {
968
            System.out.println("error in MetacatServlet.handleLoginAction: "
969
                    + e.getMessage());
970
            out.println(e.getMessage());
971
            return;
972
        }
973
        boolean isValid = sess.authenticate(request, un, pw);
974

    
975
        //if it is authernticate is true, store the session
976
        if (isValid) {
977
            HttpSession session = sess.getSessions();
978
            String id = session.getId();
979
            logMetacat.info("Store session id " + id
980
                    + "which has username" + session.getAttribute("username")
981
                    + " into hash in login method");
982
            sessionHash.put(id, session);
983
        }
984

    
985
        // format and transform the output
986
        if (qformat.equals("xml")) {
987
            response.setContentType("text/xml");
988
            out.println(sess.getMessage());
989
        } else {
990
            try {
991
                DBTransform trans = new DBTransform();
992
                response.setContentType("text/html");
993
                trans.transformXMLDocument(sess.getMessage(),
994
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
995
                        out, null);
996
            } catch (Exception e) {
997

    
998
                logMetacat.error(
999
                        "Error in MetaCatServlet.handleLoginAction: "
1000
                                + e.getMessage());
1001
            }
1002
        }
1003
    }
1004

    
1005
    /**
1006
     * Handle the logout request. Close the connection.
1007
     */
1008
    private void handleLogoutAction(PrintWriter out, Hashtable params,
1009
            HttpServletRequest request, HttpServletResponse response)
1010
    {
1011
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1012
        String qformat = "xml";
1013
        if(params.get("qformat") != null){
1014
            qformat = ((String[]) params.get("qformat"))[0];
1015
        }
1016

    
1017
        // close the connection
1018
        HttpSession sess = request.getSession(false);
1019
        logMetacat.info("After get session in logout request");
1020
        if (sess != null) {
1021
            logMetacat.info("The session id " + sess.getId()
1022
                    + " will be invalidate in logout action");
1023
            logMetacat.info("The session contains user "
1024
                    + sess.getAttribute("username")
1025
                    + " will be invalidate in logout action");
1026
            sess.invalidate();
1027
        }
1028

    
1029
        // produce output
1030
        StringBuffer output = new StringBuffer();
1031
        output.append("<?xml version=\"1.0\"?>");
1032
        output.append("<logout>");
1033
        output.append("User logged out");
1034
        output.append("</logout>");
1035

    
1036
        //format and transform the output
1037
        if (qformat.equals("xml")) {
1038
            response.setContentType("text/xml");
1039
            out.println(output.toString());
1040
        } else {
1041
            try {
1042
                DBTransform trans = new DBTransform();
1043
                response.setContentType("text/html");
1044
                trans.transformXMLDocument(output.toString(),
1045
                        "-//NCEAS//login//EN", "-//W3C//HTML//EN", qformat,
1046
                        out, null);
1047
            } catch (Exception e) {
1048
                logMetacat.error(
1049
                        "Error in MetaCatServlet.handleLogoutAction"
1050
                                + e.getMessage());
1051
            }
1052
        }
1053
    }
1054

    
1055
    // END OF LOGIN & LOGOUT SECTION
1056

    
1057
    // SQUERY & QUERY SECTION
1058
    /**
1059
     * Retreive the squery xml, execute it and display it
1060
     *
1061
     * @param out the output stream to the client
1062
     * @param params the Hashtable of parameters that should be included in the
1063
     *            squery.
1064
     * @param response the response object linked to the client
1065
     * @param conn the database connection
1066
     */
1067
    private void handleSQuery(PrintWriter out, Hashtable params,
1068
            HttpServletResponse response, String user, String[] groups,
1069
            String sessionid)
1070
    {
1071
        double startTime = System.currentTimeMillis() / 1000;
1072
        DBQuery queryobj = new DBQuery();
1073
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
1074
        double outPutTime = System.currentTimeMillis() / 1000;
1075
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1076
        logMetacat.info("Total search time for action 'squery': "
1077
                + (outPutTime - startTime));
1078
    }
1079

    
1080
    /**
1081
     * Create the xml query, execute it and display the results.
1082
     *
1083
     * @param out the output stream to the client
1084
     * @param params the Hashtable of parameters that should be included in the
1085
     *            squery.
1086
     * @param response the response object linked to the client
1087
     */
1088
    private void handleQuery(PrintWriter out, Hashtable params,
1089
            HttpServletResponse response, String user, String[] groups,
1090
            String sessionid)
1091
    {
1092
        //create the query and run it
1093
        String xmlquery = DBQuery.createSQuery(params);
1094
        String[] queryArray = new String[1];
1095
        queryArray[0] = xmlquery;
1096
        params.put("query", queryArray);
1097
        double startTime = System.currentTimeMillis() / 1000;
1098
        DBQuery queryobj = new DBQuery();
1099
        queryobj.findDocuments(response, out, params, user, groups, sessionid);
1100
        double outPutTime = System.currentTimeMillis() / 1000;
1101
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1102
        logMetacat.info("Total search time for action 'query': "
1103
                + (outPutTime - startTime));
1104

    
1105
        //handleSQuery(out, params, response,user, groups, sessionid);
1106
    }
1107

    
1108
    // END OF SQUERY & QUERY SECTION
1109

    
1110
    //Exoport section
1111
    /**
1112
     * Handle the "export" request of data package from Metacat in zip format
1113
     *
1114
     * @param params the Hashtable of HTTP request parameters
1115
     * @param response the HTTP response object linked to the client
1116
     * @param user the username sent the request
1117
     * @param groups the user's groupnames
1118
     */
1119
    private void handleExportAction(Hashtable params,
1120
            HttpServletResponse response,
1121
            String user, String[] groups, String passWord)
1122
    {
1123
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1124
        // Output stream
1125
        ServletOutputStream out = null;
1126
        // Zip output stream
1127
        ZipOutputStream zOut = null;
1128
        DBQuery queryObj = null;
1129

    
1130
        String[] docs = new String[10];
1131
        String docId = "";
1132

    
1133
        try {
1134
            // read the params
1135
            if (params.containsKey("docid")) {
1136
                docs = (String[]) params.get("docid");
1137
            }
1138
            // Create a DBuery to handle export
1139
            queryObj = new DBQuery();
1140
            // Get the docid
1141
            docId = docs[0];
1142
            // Make sure the client specify docid
1143
            if (docId == null || docId.equals("")) {
1144
                response.setContentType("text/xml"); //MIME type
1145
                // Get a printwriter
1146
                PrintWriter pw = response.getWriter();
1147
                // Send back message
1148
                pw.println("<?xml version=\"1.0\"?>");
1149
                pw.println("<error>");
1150
                pw.println("You didn't specify requested docid");
1151
                pw.println("</error>");
1152
                // Close printwriter
1153
                pw.close();
1154
                return;
1155
            }
1156
            // Get output stream
1157
            out = response.getOutputStream();
1158
            response.setContentType("application/zip"); //MIME type
1159
            response.setHeader("Content-Disposition", 
1160
            		"attachment; filename=" 
1161
            		+ docId + ".zip"); // Set the name of the zip file
1162
            		
1163
            zOut = new ZipOutputStream(out);
1164
            zOut = queryObj
1165
                    .getZippedPackage(docId, out, user, groups, passWord);
1166
            zOut.finish(); //terminate the zip file
1167
            zOut.close(); //close the zip stream
1168

    
1169
        } catch (Exception e) {
1170
            try {
1171
                response.setContentType("text/xml"); //MIME type
1172
                // Send error message back
1173
                if (out != null) {
1174
                    PrintWriter pw = new PrintWriter(out);
1175
                    pw.println("<?xml version=\"1.0\"?>");
1176
                    pw.println("<error>");
1177
                    pw.println(e.getMessage());
1178
                    pw.println("</error>");
1179
                    // Close printwriter
1180
                    pw.close();
1181
                    // Close output stream
1182
                    out.close();
1183
                }
1184
                // Close zip output stream
1185
                if (zOut != null) {
1186
                    zOut.close();
1187
                }
1188
            } catch (IOException ioe) {
1189
                logMetacat.error("Problem with the servlet output "
1190
                        + "in MetacatServlet.handleExportAction: "
1191
                        + ioe.getMessage());
1192
            }
1193

    
1194
            logMetacat.error(
1195
                    "Error in MetacatServlet.handleExportAction: "
1196
                            + e.getMessage());
1197
            e.printStackTrace(System.out);
1198

    
1199
        }
1200

    
1201
    }
1202

    
1203
    /**
1204
     * In eml2 document, the xml can have inline data and data was stripped off
1205
     * and store in file system. This action can be used to read inline data
1206
     * only
1207
     *
1208
     * @param params the Hashtable of HTTP request parameters
1209
     * @param response the HTTP response object linked to the client
1210
     * @param user the username sent the request
1211
     * @param groups the user's groupnames
1212
     */
1213
    private void handleReadInlineDataAction(Hashtable params,
1214
            HttpServletRequest request, HttpServletResponse response,
1215
            String user, String passWord, String[] groups)
1216
    {
1217
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1218
        String[] docs = new String[10];
1219
        String inlineDataId = null;
1220
        String docId = "";
1221
        ServletOutputStream out = null;
1222

    
1223
        try {
1224
            // read the params
1225
            if (params.containsKey("inlinedataid")) {
1226
                docs = (String[]) params.get("inlinedataid");
1227
            }
1228
            // Get the docid
1229
            inlineDataId = docs[0];
1230
            // Make sure the client specify docid
1231
            if (inlineDataId == null || inlineDataId.equals("")) {
1232
                throw new Exception("You didn't specify requested inlinedataid"); }
1233

    
1234
            // check for permission
1235
            docId = MetaCatUtil
1236
                    .getDocIdWithoutRevFromInlineDataID(inlineDataId);
1237
            PermissionController controller = new PermissionController(docId);
1238
            // check top level read permission
1239
            if (!controller.hasPermission(user, groups,
1240
                    AccessControlInterface.READSTRING))
1241
            {
1242
                throw new Exception("User " + user
1243
                        + " doesn't have permission " + " to read document "
1244
                        + docId);
1245
            }
1246
            else
1247
            {
1248
              //check data access level
1249
              try
1250
              {
1251
                Hashtable unReadableInlineDataList =
1252
                    PermissionController.getUnReadableInlineDataIdList(docId,
1253
                    user, groups, false);
1254
                if (unReadableInlineDataList.containsValue(
1255
                          MetaCatUtil.getInlineDataIdWithoutRev(inlineDataId)))
1256
                {
1257
                  throw new Exception("User " + user
1258
                       + " doesn't have permission " + " to read inlinedata "
1259
                       + inlineDataId);
1260

    
1261
                }//if
1262
              }//try
1263
              catch (Exception e)
1264
              {
1265
                throw e;
1266
              }//catch
1267
            }//else
1268

    
1269
            // Get output stream
1270
            out = response.getOutputStream();
1271
            // read the inline data from the file
1272
            String inlinePath = MetaCatUtil.getOption("inlinedatafilepath");
1273
            File lineData = new File(inlinePath, inlineDataId);
1274
            FileInputStream input = new FileInputStream(lineData);
1275
            byte[] buffer = new byte[4 * 1024];
1276
            int bytes = input.read(buffer);
1277
            while (bytes != -1) {
1278
                out.write(buffer, 0, bytes);
1279
                bytes = input.read(buffer);
1280
            }
1281
            out.close();
1282

    
1283
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1284
                    inlineDataId, "readinlinedata");
1285
        } catch (Exception e) {
1286
            try {
1287
                PrintWriter pw = null;
1288
                // Send error message back
1289
                if (out != null) {
1290
                    pw = new PrintWriter(out);
1291
                } else {
1292
                    pw = response.getWriter();
1293
                }
1294
                pw.println("<?xml version=\"1.0\"?>");
1295
                pw.println("<error>");
1296
                pw.println(e.getMessage());
1297
                pw.println("</error>");
1298
                // Close printwriter
1299
                pw.close();
1300
                // Close output stream if out is not null
1301
                if (out != null) {
1302
                    out.close();
1303
                }
1304
            } catch (IOException ioe) {
1305
                logMetacat.error("Problem with the servlet output "
1306
                        + "in MetacatServlet.handleExportAction: "
1307
                        + ioe.getMessage());
1308
            }
1309
            logMetacat.error(
1310
                    "Error in MetacatServlet.handleReadInlineDataAction: "
1311
                            + e.getMessage());
1312
        }
1313
    }
1314

    
1315
    /*
1316
     * Get the nodeid from xml_nodes for the inlinedataid
1317
     */
1318
    private long getInlineDataNodeId(String inLineDataId, String docId)
1319
            throws SQLException
1320
    {
1321
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1322
        long nodeId = 0;
1323
        String INLINE = "inline";
1324
        boolean hasRow;
1325
        PreparedStatement pStmt = null;
1326
        DBConnection conn = null;
1327
        int serialNumber = -1;
1328
        String sql = "SELECT nodeid FROM xml_nodes WHERE docid=? AND nodedata=? "
1329
                + "AND nodetype='TEXT' AND parentnodeid IN "
1330
                + "(SELECT nodeid FROM xml_nodes WHERE docid=? AND "
1331
                + "nodetype='ELEMENT' AND nodename='" + INLINE + "')";
1332

    
1333
        try {
1334
            //check out DBConnection
1335
            conn = DBConnectionPool
1336
                    .getDBConnection("AccessControlList.isAllowFirst");
1337
            serialNumber = conn.getCheckOutSerialNumber();
1338

    
1339
            pStmt = conn.prepareStatement(sql);
1340
            //bind value
1341
            pStmt.setString(1, docId);//docid
1342
            pStmt.setString(2, inLineDataId);//inlinedataid
1343
            pStmt.setString(3, docId);
1344
            // excute query
1345
            pStmt.execute();
1346
            ResultSet rs = pStmt.getResultSet();
1347
            hasRow = rs.next();
1348
            // get result
1349
            if (hasRow) {
1350
                nodeId = rs.getLong(1);
1351
            }//if
1352

    
1353
        } catch (SQLException e) {
1354
            throw e;
1355
        } finally {
1356
            try {
1357
                pStmt.close();
1358
            } finally {
1359
                DBConnectionPool.returnDBConnection(conn, serialNumber);
1360
            }
1361
        }
1362
        logMetacat.debug("The nodeid for inlinedataid " + inLineDataId
1363
                + " is: " + nodeId);
1364
        return nodeId;
1365
    }
1366

    
1367
    /**
1368
     * Handle the "read" request of metadata/data files from Metacat or any
1369
     * files from Internet; transformed metadata XML document into HTML
1370
     * presentation if requested; zip files when more than one were requested.
1371
     *
1372
     * @param params the Hashtable of HTTP request parameters
1373
     * @param request the HTTP request object linked to the client
1374
     * @param response the HTTP response object linked to the client
1375
     * @param user the username sent the request
1376
     * @param groups the user's groupnames
1377
     */
1378
    private void handleReadAction(Hashtable params, HttpServletRequest request,
1379
            HttpServletResponse response, String user, String passWord,
1380
            String[] groups)
1381
    {
1382
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1383
        ServletOutputStream out = null;
1384
        ZipOutputStream zout = null;
1385
        PrintWriter pw = null;
1386
        boolean zip = false;
1387
        boolean withInlineData = true;
1388

    
1389
        try {
1390
            String[] docs = new String[0];
1391
            String docid = "";
1392
            String qformat = "";
1393
            String abstrpath = null;
1394

    
1395
            // read the params
1396
            if (params.containsKey("docid")) {
1397
                docs = (String[]) params.get("docid");
1398
            }
1399
            if (params.containsKey("qformat")) {
1400
                qformat = ((String[]) params.get("qformat"))[0];
1401
            }
1402
            // the param for only metadata (eml)
1403
            // we don't support read a eml document without inline data now.
1404
            /*if (params.containsKey("inlinedata")) {
1405

    
1406
                String inlineData = ((String[]) params.get("inlinedata"))[0];
1407
                if (inlineData.equalsIgnoreCase("false")) {
1408
                    withInlineData = false;
1409
                }
1410
            }*/
1411
            if ((docs.length > 1) || qformat.equals("zip")) {
1412
                zip = true;
1413
                out = response.getOutputStream();
1414
                response.setContentType("application/zip"); //MIME type
1415
                zout = new ZipOutputStream(out);
1416
            }
1417
            // go through the list of docs to read
1418
            for (int i = 0; i < docs.length; i++) {
1419
                try {
1420

    
1421
                    URL murl = new URL(docs[i]);
1422
                    Hashtable murlQueryStr = MetaCatUtil.parseQuery(
1423
                            murl.getQuery());
1424
                    // case docid="http://.../?docid=aaa"
1425
                    // or docid="metacat://.../?docid=bbb"
1426
                    if (murlQueryStr.containsKey("docid")) {
1427
                        // get only docid, eliminate the rest
1428
                        docid = (String) murlQueryStr.get("docid");
1429
                        if (zip) {
1430
                            addDocToZip(request, docid, zout, user, groups);
1431
                        } else {
1432
                            readFromMetacat(request, response, docid, qformat,
1433
                                    abstrpath, user, groups, zip, zout,
1434
                                    withInlineData, params);
1435
                        }
1436

    
1437
                        // case docid="http://.../filename"
1438
                    } else {
1439
                        docid = docs[i];
1440
                        if (zip) {
1441
                            addDocToZip(request, docid, zout, user, groups);
1442
                        } else {
1443
                            readFromURLConnection(response, docid);
1444
                        }
1445
                    }
1446

    
1447
                } catch (MalformedURLException mue) {
1448
                    docid = docs[i];
1449
                    if (zip) {
1450
                        addDocToZip(request, docid, zout, user, groups);
1451
                    } else {
1452
                        readFromMetacat(request, response, docid, qformat,
1453
                                abstrpath, user, groups, zip, zout,
1454
                                withInlineData, params);
1455
                    }
1456
                }
1457
            }
1458

    
1459
            if (zip) {
1460
                zout.finish(); //terminate the zip file
1461
                zout.close(); //close the zip stream
1462
            }
1463

    
1464
        } catch (McdbDocNotFoundException notFoundE) {
1465
            // To handle doc not found exception
1466
            // the docid which didn't be found
1467
            String notFoundDocId = notFoundE.getUnfoundDocId();
1468
            String notFoundRevision = notFoundE.getUnfoundRevision();
1469
            logMetacat.warn("Missed id: " + notFoundDocId);
1470
            logMetacat.warn("Missed rev: " + notFoundRevision);
1471
            try {
1472
                // read docid from remote server
1473
                readFromRemoteMetaCat(response, notFoundDocId,
1474
                        notFoundRevision, user, passWord, out, zip, zout);
1475
                // Close zout outputstream
1476
                if (zout != null) {
1477
                    zout.close();
1478
                }
1479
                // close output stream
1480
                if (out != null) {
1481
                    out.close();
1482
                }
1483

    
1484
            } catch (Exception exc) {
1485
                logMetacat.error(
1486
                        "Erorr in MetacatServlet.hanldReadAction: "
1487
                                + exc.getMessage());
1488
                try {
1489
                    if (out != null) {
1490
                        response.setContentType("text/xml");
1491
                        // Send back error message by printWriter
1492
                        pw = new PrintWriter(out);
1493
                        pw.println("<?xml version=\"1.0\"?>");
1494
                        pw.println("<error>");
1495
                        pw.println(notFoundE.getMessage());
1496
                        pw.println("</error>");
1497
                        pw.close();
1498
                        out.close();
1499

    
1500
                    } else {
1501
                        response.setContentType("text/xml"); //MIME type
1502
                        // Send back error message if out = null
1503
                        if (pw == null) {
1504
                            // If pw is null, open the respnose
1505
                            pw = response.getWriter();
1506
                        }
1507
                        pw.println("<?xml version=\"1.0\"?>");
1508
                        pw.println("<error>");
1509
                        pw.println(notFoundE.getMessage());
1510
                        pw.println("</error>");
1511
                        pw.close();
1512
                    }
1513
                    // close zout
1514
                    if (zout != null) {
1515
                        zout.close();
1516
                    }
1517
                } catch (IOException ie) {
1518
                    logMetacat.error("Problem with the servlet output "
1519
                            + "in MetacatServlet.handleReadAction: "
1520
                            + ie.getMessage());
1521
                }
1522
            }
1523
        } catch (Exception e) {
1524
            try {
1525

    
1526
                if (out != null) {
1527
                    response.setContentType("text/xml"); //MIME type
1528
                    pw = new PrintWriter(out);
1529
                    pw.println("<?xml version=\"1.0\"?>");
1530
                    pw.println("<error>");
1531
                    pw.println(e.getMessage());
1532
                    pw.println("</error>");
1533
                    pw.close();
1534
                    out.close();
1535
                } else {
1536
                    response.setContentType("text/xml"); //MIME type
1537
                    // Send back error message if out = null
1538
                    if (pw == null) {
1539
                        pw = response.getWriter();
1540
                    }
1541
                    pw.println("<?xml version=\"1.0\"?>");
1542
                    pw.println("<error>");
1543
                    pw.println(e.getMessage());
1544
                    pw.println("</error>");
1545
                    pw.close();
1546

    
1547
                }
1548
                // Close zip output stream
1549
                if (zout != null) {
1550
                    zout.close();
1551
                }
1552

    
1553
            } catch (IOException ioe) {
1554
                logMetacat.error("Problem with the servlet output "
1555
                        + "in MetacatServlet.handleReadAction: "
1556
                        + ioe.getMessage());
1557
                ioe.printStackTrace(System.out);
1558

    
1559
            }
1560

    
1561
            logMetacat.error(
1562
                    "Error in MetacatServlet.handleReadAction: "
1563
                            + e.getMessage());
1564
            //e.printStackTrace(System.out);
1565
        }
1566
    }
1567

    
1568
    /** read metadata or data from Metacat
1569
     */
1570
    private void readFromMetacat(HttpServletRequest request,
1571
            HttpServletResponse response, String docid, String qformat,
1572
            String abstrpath, String user, String[] groups, boolean zip,
1573
            ZipOutputStream zout, boolean withInlineData, Hashtable params)
1574
            throws ClassNotFoundException, IOException, SQLException,
1575
            McdbException, Exception
1576
    {
1577
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1578
        try {
1579
            
1580
            // here is hack for handle docid=john.10(in order to tell mike.jim.10.1
1581
            // mike.jim.10, we require to provide entire docid with rev). But
1582
            // some old client they only provide docid without rev, so we need
1583
            // to handle this suituation. First we will check how many
1584
            // seperator here, if only one, we will append the rev in xml_documents
1585
            // to the id.
1586
            docid = appendRev(docid);
1587
         
1588
            DocumentImpl doc = new DocumentImpl(docid);
1589

    
1590
            //check the permission for read
1591
            if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1592
                Exception e = new Exception("User " + user
1593
                        + " does not have permission"
1594
                        + " to read the document with the docid " + docid);
1595

    
1596
                throw e;
1597
            }
1598

    
1599
            if (doc.getRootNodeID() == 0) {
1600
                // this is data file
1601
                String filepath = MetaCatUtil.getOption("datafilepath");
1602
                if (!filepath.endsWith("/")) {
1603
                    filepath += "/";
1604
                }
1605
                String filename = filepath + docid;
1606
                FileInputStream fin = null;
1607
                fin = new FileInputStream(filename);
1608

    
1609
                //MIME type
1610
                String contentType = getServletContext().getMimeType(filename);
1611
                if (contentType == null) {
1612
                    ContentTypeProvider provider = new ContentTypeProvider(
1613
                            docid);
1614
                    contentType = provider.getContentType();
1615
                    logMetacat.info("Final contenttype is: "
1616
                            + contentType);
1617
                }
1618

    
1619
                response.setContentType(contentType);
1620
                // if we decide to use "application/octet-stream" for all data
1621
                // returns
1622
                // response.setContentType("application/octet-stream");
1623

    
1624
                try {
1625

    
1626
                    ServletOutputStream out = response.getOutputStream();
1627
                    byte[] buf = new byte[4 * 1024]; // 4K buffer
1628
                    int b = fin.read(buf);
1629
                    while (b != -1) {
1630
                        out.write(buf, 0, b);
1631
                        b = fin.read(buf);
1632
                    }
1633
                } finally {
1634
                    if (fin != null) fin.close();
1635
                }
1636

    
1637
            } else {
1638
                // this is metadata doc
1639
                if (qformat.equals("xml") || qformat.equals("")) {
1640
                    // if equals "", that means no qformat is specified. hence
1641
                    // by default the document should be returned in xml format
1642
                    // set content type first
1643
                    response.setContentType("text/xml"); //MIME type
1644
                    PrintWriter out = response.getWriter();
1645
                    doc.toXml(out, user, groups, withInlineData);
1646
                } else {
1647
                    response.setContentType("text/html"); //MIME type
1648
                    PrintWriter out = response.getWriter();
1649

    
1650
                    // Look up the document type
1651
                    String doctype = doc.getDoctype();
1652
                    // Transform the document to the new doctype
1653
                    DBTransform dbt = new DBTransform();
1654
                    dbt.transformXMLDocument(doc.toString(user, groups,
1655
                            withInlineData), doctype, "-//W3C//HTML//EN",
1656
                            qformat, out, params);
1657
                }
1658

    
1659
            }
1660
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1661
                    docid, "read");
1662
        } catch (Exception except) {
1663
            throw except;
1664
        }
1665
    }
1666

    
1667
    /**
1668
     * read data from URLConnection
1669
     */
1670
    private void readFromURLConnection(HttpServletResponse response,
1671
            String docid) throws IOException, MalformedURLException
1672
    {
1673
        ServletOutputStream out = response.getOutputStream();
1674
        String contentType = getServletContext().getMimeType(docid); //MIME
1675
                                                                     // type
1676
        if (contentType == null) {
1677
            if (docid.endsWith(".xml")) {
1678
                contentType = "text/xml";
1679
            } else if (docid.endsWith(".css")) {
1680
                contentType = "text/css";
1681
            } else if (docid.endsWith(".dtd")) {
1682
                contentType = "text/plain";
1683
            } else if (docid.endsWith(".xsd")) {
1684
                contentType = "text/xml";
1685
            } else if (docid.endsWith("/")) {
1686
                contentType = "text/html";
1687
            } else {
1688
                File f = new File(docid);
1689
                if (f.isDirectory()) {
1690
                    contentType = "text/html";
1691
                } else {
1692
                    contentType = "application/octet-stream";
1693
                }
1694
            }
1695
        }
1696
        response.setContentType(contentType);
1697
        // if we decide to use "application/octet-stream" for all data returns
1698
        // response.setContentType("application/octet-stream");
1699

    
1700
        // this is http url
1701
        URL url = new URL(docid);
1702
        BufferedInputStream bis = null;
1703
        try {
1704
            bis = new BufferedInputStream(url.openStream());
1705
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1706
            int b = bis.read(buf);
1707
            while (b != -1) {
1708
                out.write(buf, 0, b);
1709
                b = bis.read(buf);
1710
            }
1711
        } finally {
1712
            if (bis != null) bis.close();
1713
        }
1714

    
1715
    }
1716

    
1717
    /**
1718
     * read file/doc and write to ZipOutputStream
1719
     *
1720
     * @param docid
1721
     * @param zout
1722
     * @param user
1723
     * @param groups
1724
     * @throws ClassNotFoundException
1725
     * @throws IOException
1726
     * @throws SQLException
1727
     * @throws McdbException
1728
     * @throws Exception
1729
     */
1730
    private void addDocToZip(HttpServletRequest request, String docid,
1731
            ZipOutputStream zout, String user, String[] groups) throws
1732
            ClassNotFoundException, IOException, SQLException, McdbException,
1733
            Exception
1734
    {
1735
        byte[] bytestring = null;
1736
        ZipEntry zentry = null;
1737

    
1738
        try {
1739
            URL url = new URL(docid);
1740

    
1741
            // this http url; read from URLConnection; add to zip
1742
            zentry = new ZipEntry(docid);
1743
            zout.putNextEntry(zentry);
1744
            BufferedInputStream bis = null;
1745
            try {
1746
                bis = new BufferedInputStream(url.openStream());
1747
                byte[] buf = new byte[4 * 1024]; // 4K buffer
1748
                int b = bis.read(buf);
1749
                while (b != -1) {
1750
                    zout.write(buf, 0, b);
1751
                    b = bis.read(buf);
1752
                }
1753
            } finally {
1754
                if (bis != null) bis.close();
1755
            }
1756
            zout.closeEntry();
1757

    
1758
        } catch (MalformedURLException mue) {
1759

    
1760
            // this is metacat doc (data file or metadata doc)
1761
            try {
1762
                DocumentImpl doc = new DocumentImpl(docid);
1763

    
1764
                //check the permission for read
1765
                if (!DocumentImpl.hasReadPermission(user, groups, docid)) {
1766
                    Exception e = new Exception("User " + user
1767
                            + " does not have "
1768
                            + "permission to read the document with the docid "
1769
                            + docid);
1770
                    throw e;
1771
                }
1772

    
1773
                if (doc.getRootNodeID() == 0) {
1774
                    // this is data file; add file to zip
1775
                    String filepath = MetaCatUtil.getOption("datafilepath");
1776
                    if (!filepath.endsWith("/")) {
1777
                        filepath += "/";
1778
                    }
1779
                    String filename = filepath + docid;
1780
                    FileInputStream fin = null;
1781
                    fin = new FileInputStream(filename);
1782
                    try {
1783

    
1784
                        zentry = new ZipEntry(docid);
1785
                        zout.putNextEntry(zentry);
1786
                        byte[] buf = new byte[4 * 1024]; // 4K buffer
1787
                        int b = fin.read(buf);
1788
                        while (b != -1) {
1789
                            zout.write(buf, 0, b);
1790
                            b = fin.read(buf);
1791
                        }
1792
                    } finally {
1793
                        if (fin != null) fin.close();
1794
                    }
1795
                    zout.closeEntry();
1796

    
1797
                } else {
1798
                    // this is metadata doc; add doc to zip
1799
                    bytestring = doc.toString().getBytes();
1800
                    zentry = new ZipEntry(docid + ".xml");
1801
                    zentry.setSize(bytestring.length);
1802
                    zout.putNextEntry(zentry);
1803
                    zout.write(bytestring, 0, bytestring.length);
1804
                    zout.closeEntry();
1805
                }
1806
                EventLog.getInstance().log(request.getRemoteAddr(), user,
1807
                        docid, "read");
1808
            } catch (Exception except) {
1809
                throw except;
1810
            }
1811
        }
1812
    }
1813

    
1814
    /**
1815
     * If metacat couldn't find a data file or document locally, it will read
1816
     * this docid from its home server. This is for the replication feature
1817
     */
1818
    private void readFromRemoteMetaCat(HttpServletResponse response,
1819
            String docid, String rev, String user, String password,
1820
            ServletOutputStream out, boolean zip, ZipOutputStream zout)
1821
            throws Exception
1822
    {
1823
        // Create a object of RemoteDocument, "" is for zipEntryPath
1824
        RemoteDocument remoteDoc = new RemoteDocument(docid, rev, user,
1825
                password, "");
1826
        String docType = remoteDoc.getDocType();
1827
        // Only read data file
1828
        if (docType.equals("BIN")) {
1829
            // If it is zip format
1830
            if (zip) {
1831
                remoteDoc.readDocumentFromRemoteServerByZip(zout);
1832
            } else {
1833
                if (out == null) {
1834
                    out = response.getOutputStream();
1835
                }
1836
                response.setContentType("application/octet-stream");
1837
                remoteDoc.readDocumentFromRemoteServer(out);
1838
            }
1839
        } else {
1840
            throw new Exception("Docid: " + docid + "." + rev
1841
                    + " couldn't find");
1842
        }
1843
    }
1844

    
1845
    /**
1846
     * Handle the database putdocument request and write an XML document to the
1847
     * database connection
1848
     */
1849
    private void handleInsertOrUpdateAction(HttpServletRequest request,
1850
            HttpServletResponse response, PrintWriter out, Hashtable params,
1851
            String user, String[] groups)
1852
    {
1853
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
1854
        DBConnection dbConn = null;
1855
        int serialNumber = -1;
1856

    
1857
        if(params.get("docid") == null){
1858
            out.println("<?xml version=\"1.0\"?>");
1859
            out.println("<error>");
1860
            out.println("Docid not specified");
1861
            out.println("</error>");
1862
            logMetacat.error("Docid not specified");
1863
            return;
1864
        }
1865
        
1866
        if(!MetaCatUtil.canInsertOrUpdate(user, groups)){
1867
        	out.println("<?xml version=\"1.0\"?>");
1868
            out.println("<error>");
1869
            out.println("User '" + user + "' not allowed to insert and update");
1870
            out.println("</error>");
1871
            logMetacat.error("User '" + user + "' not allowed to insert and update");
1872
            return;
1873
        }
1874

    
1875
        try {
1876
            // Get the document indicated
1877
            String[] doctext = (String[]) params.get("doctext");
1878
            String pub = null;
1879
            if (params.containsKey("public")) {
1880
                pub = ((String[]) params.get("public"))[0];
1881
            }
1882

    
1883
            StringReader dtd = null;
1884
            if (params.containsKey("dtdtext")) {
1885
                String[] dtdtext = (String[]) params.get("dtdtext");
1886
                try {
1887
                    if (!dtdtext[0].equals("")) {
1888
                        dtd = new StringReader(dtdtext[0]);
1889
                    }
1890
                } catch (NullPointerException npe) {
1891
                }
1892
            }
1893

    
1894
            if(doctext == null){
1895
                out.println("<?xml version=\"1.0\"?>");
1896
                out.println("<error>");
1897
                out.println("Document text not submitted");
1898
                out.println("</error>");
1899
                return;
1900
            }
1901

    
1902
            StringReader xml = new StringReader(doctext[0]);
1903
            boolean validate = false;
1904
            DocumentImplWrapper documentWrapper = null;
1905
            try {
1906
                // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ...
1907
                // >
1908
                // in order to decide whether to use validation parser
1909
                validate = needDTDValidation(xml);
1910
                if (validate) {
1911
                    // set a dtd base validation parser
1912
                    String rule = DocumentImpl.DTD;
1913
                    documentWrapper = new DocumentImplWrapper(rule, validate);
1914
                } else {
1915

    
1916
                    String namespace = findNamespace(xml);
1917
                    
1918
                	if (namespace != null) {
1919
                		if (namespace.compareTo(DocumentImpl.EML2_0_0NAMESPACE) == 0
1920
                				|| namespace.compareTo(
1921
                				DocumentImpl.EML2_0_1NAMESPACE) == 0) {
1922
                			// set eml2 base	 validation parser
1923
                			String rule = DocumentImpl.EML200;
1924
                			// using emlparser to check id validation
1925
                			EMLParser parser = new EMLParser(doctext[0]);
1926
                			documentWrapper = new DocumentImplWrapper(rule, true);
1927
                		} else if (namespace.compareTo(
1928
                                DocumentImpl.EML2_1_0NAMESPACE) == 0) {
1929
                			// set eml2 base validation parser
1930
                			String rule = DocumentImpl.EML210;
1931
                			// using emlparser to check id validation
1932
                			EMLParser parser = new EMLParser(doctext[0]);
1933
                			documentWrapper = new DocumentImplWrapper(rule, true);
1934
                		} else {
1935
                			// set schema base validation parser
1936
                			String rule = DocumentImpl.SCHEMA;
1937
                			documentWrapper = new DocumentImplWrapper(rule, true);
1938
                		}
1939
                	} else {
1940
                		documentWrapper = new DocumentImplWrapper("", false);
1941
                	}
1942
                }
1943

    
1944
                String[] action = (String[]) params.get("action");
1945
                String[] docid = (String[]) params.get("docid");
1946
                String newdocid = null;
1947

    
1948
                String doAction = null;
1949
                if (action[0].equals("insert")) {
1950
                    doAction = "INSERT";
1951
                } else if (action[0].equals("update")) {
1952
                    doAction = "UPDATE";
1953
                }
1954

    
1955
                try {
1956
                    // get a connection from the pool
1957
                    dbConn = DBConnectionPool
1958
                            .getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1959
                    serialNumber = dbConn.getCheckOutSerialNumber();
1960

    
1961
                    // write the document to the database
1962
                    try {
1963
                        String accNumber = docid[0];
1964
                        logMetacat.debug("" + doAction + " "
1965
                                + accNumber + "...");
1966
                        if (accNumber.equals("")) {
1967
                            accNumber = null;
1968
                        }
1969
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1970
                                doAction, accNumber, user, groups);
1971
                        EventLog.getInstance().log(request.getRemoteAddr(),
1972
                                user, accNumber, action[0]);
1973
                    } catch (NullPointerException npe) {
1974
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1975
                                doAction, null, user, groups);
1976
                        EventLog.getInstance().log(request.getRemoteAddr(),
1977
                                user, "", action[0]);
1978
                    }
1979
                }
1980
                finally {
1981
                    // Return db connection
1982
                    DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1983
                }
1984

    
1985
                // set content type and other response header fields first
1986
                //response.setContentType("text/xml");
1987
                out.println("<?xml version=\"1.0\"?>");
1988
                out.println("<success>");
1989
                out.println("<docid>" + newdocid + "</docid>");
1990
                out.println("</success>");
1991

    
1992
            } catch (NullPointerException npe) {
1993
                //response.setContentType("text/xml");
1994
                out.println("<?xml version=\"1.0\"?>");
1995
                out.println("<error>");
1996
                out.println(npe.getMessage());
1997
                out.println("</error>");
1998
                logMetacat.warn("Error in writing eml document to the database" + npe.getMessage());
1999
                npe.printStackTrace();
2000
            }
2001
        } catch (Exception e) {
2002
            //response.setContentType("text/xml");
2003
            out.println("<?xml version=\"1.0\"?>");
2004
            out.println("<error>");
2005
            out.println(e.getMessage());
2006
            out.println("</error>");
2007
            logMetacat.warn("Error in writing eml document to the database" + e.getMessage());
2008
            e.printStackTrace();
2009
        }
2010
    }
2011

    
2012
    /**
2013
     * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... > in
2014
     * order to decide whether to use validation parser
2015
     */
2016
    private static boolean needDTDValidation(StringReader xmlreader)
2017
            throws IOException
2018
    {
2019
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2020
        StringBuffer cbuff = new StringBuffer();
2021
        java.util.Stack st = new java.util.Stack();
2022
        boolean validate = false;
2023
        int c;
2024
        int inx;
2025

    
2026
        // read from the stream until find the keywords
2027
        while ((st.empty() || st.size() < 4) && ((c = xmlreader.read()) != -1)) {
2028
            cbuff.append((char) c);
2029

    
2030
            // "<!DOCTYPE" keyword is found; put it in the stack
2031
            if ((inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1) {
2032
                cbuff = new StringBuffer();
2033
                st.push("<!DOCTYPE");
2034
            }
2035
            // "PUBLIC" keyword is found; put it in the stack
2036
            if ((inx = cbuff.toString().indexOf("PUBLIC")) != -1) {
2037
                cbuff = new StringBuffer();
2038
                st.push("PUBLIC");
2039
            }
2040
            // "SYSTEM" keyword is found; put it in the stack
2041
            if ((inx = cbuff.toString().indexOf("SYSTEM")) != -1) {
2042
                cbuff = new StringBuffer();
2043
                st.push("SYSTEM");
2044
            }
2045
            // ">" character is found; put it in the stack
2046
            // ">" is found twice: fisrt from <?xml ...?>
2047
            // and second from <!DOCTYPE ... >
2048
            if ((inx = cbuff.toString().indexOf(">")) != -1) {
2049
                cbuff = new StringBuffer();
2050
                st.push(">");
2051
            }
2052
        }
2053

    
2054
        // close the stream
2055
        xmlreader.reset();
2056

    
2057
        // check the stack whether it contains the keywords:
2058
        // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
2059
        if (st.size() == 4) {
2060
            if (((String) st.pop()).equals(">")
2061
                    && (((String) st.peek()).equals("PUBLIC") | ((String) st
2062
                            .pop()).equals("SYSTEM"))
2063
                    && ((String) st.pop()).equals("<!DOCTYPE")) {
2064
                validate = true;
2065
            }
2066
        }
2067

    
2068
        logMetacat.info("Validation for dtd is " + validate);
2069
        return validate;
2070
    }
2071

    
2072
    // END OF INSERT/UPDATE SECTION
2073

    
2074
    /* check if the xml string contains key words to specify schema loocation */
2075
    private String findNamespace(StringReader xml) throws IOException
2076
    {
2077
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2078
        String namespace = null;
2079

    
2080
        String eml2_0_0NameSpace = DocumentImpl.EML2_0_0NAMESPACE;
2081
        String eml2_0_1NameSpace = DocumentImpl.EML2_0_1NAMESPACE;
2082
        String eml2_1_0NameSpace = DocumentImpl.EML2_1_0NAMESPACE;
2083

    
2084
        if (xml == null) {
2085
            logMetacat.debug("Validation for schema is "
2086
                    + namespace);
2087
            return namespace;
2088
        }
2089
        String targetLine = getSchemaLine(xml);
2090
		
2091
        if (targetLine != null) {
2092

    
2093
        	// find if the root element has prefix
2094
        	String prefix = getPrefix(targetLine);
2095
        	logMetacat.info("prefix is:" + prefix);
2096
        	int startIndex = 0;
2097
        	
2098
        	
2099
        	if(prefix != null)
2100
        	{
2101
        		// if prefix found then look for xmlns:prefix
2102
        		// element to find the ns 
2103
        		String namespaceWithPrefix = NAMESPACEKEYWORD 
2104
        					+ ":" + prefix;
2105
        		startIndex = targetLine.indexOf(namespaceWithPrefix);
2106
            	logMetacat.debug("namespaceWithPrefix is:" + namespaceWithPrefix+":");
2107
            	logMetacat.debug("startIndex is:" + startIndex);
2108
        		
2109
        	} else {
2110
        		// if prefix not found then look for xmlns
2111
        		// attribute to find the ns 
2112
        		startIndex = targetLine.indexOf(NAMESPACEKEYWORD);
2113
            	logMetacat.debug("startIndex is:" + startIndex);
2114
        	}
2115
        		
2116
            int start = 1;
2117
            int end = 1;
2118
            String namespaceString = null;
2119
            int count = 0;
2120
            if (startIndex != -1) {
2121
                for (int i = startIndex; i < targetLine.length(); i++) {
2122
                    if (targetLine.charAt(i) == '"') {
2123
                        count++;
2124
                    }
2125
                    if (targetLine.charAt(i) == '"' && count == 1) {
2126
                        start = i;
2127
                    }
2128
                    if (targetLine.charAt(i) == '"' && count == 2) {
2129
                        end = i;
2130
                        break;
2131
                    }
2132
                }
2133
            } 
2134
            // else: xmlns not found. namespace = null will be returned
2135

    
2136
         	logMetacat.debug("targetLine is " + targetLine);
2137
         	logMetacat.debug("start is " + end);
2138
         	logMetacat.debug("end is " + end);
2139
           
2140
            if(start < end){
2141
            	namespaceString = targetLine.substring(start + 1, end);
2142
            	logMetacat.debug("namespaceString is " + namespaceString);
2143
            }
2144
            logMetacat.debug("namespace in xml is: "
2145
                    + namespaceString);
2146
            if(namespaceString != null){
2147
            	if (namespaceString.indexOf(eml2_0_0NameSpace) != -1) {
2148
            		namespace = eml2_0_0NameSpace;
2149
            	} else if (namespaceString.indexOf(eml2_0_1NameSpace) != -1) {
2150
            		namespace = eml2_0_1NameSpace;
2151
            	} else if (namespaceString.indexOf(eml2_1_0NameSpace) != -1) {
2152
            		namespace = eml2_1_0NameSpace;
2153
            	} else {
2154
            		namespace = namespaceString;
2155
            	}
2156
            }
2157
        }
2158

    
2159
        logMetacat.debug("Validation for eml is " + namespace);
2160

    
2161
        return namespace;
2162

    
2163
    }
2164

    
2165
    private String getSchemaLine(StringReader xml) throws IOException
2166
    {
2167
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2168
        // find the line
2169
        String secondLine = null;
2170
        int count = 0;
2171
        int endIndex = 0;
2172
        int startIndex = 0;
2173
        final int TARGETNUM = 1;
2174
        StringBuffer buffer = new StringBuffer();
2175
        boolean comment = false;
2176
        boolean processingInstruction = false;
2177
        char thirdPreviousCharacter = '?';
2178
        char secondPreviousCharacter = '?';
2179
        char previousCharacter = '?';
2180
        char currentCharacter = '?';
2181
        int tmp = xml.read();
2182
        while (tmp != -1) {
2183
            currentCharacter = (char)tmp;
2184
            //in a comment
2185
            if (currentCharacter == '-' && previousCharacter == '-'
2186
                    && secondPreviousCharacter == '!'
2187
                    && thirdPreviousCharacter == '<') {
2188
                comment = true;
2189
            }
2190
            //out of comment
2191
            if (comment && currentCharacter == '>' && previousCharacter == '-'
2192
                    && secondPreviousCharacter == '-') {
2193
                comment = false;
2194
            }
2195

    
2196
            //in a processingInstruction
2197
            if (currentCharacter == '?' && previousCharacter == '<') {
2198
            	processingInstruction = true;
2199
            }
2200
            
2201
            //out of processingInstruction
2202
            if (processingInstruction && currentCharacter == '>' 
2203
            	&& previousCharacter == '?') {
2204
            	processingInstruction = false;
2205
            }
2206
            
2207
            //this is not comment or a processingInstruction
2208
            if (currentCharacter != '!' && previousCharacter == '<' 
2209
            	&& !comment && !processingInstruction) {
2210
                count++;
2211
            }
2212
            
2213
            // get target line
2214
            if (count == TARGETNUM && currentCharacter != '>') {
2215
                buffer.append(currentCharacter);
2216
            }
2217
            if (count == TARGETNUM && currentCharacter == '>') {
2218
                break;
2219
            }
2220
            thirdPreviousCharacter = secondPreviousCharacter;
2221
            secondPreviousCharacter = previousCharacter;
2222
            previousCharacter = currentCharacter;
2223
            tmp = xml.read();
2224
        }
2225
        secondLine = buffer.toString();
2226
        logMetacat.debug("the second line string is: " + secondLine);
2227
        
2228
        xml.reset();
2229
        return secondLine;
2230
    }
2231

    
2232
    private String getPrefix(String schemaLine)
2233
    {
2234
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2235
        String prefix = null;
2236
        
2237
        if(schemaLine.indexOf(" ") > 0){
2238
            String rootElement = "";
2239
            try {
2240
                rootElement = schemaLine.substring(0, schemaLine.indexOf(" "));
2241
            } catch (StringIndexOutOfBoundsException sioobe) {
2242
                rootElement = schemaLine;
2243
            }
2244

    
2245
            logMetacat.debug("rootElement:" + rootElement);
2246
        
2247
            if(rootElement.indexOf(":") > 0){
2248
                prefix = rootElement.substring(rootElement.indexOf(":") + 1,
2249
                    rootElement.length());
2250
            }
2251
            
2252
            if(prefix != null){
2253
                return prefix.trim();
2254
            }
2255
        }
2256
        return null;
2257
    }
2258

    
2259
    /**
2260
     * Handle the database delete request and delete an XML document from the
2261
     * database connection
2262
     */
2263
    private void handleDeleteAction(PrintWriter out, Hashtable params,
2264
            HttpServletRequest request, HttpServletResponse response,
2265
            String user, String[] groups)
2266
    {
2267
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2268
        String[] docid = (String[]) params.get("docid");
2269

    
2270
        if(docid == null){
2271
          response.setContentType("text/xml");
2272
          out.println("<?xml version=\"1.0\"?>");
2273
          out.println("<error>");
2274
          out.println("Docid not specified.");
2275
          out.println("</error>");
2276
          logMetacat.error("Docid not specified for the document to be deleted.");
2277
        } else {
2278

    
2279
            // delete the document from the database
2280
            try {
2281

    
2282
                try {
2283
                    // null means notify server is null
2284
                    DocumentImpl.delete(docid[0], user, groups, null);
2285
                    EventLog.getInstance().log(request.getRemoteAddr(),
2286
                                               user, docid[0], "delete");
2287
                    response.setContentType("text/xml");
2288
                    out.println("<?xml version=\"1.0\"?>");
2289
                    out.println("<success>");
2290
                    out.println("Document deleted.");
2291
                    out.println("</success>");
2292
                    logMetacat.info("Document deleted.");
2293
                }
2294
                catch (AccessionNumberException ane) {
2295
                    response.setContentType("text/xml");
2296
                    out.println("<?xml version=\"1.0\"?>");
2297
                    out.println("<error>");
2298
                    //out.println("Error deleting document!!!");
2299
                    out.println(ane.getMessage());
2300
                    out.println("</error>");
2301
                    logMetacat.error("Document could not be deleted: " 
2302
                    		+ ane.getMessage());
2303
                }
2304
            }
2305
            catch (Exception e) {
2306
                response.setContentType("text/xml");
2307
                out.println("<?xml version=\"1.0\"?>");
2308
                out.println("<error>");
2309
                out.println(e.getMessage());
2310
                out.println("</error>");
2311
                logMetacat.error("Document could not be deleted: " 
2312
                		+ e.getMessage());
2313
            }
2314
        }
2315
    }
2316

    
2317
    /**
2318
     * Handle the validation request and return the results to the requestor
2319
     */
2320
    private void handleValidateAction(PrintWriter out, Hashtable params)
2321
    {
2322

    
2323
        // Get the document indicated
2324
        String valtext = null;
2325
        DBConnection dbConn = null;
2326
        int serialNumber = -1;
2327

    
2328
        try {
2329
            valtext = ((String[]) params.get("valtext"))[0];
2330
        } catch (Exception nullpe) {
2331

    
2332
            String docid = null;
2333
            try {
2334
                // Find the document id number
2335
                docid = ((String[]) params.get("docid"))[0];
2336

    
2337
                // Get the document indicated from the db
2338
                DocumentImpl xmldoc = new DocumentImpl(docid);
2339
                valtext = xmldoc.toString();
2340

    
2341
            } catch (NullPointerException npe) {
2342

    
2343
                out.println("<error>Error getting document ID: " + docid
2344
                        + "</error>");
2345
                //if ( conn != null ) { util.returnConnection(conn); }
2346
                return;
2347
            } catch (Exception e) {
2348

    
2349
                out.println(e.getMessage());
2350
            }
2351
        }
2352

    
2353
        try {
2354
            // get a connection from the pool
2355
            dbConn = DBConnectionPool
2356
                    .getDBConnection("MetaCatServlet.handleValidateAction");
2357
            serialNumber = dbConn.getCheckOutSerialNumber();
2358
            DBValidate valobj = new DBValidate(dbConn);
2359
            boolean valid = valobj.validateString(valtext);
2360

    
2361
            // set content type and other response header fields first
2362

    
2363
            out.println(valobj.returnErrors());
2364

    
2365
        } catch (NullPointerException npe2) {
2366
            // set content type and other response header fields first
2367

    
2368
            out.println("<error>Error validating document.</error>");
2369
        } catch (Exception e) {
2370

    
2371
            out.println(e.getMessage());
2372
        } finally {
2373
            // Return db connection
2374
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2375
        }
2376
    }
2377

    
2378
    /**
2379
     * Handle "getrevsionanddoctype" action Given a docid, return it's current
2380
     * revision and doctype from data base The output is String look like
2381
     * "rev;doctype"
2382
     */
2383
    private void handleGetRevisionAndDocTypeAction(PrintWriter out,
2384
            Hashtable params)
2385
    {
2386
        // To store doc parameter
2387
        String[] docs = new String[10];
2388
        // Store a single doc id
2389
        String givenDocId = null;
2390
        // Get docid from parameters
2391
        if (params.containsKey("docid")) {
2392
            docs = (String[]) params.get("docid");
2393
        }
2394
        // Get first docid form string array
2395
        givenDocId = docs[0];
2396

    
2397
        try {
2398
            // Make sure there is a docid
2399
            if (givenDocId == null || givenDocId.equals("")) { throw new Exception(
2400
                    "User didn't specify docid!"); }//if
2401

    
2402
            // Create a DBUtil object
2403
            DBUtil dbutil = new DBUtil();
2404
            // Get a rev and doctype
2405
            String revAndDocType = dbutil
2406
                    .getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
2407
            out.println(revAndDocType);
2408

    
2409
        } catch (Exception e) {
2410
            // Handle exception
2411
            out.println("<?xml version=\"1.0\"?>");
2412
            out.println("<error>");
2413
            out.println(e.getMessage());
2414
            out.println("</error>");
2415
        }
2416

    
2417
    }
2418

    
2419
    /**
2420
     * Handle "getaccesscontrol" action. Read Access Control List from db
2421
     * connection in XML format
2422
     */
2423
    private void handleGetAccessControlAction(PrintWriter out,
2424
            Hashtable params, HttpServletResponse response, String username,
2425
            String[] groupnames)
2426
    {
2427
        DBConnection dbConn = null;
2428
        int serialNumber = -1;
2429
        String docid = ((String[]) params.get("docid"))[0];
2430

    
2431
        try {
2432

    
2433
            // get connection from the pool
2434
            dbConn = DBConnectionPool
2435
                    .getDBConnection("MetaCatServlet.handleGetAccessControlAction");
2436
            serialNumber = dbConn.getCheckOutSerialNumber();
2437
            AccessControlList aclobj = new AccessControlList(dbConn);
2438
            String acltext = aclobj.getACL(docid, username, groupnames);
2439
            out.println(acltext);
2440

    
2441
        } catch (Exception e) {
2442
            out.println("<?xml version=\"1.0\"?>");
2443
            out.println("<error>");
2444
            out.println(e.getMessage());
2445
            out.println("</error>");
2446
        } finally {
2447
            // Retrun db connection to pool
2448
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
2449
        }
2450
    }
2451

    
2452
    /**
2453
     * Handle the "getprincipals" action. Read all principals from
2454
     * authentication scheme in XML format
2455
     */
2456
    private void handleGetPrincipalsAction(PrintWriter out, String user,
2457
            String password)
2458
    {
2459
        try {
2460
            AuthSession auth = new AuthSession();
2461
            String principals = auth.getPrincipals(user, password);
2462
            out.println(principals);
2463

    
2464
        } catch (Exception e) {
2465
            out.println("<?xml version=\"1.0\"?>");
2466
            out.println("<error>");
2467
            out.println(e.getMessage());
2468
            out.println("</error>");
2469
        }
2470
    }
2471

    
2472
    /**
2473
     * Handle "getdoctypes" action. Read all doctypes from db connection in XML
2474
     * format
2475
     */
2476
    private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
2477
            HttpServletResponse response)
2478
    {
2479
        try {
2480
            DBUtil dbutil = new DBUtil();
2481
            String doctypes = dbutil.readDoctypes();
2482
            out.println(doctypes);
2483
        } catch (Exception e) {
2484
            out.println("<?xml version=\"1.0\"?>");
2485
            out.println("<error>");
2486
            out.println(e.getMessage());
2487
            out.println("</error>");
2488
        }
2489
    }
2490

    
2491
    /**
2492
     * Handle the "getdtdschema" action. Read DTD or Schema file for a given
2493
     * doctype from Metacat catalog system
2494
     */
2495
    private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
2496
            HttpServletResponse response)
2497
    {
2498

    
2499
        String doctype = null;
2500
        String[] doctypeArr = (String[]) params.get("doctype");
2501

    
2502
        // get only the first doctype specified in the list of doctypes
2503
        // it could be done for all doctypes in that list
2504
        if (doctypeArr != null) {
2505
            doctype = ((String[]) params.get("doctype"))[0];
2506
        }
2507

    
2508
        try {
2509
            DBUtil dbutil = new DBUtil();
2510
            String dtdschema = dbutil.readDTDSchema(doctype);
2511
            out.println(dtdschema);
2512

    
2513
        } catch (Exception e) {
2514
            out.println("<?xml version=\"1.0\"?>");
2515
            out.println("<error>");
2516
            out.println(e.getMessage());
2517
            out.println("</error>");
2518
        }
2519

    
2520
    }
2521

    
2522
    /**
2523
     * Handle the "getlastdocid" action. Get the latest docid with rev number
2524
     * from db connection in XML format
2525
     */
2526
    private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
2527
            HttpServletResponse response)
2528
    {
2529

    
2530
        String scope = ((String[]) params.get("scope"))[0];
2531
        if (scope == null) {
2532
            scope = ((String[]) params.get("username"))[0];
2533
        }
2534

    
2535
        try {
2536

    
2537
            DBUtil dbutil = new DBUtil();
2538
            String lastDocid = dbutil.getMaxDocid(scope);
2539
            out.println("<?xml version=\"1.0\"?>");
2540
            out.println("<lastDocid>");
2541
            out.println("  <scope>" + scope + "</scope>");
2542
            out.println("  <docid>" + lastDocid + "</docid>");
2543
            out.println("</lastDocid>");
2544

    
2545
        } catch (Exception e) {
2546
            out.println("<?xml version=\"1.0\"?>");
2547
            out.println("<error>");
2548
            out.println(e.getMessage());
2549
            out.println("</error>");
2550
        }
2551
    }
2552

    
2553
    /**
2554
     * Print a report from the event log based on filter parameters passed in
2555
     * from the web.
2556
     *
2557
     * @param params the parameters from the web request
2558
     * @param request the http request object for getting request details
2559
     * @param response the http response object for writing output
2560
     */
2561
    private void handleGetLogAction(Hashtable params, HttpServletRequest request,
2562
            HttpServletResponse response, String username, String[] groups)
2563
    {
2564
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2565
        try {
2566
            response.setContentType("text/xml");
2567
            PrintWriter out = response.getWriter();
2568

    
2569
            // Check that the user is authenticated as an administrator account
2570
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2571
                out.print("<error>");
2572
                out.print("The user \"" + username +
2573
                        "\" is not authorized for this action.");
2574
                out.print("</error>");
2575
                return;
2576
            }
2577

    
2578
            // Get all of the parameters in the correct formats
2579
            String[] ipAddress = (String[])params.get("ipaddress");
2580
            String[] principal = (String[])params.get("principal");
2581
            String[] docid = (String[])params.get("docid");
2582
            String[] event = (String[])params.get("event");
2583
            String[] startArray = (String[]) params.get("start");
2584
            String[] endArray = (String[]) params.get("end");
2585
            String start = null;
2586
            String end = null;
2587
            if (startArray != null) {
2588
                start = startArray[0];
2589
            }
2590
            if (endArray != null) {
2591
                end = endArray[0];
2592
            }
2593
            Timestamp startDate = null;
2594
            Timestamp endDate = null;
2595
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
2596
            try {
2597
                if (start != null) {
2598
                    startDate = new Timestamp((format.parse(start)).getTime());
2599
                }
2600
                if (end != null) {
2601
                    endDate = new Timestamp((format.parse(end)).getTime());
2602
                }
2603
            } catch (ParseException e) {
2604
                System.out.println("Failed to created Timestamp from input.");
2605
            }
2606

    
2607
            // Request the report by passing the filter parameters
2608
            out.println(EventLog.getInstance().getReport(ipAddress, principal,
2609
                    docid, event, startDate, endDate));
2610
            out.close();
2611
        } catch (IOException e) {
2612
            logMetacat.error(
2613
                    "Could not open http response for writing: " + e.getMessage());
2614
        }
2615
    }
2616

    
2617
    /**
2618
     * Rebuild the index for one or more documents. If the docid parameter is
2619
     * provided, rebuild for just that one document or list of documents. If
2620
     * not, then rebuild the index for all documents in the xml_documents
2621
     * table.
2622
     *
2623
     * @param params the parameters from the web request
2624
     * @param request the http request object for getting request details
2625
     * @param response the http response object for writing output
2626
     * @param username the username of the authenticated user
2627
     */
2628
    private void handleBuildIndexAction(Hashtable params,
2629
            HttpServletRequest request, HttpServletResponse response,
2630
            String username, String[] groups)
2631
    {
2632
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2633
        
2634
        // Get all of the parameters in the correct formats
2635
        String[] docid = (String[])params.get("docid");
2636

    
2637
        // Rebuild the indices for appropriate documents
2638
        try {
2639
            response.setContentType("text/xml");
2640
            PrintWriter out = response.getWriter();
2641

    
2642
            // Check that the user is authenticated as an administrator account
2643
            if (!MetaCatUtil.isAdministrator(username, groups)) {
2644
                out.print("<error>");
2645
                out.print("The user \"" + username +
2646
                        "\" is not authorized for this action.");
2647
                out.print("</error>");
2648
                return;
2649
            }
2650

    
2651
            // Process the documents
2652
            out.println("<success>");
2653
            if (docid == null || docid.length == 0) {
2654
                // Process all of the documents
2655
                try {
2656
                    Vector documents = getDocumentList();
2657
                    Iterator it = documents.iterator();
2658
                    while (it.hasNext()) {
2659
                        String id = (String) it.next();
2660
                        buildDocumentIndex(id, out);
2661
                    }
2662
                } catch (SQLException se) {
2663
                    out.print("<error>");
2664
                    out.print(se.getMessage());
2665
                    out.println("</error>");
2666
                }
2667
            } else {
2668
                // Only process the requested documents
2669
                for (int i = 0; i < docid.length; i++) {
2670
                    buildDocumentIndex(docid[i], out);
2671
                }
2672
            }
2673
            out.println("</success>");
2674
            out.close();
2675
        } catch (IOException e) {
2676
            logMetacat.error(
2677
                    "Could not open http response for writing: "
2678
                    + e.getMessage());
2679
        }
2680
    }
2681

    
2682
    /**
2683
     * Build the index for one document by reading the document and
2684
     * calling its buildIndex() method.
2685
     *
2686
     * @param docid the document (with revision) to rebuild
2687
     * @param out the PrintWriter to which output is printed
2688
     */
2689
    private void buildDocumentIndex(String docid, PrintWriter out)
2690
    {
2691
        try {
2692
            DocumentImpl doc = new DocumentImpl(docid, false);
2693
            doc.buildIndex();
2694
            out.print("<docid>" + docid);
2695
            out.println("</docid>");
2696
        } catch (McdbException me) {
2697
            out.print("<error>");
2698
            out.print(me.getMessage());
2699
            out.println("</error>");
2700
        }
2701
    }
2702

    
2703
    /**
2704
     * Handle documents passed to metacat that are encoded using the
2705
     * "multipart/form-data" mime type. This is typically used for uploading
2706
     * data files which may be binary and large.
2707
     */
2708
    private void handleMultipartForm(HttpServletRequest request,
2709
            HttpServletResponse response)
2710
    {
2711
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2712
        PrintWriter out = null;
2713
        String action = null;
2714

    
2715
        // Parse the multipart form, and save the parameters in a Hashtable and
2716
        // save the FileParts in a hashtable
2717

    
2718
        Hashtable params = new Hashtable();
2719
        Hashtable fileList = new Hashtable();
2720
        int sizeLimit = (new Integer(MetaCatUtil.getOption("datafilesizelimit")))
2721
                .intValue();
2722
        logMetacat.info(
2723
                "The size limit of uploaded data files is: " + sizeLimit);
2724

    
2725
        try {
2726
            MultipartParser mp = new MultipartParser(request,
2727
                    sizeLimit * 1024 * 1024);
2728
            Part part;
2729
            while ((part = mp.readNextPart()) != null) {
2730
                String name = part.getName();
2731

    
2732
                if (part.isParam()) {
2733
                    // it's a parameter part
2734
                    ParamPart paramPart = (ParamPart) part;
2735
                    String value = paramPart.getStringValue();
2736
                    params.put(name, value);
2737
                    if (name.equals("action")) {
2738
                        action = value;
2739
                    }
2740
                } else if (part.isFile()) {
2741
                    // it's a file part
2742
                    FilePart filePart = (FilePart) part;
2743
                    fileList.put(name, filePart);
2744

    
2745
                    // Stop once the first file part is found, otherwise going
2746
                    // onto the
2747
                    // next part prevents access to the file contents. So...for
2748
                    // upload
2749
                    // to work, the datafile must be the last part
2750
                    break;
2751
                }
2752
            }
2753
        } catch (IOException ioe) {
2754
            try {
2755
                out = response.getWriter();
2756
            } catch (IOException ioe2) {
2757
                logMetacat.fatal("Fatal Error: couldn't get response output stream.");
2758
            }
2759
            out.println("<?xml version=\"1.0\"?>");
2760
            out.println("<error>");
2761
            out.println("Error: problem reading multipart data.");
2762
            out.println("</error>");
2763
        }
2764

    
2765
        // Get the session information
2766
        String username = null;
2767
        String password = null;
2768
        String[] groupnames = null;
2769
        String sess_id = null;
2770

    
2771
        // be aware of session expiration on every request
2772
        HttpSession sess = request.getSession(true);
2773
        if (sess.isNew()) {
2774
            // session expired or has not been stored b/w user requests
2775
            username = "public";
2776
            sess.setAttribute("username", username);
2777
        } else {
2778
            username = (String) sess.getAttribute("username");
2779
            password = (String) sess.getAttribute("password");
2780
            groupnames = (String[]) sess.getAttribute("groupnames");
2781
            try {
2782
                sess_id = (String) sess.getId();
2783
            } catch (IllegalStateException ise) {
2784
                System.out
2785
                        .println("error in  handleMultipartForm: this shouldn't "
2786
                                + "happen: the session should be valid: "
2787
                                + ise.getMessage());
2788
            }
2789
        }
2790

    
2791
        // Get the out stream
2792
        try {
2793
            out = response.getWriter();
2794
        } catch (IOException ioe2) {
2795
            logMetacat.error("Fatal Error: couldn't get response "
2796
                    + "output stream.");
2797
        }
2798

    
2799
        if (action.equals("upload")) {
2800
            if (username != null && !username.equals("public")) {
2801
                handleUploadAction(request, out, params, fileList, username,
2802
                        groupnames);
2803
            } else {
2804

    
2805
                out.println("<?xml version=\"1.0\"?>");
2806
                out.println("<error>");
2807
                out.println("Permission denied for " + action);
2808
                out.println("</error>");
2809
            }
2810
        } else {
2811
            /*
2812
             * try { out = response.getWriter(); } catch (IOException ioe2) {
2813
             * System.err.println("Fatal Error: couldn't get response output
2814
             * stream.");
2815
             */
2816
            out.println("<?xml version=\"1.0\"?>");
2817
            out.println("<error>");
2818
            out.println(
2819
                    "Error: action not registered.  Please report this error.");
2820
            out.println("</error>");
2821
        }
2822
        out.close();
2823
    }
2824

    
2825
    /**
2826
     * Handle the upload action by saving the attached file to disk and
2827
     * registering it in the Metacat db
2828
     */
2829
    private void handleUploadAction(HttpServletRequest request,
2830
            PrintWriter out, Hashtable params, Hashtable fileList,
2831
            String username, String[] groupnames)
2832
    {
2833
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2834
        //PrintWriter out = null;
2835
        //Connection conn = null;
2836
        String action = null;
2837
        String docid = null;
2838

    
2839
        /*
2840
         * response.setContentType("text/xml"); try { out =
2841
         * response.getWriter(); } catch (IOException ioe2) {
2842
         * System.err.println("Fatal Error: couldn't get response output
2843
         * stream.");
2844
         */
2845

    
2846
        if (params.containsKey("docid")) {
2847
            docid = (String) params.get("docid");
2848
        }
2849

    
2850
        // Make sure we have a docid and datafile
2851
        if (docid != null && fileList.containsKey("datafile")) {
2852
            logMetacat.info("Uploading data docid: " + docid);
2853
            // Get a reference to the file part of the form
2854
            FilePart filePart = (FilePart) fileList.get("datafile");
2855
            String fileName = filePart.getFileName();
2856
            logMetacat.info("Uploading filename: " + fileName);
2857
            // Check if the right file existed in the uploaded data
2858
            if (fileName != null) {
2859

    
2860
                try {
2861
                    //logMetacat.info("Upload datafile " + docid
2862
                    // +"...", 10);
2863
                    //If document get lock data file grant
2864
                    if (DocumentImpl.getDataFileLockGrant(docid)) {
2865
                        // Save the data file to disk using "docid" as the name
2866
                        String datafilepath = MetaCatUtil.getOption("datafilepath");
2867
                        File dataDirectory = new File(datafilepath);
2868
                        dataDirectory.mkdirs();
2869
                        File newFile = null;
2870
                        long size = 0;
2871
                        try
2872
                        {
2873
                          newFile = new File(dataDirectory, docid);
2874
                          size = filePart.writeTo(newFile);
2875
                        
2876
//                        register the file in the database (which generates
2877
                          // an exception
2878
                          //if the docid is not acceptable or other untoward
2879
                          // things happen
2880
                          DocumentImpl.registerDocument(fileName, "BIN", docid,
2881
                                username, groupnames);
2882
                        }
2883
                        catch (Exception ee)
2884
                        {
2885
                           //detelte the file to create
2886
                            newFile.delete();
2887
                            throw ee;
2888
                        }
2889

    
2890
                        EventLog.getInstance().log(request.getRemoteAddr(),
2891
                                username, docid, "upload");
2892
                        // Force replication this data file
2893
                        // To data file, "insert" and update is same
2894
                        // The fourth parameter is null. Because it is
2895
                        // notification server
2896
                        // and this method is in MetaCatServerlet. It is
2897
                        // original command,
2898
                        // not get force replication info from another metacat
2899
                        ForceReplicationHandler frh = new ForceReplicationHandler(
2900
                                docid, "insert", false, null);
2901

    
2902
                        // set content type and other response header fields
2903
                        // first
2904
                        out.println("<?xml version=\"1.0\"?>");
2905
                        out.println("<success>");
2906
                        out.println("<docid>" + docid + "</docid>");
2907
                        out.println("<size>" + size + "</size>");
2908
                        out.println("</success>");
2909
                    }
2910

    
2911
                } catch (Exception e) {
2912
                    
2913
                    out.println("<?xml version=\"1.0\"?>");
2914
                    out.println("<error>");
2915
                    out.println(e.getMessage());
2916
                    out.println("</error>");
2917
                }
2918
            } else {
2919
                // the field did not contain a file
2920
                out.println("<?xml version=\"1.0\"?>");
2921
                out.println("<error>");
2922
                out.println("The uploaded data did not contain a valid file.");
2923
                out.println("</error>");
2924
            }
2925
        } else {
2926
            // Error bcse docid missing or file missing
2927
            out.println("<?xml version=\"1.0\"?>");
2928
            out.println("<error>");
2929
            out.println("The uploaded data did not contain a valid docid "
2930
                    + "or valid file.");
2931
            out.println("</error>");
2932
        }
2933
    }
2934

    
2935
    /*
2936
     * A method to handle set access action
2937
     */
2938
    private void handleSetAccessAction(PrintWriter out, Hashtable params,
2939
            String username)
2940
    {
2941
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
2942
        String[] docList = null;
2943
        String[] principalList = null;
2944
        String[] permissionList = null;
2945
        String[] permTypeList = null;
2946
        String[] permOrderList = null;
2947
        String permission = null;
2948
        String permType = null;
2949
        String permOrder = null;
2950
        Vector errorList = new Vector();
2951
        String error = null;
2952
        Vector successList = new Vector();
2953
        String success = null;
2954

    
2955
        // Get parameters
2956
        if (params.containsKey("docid")) {
2957
            docList = (String[]) params.get("docid");
2958
        }
2959
        if (params.containsKey("principal")) {
2960
            principalList = (String[]) params.get("principal");
2961
        }
2962
        if (params.containsKey("permission")) {
2963
            permissionList = (String[]) params.get("permission");
2964

    
2965
        }
2966
        if (params.containsKey("permType")) {
2967
            permTypeList = (String[]) params.get("permType");
2968

    
2969
        }
2970
        if (params.containsKey("permOrder")) {
2971
            permOrderList = (String[]) params.get("permOrder");
2972

    
2973
        }
2974

    
2975
        // Make sure the parameter is not null
2976
        if (docList == null || principalList == null || permTypeList == null
2977
                || permissionList == null) {
2978
            error = "Please check your parameter list, it should look like: "
2979
                    + "?action=setaccess&docid=pipeline.1.1&principal=public"
2980
                    + "&permission=read&permType=allow&permOrder=allowFirst";
2981
            errorList.addElement(error);
2982
            outputResponse(successList, errorList, out);
2983
            return;
2984
        }
2985

    
2986
        // Only select first element for permission, type and order
2987
        permission = permissionList[0];
2988
        permType = permTypeList[0];
2989
        if (permOrderList != null) {
2990
            permOrder = permOrderList[0];
2991
        }
2992

    
2993
        // Get package doctype set
2994
        Vector packageSet = MetaCatUtil.getOptionList(MetaCatUtil
2995
                .getOption("packagedoctypeset"));
2996
        //debug
2997
        if (packageSet != null) {
2998
            for (int i = 0; i < packageSet.size(); i++) {
2999
                logMetacat.debug("doctype in package set: "
3000
                        + (String) packageSet.elementAt(i));
3001
            }
3002
        }
3003

    
3004
        // handle every accessionNumber
3005
        for (int i = 0; i < docList.length; i++) {
3006
            String accessionNumber = docList[i];
3007
            String owner = null;
3008
            String publicId = null;
3009
            // Get document owner and public id
3010
            try {
3011
                owner = getFieldValueForDoc(accessionNumber, "user_owner");
3012
                publicId = getFieldValueForDoc(accessionNumber, "doctype");
3013
            } catch (Exception e) {
3014
                logMetacat.error("Error in handleSetAccessAction: "
3015
                        + e.getMessage());
3016
                error = "Error in set access control for document - "
3017
                        + accessionNumber + e.getMessage();
3018
                errorList.addElement(error);
3019
                continue;
3020
            }
3021
            //check if user is the owner. Only owner can do owner
3022
            if (username == null || owner == null || !username.equals(owner)) {
3023
                error = "User - " + username
3024
                        + " does not have permission to set "
3025
                        + "access control for docid - " + accessionNumber;
3026
                errorList.addElement(error);
3027
                continue;
3028
            }
3029

    
3030
            // If docid publicid is BIN data file or other beta4, 6 package
3031
            // document
3032
            // we could not do set access control. Because we don't want
3033
            // inconsistent
3034
            // to its access docuemnt
3035
            if (publicId != null && packageSet != null
3036
                    && packageSet.contains(publicId)) {
3037
                error = "Could not set access control to document "
3038
                        + accessionNumber
3039
                        + "because it is in a pakcage and it has a access file for it";
3040
                errorList.addElement(error);
3041
                continue;
3042
            }
3043

    
3044
            // for every principle
3045
            for (int j = 0; j < principalList.length; j++) {
3046
                String principal = principalList[j];
3047
                try {
3048
                    //insert permission
3049
                    AccessControlForSingleFile accessControl = new AccessControlForSingleFile(
3050
                            accessionNumber, principal, permission, permType,
3051
                            permOrder);
3052
                    accessControl.insertPermissions();
3053
                    success = "Set access control to document "
3054
                            + accessionNumber + " successfully";
3055
                    successList.addElement(success);
3056
                } catch (Exception ee) {
3057
                    logMetacat.error(
3058
                            "Erorr in handleSetAccessAction2: "
3059
                                    + ee.getMessage());
3060
                    error = "Faild to set access control for document "
3061
                            + accessionNumber + " because " + ee.getMessage();
3062
                    errorList.addElement(error);
3063
                    continue;
3064
                }
3065
            }
3066
        }
3067
        outputResponse(successList, errorList, out);
3068
    }
3069

    
3070
    /*
3071
     * A method try to determin a docid's public id, if couldn't find null will
3072
     * be returned.
3073
     */
3074
    private String getFieldValueForDoc(String accessionNumber, String fieldName)
3075
            throws Exception
3076
    {
3077
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
3078
        if (accessionNumber == null || accessionNumber.equals("")
3079
                || fieldName == null || fieldName.equals("")) { throw new Exception(
3080
                "Docid or field name was not specified"); }
3081

    
3082
        PreparedStatement pstmt = null;
3083
        ResultSet rs = null;
3084
        String fieldValue = null;
3085
        String docId = null;
3086
        DBConnection conn = null;
3087
        int serialNumber = -1;
3088

    
3089
        // get rid of revision if access number has
3090
        docId = MetaCatUtil.getDocIdFromString(accessionNumber);
3091
        try {
3092
            //check out DBConnection
3093
            conn = DBConnectionPool
3094
                    .getDBConnection("MetaCatServlet.getPublicIdForDoc");
3095
            serialNumber = conn.getCheckOutSerialNumber();
3096
            pstmt = conn.prepareStatement("SELECT " + fieldName
3097
                    + " FROM xml_documents " + "WHERE docid = ? ");
3098

    
3099
            pstmt.setString(1, docId);
3100
            pstmt.execute();
3101
            rs = pstmt.getResultSet();
3102
            boolean hasRow = rs.next();
3103
            int perm = 0;
3104
            if (hasRow) {
3105
                fieldValue = rs.getString(1);
3106
            } else {
3107
                throw new Exception("Could not find document: "
3108
                        + accessionNumber);
3109
            }
3110
        } catch (Exception e) {
3111
            logMetacat.error(
3112
                    "Exception in MetacatServlet.getPublicIdForDoc: "
3113
                            + e.getMessage());
3114
            throw e;
3115
        } finally {
3116
            try {
3117
                rs.close();
3118
                pstmt.close();
3119

    
3120
            } finally {
3121
                DBConnectionPool.returnDBConnection(conn, serialNumber);
3122
            }
3123
        }
3124
        return fieldValue;
3125
    }
3126

    
3127
    /*
3128
     * Get the list of documents from the database and return the list in an
3129
     * Vector of identifiers.
3130
     *
3131
     * @ returns the array of identifiers
3132
     */
3133
    private Vector getDocumentList() throws SQLException
3134
    {
3135
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
3136
        Vector docList = new Vector();
3137
        PreparedStatement pstmt = null;
3138
        ResultSet rs = null;
3139
        DBConnection conn = null;
3140
        int serialNumber = -1;
3141

    
3142
        try {
3143
            //check out DBConnection
3144
            conn = DBConnectionPool
3145
                    .getDBConnection("MetaCatServlet.getDocumentList");
3146
            serialNumber = conn.getCheckOutSerialNumber();
3147
            pstmt = conn.prepareStatement("SELECT docid, rev"
3148
                    + " FROM xml_documents ");
3149
            pstmt.execute();
3150
            rs = pstmt.getResultSet();
3151
            while (rs.next()) {
3152
                String docid = rs.getString(1);
3153
                String rev = rs.getString(2);
3154
                docList.add(docid + "." + rev);
3155
            }
3156
        } catch (SQLException e) {
3157
            logMetacat.error(
3158
                    "Exception in MetacatServlet.getDocumentList: "
3159
                            + e.getMessage());
3160
            throw e;
3161
        } finally {
3162
            try {
3163
                rs.close();
3164
                pstmt.close();
3165

    
3166
            } catch (SQLException se) {
3167
                logMetacat.error(
3168
                    "Exception in MetacatServlet.getDocumentList: "
3169
                            + se.getMessage());
3170
                throw se;
3171
            } finally {
3172
                DBConnectionPool.returnDBConnection(conn, serialNumber);
3173
            }
3174
        }
3175
        return docList;
3176
    }
3177

    
3178
    /*
3179
     * A method to output setAccess action result
3180
     */
3181
    private void outputResponse(Vector successList, Vector errorList,
3182
            PrintWriter out)
3183
    {
3184
        boolean error = false;
3185
        boolean success = false;
3186
        // Output prolog
3187
        out.println(PROLOG);
3188
        // output success message
3189
        if (successList != null) {
3190
            for (int i = 0; i < successList.size(); i++) {
3191
                out.println(SUCCESS);
3192
                out.println((String) successList.elementAt(i));
3193
                out.println(SUCCESSCLOSE);
3194
                success = true;
3195
            }
3196
        }
3197
        // output error message
3198
        if (errorList != null) {
3199
            for (int i = 0; i < errorList.size(); i++) {
3200
                out.println(ERROR);
3201
                out.println((String) errorList.elementAt(i));
3202
                out.println(ERRORCLOSE);
3203
                error = true;
3204
            }
3205
        }
3206

    
3207
        // if no error and no success info, send a error that nothing happened
3208
        if (!error && !success) {
3209
            out.println(ERROR);
3210
            out.println("Nothing happend for setaccess action");
3211
            out.println(ERRORCLOSE);
3212
        }
3213
    }
3214
    
3215
    /**
3216
     * Method to get session table which store the session info
3217
     * @return
3218
     */
3219
    public static Hashtable getSessionHash()
3220
    {
3221
        return sessionHash;
3222
    }
3223
    
3224
    /*
3225
     * If the given docid only have one seperter, we need 
3226
     * append rev for it. The rev come from xml_documents
3227
     */
3228
    private static String appendRev(String docid) throws Exception
3229
    {
3230
        Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
3231
        String newAccNum = null;
3232
        String separator = MetaCatUtil.getOption("accNumSeparator");
3233
        int firstIndex = docid.indexOf(separator);
3234
        int lastIndex = docid.lastIndexOf(separator);
3235
        if (firstIndex == lastIndex)
3236
        {
3237
            
3238
           //only one seperater
3239
            int rev = DBUtil.getLatestRevisionInDocumentTable(docid);
3240
            if (rev == -1)
3241
            {
3242
                throw new Exception("the requested docid '"
3243
                        + docid+ "' does not exist");
3244
            }
3245
            else
3246
            {
3247
                newAccNum = docid+ separator+ rev;
3248
            }
3249
        }
3250
        else
3251
        {
3252
            // in other suituation we don't change the docid
3253
            newAccNum = docid;
3254
        }
3255
        //logMetacat.debug("The docid will be read is "+newAccNum);
3256
        return newAccNum;
3257
  }
3258
}
(44-44/65)