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
7
 *    Release: @release@
8
 *
9
 *   '$Author: berkley $'
10
 *     '$Date: 2000-08-14 14:28:54 -0700 (Mon, 14 Aug 2000) $'
11
 * '$Revision: 351 $'
12
 */
13

    
14
package edu.ucsb.nceas.metacat;
15

    
16
import java.io.PrintWriter;
17
import java.io.IOException;
18
import java.io.Reader;
19
import java.io.StringReader;
20
import java.io.BufferedReader;
21
import java.io.File;
22
import java.io.FileInputStream;
23
import java.util.Enumeration;
24
import java.util.Hashtable;
25
import java.util.ResourceBundle; 
26
import java.util.PropertyResourceBundle;
27
import java.net.URL;
28
import java.net.MalformedURLException;
29
import java.sql.PreparedStatement;
30
import java.sql.ResultSet;
31
import java.sql.Connection;
32
import java.sql.SQLException;
33

    
34
import javax.servlet.ServletConfig;
35
import javax.servlet.ServletContext;
36
import javax.servlet.ServletException;
37
import javax.servlet.ServletInputStream;
38
import javax.servlet.http.HttpServlet;
39
import javax.servlet.http.HttpServletRequest;
40
import javax.servlet.http.HttpServletResponse;
41
import javax.servlet.http.HttpSession;
42
import javax.servlet.http.HttpUtils;
43

    
44
import oracle.xml.parser.v2.XSLStylesheet;
45
import oracle.xml.parser.v2.XSLException;
46
import oracle.xml.parser.v2.XMLDocumentFragment;
47
import oracle.xml.parser.v2.XSLProcessor;
48

    
49
import org.xml.sax.SAXException;
50

    
51
/**
52
 * A metadata catalog server implemented as a Java Servlet
53
 *
54
 * <p>Valid parameters are:<br>
55
 * action=query -- query the values of all elements and attributes
56
 *                     and return a result set of nodes<br>
57
 * action=squery -- structured query (see pathquery.dtd)<br>
58
 * action=insert -- insert an XML document into the database store<br>
59
 * action=update -- update an XML document that is in the database store<br>
60
 * action=delete --  delete an XML document from the database store<br>
61
 * action=validate -- vallidate the xml contained in valtext<br>
62
 * action=getdocument -- display an XML document in XML or HTML<br>
63
 * doctype -- document type list returned by the query (publicID)<br>
64
 * qformat=xml -- display resultset from query in XML<br>
65
 * qformat=html -- display resultset from query in HTML<br>
66
 * docid=34 -- display the document with the document ID number 34<br>
67
 * doctext -- XML text of the document to load into the database<br>
68
 * query -- actual query text (to go with 'action=query' or 'action=squery')<br>
69
 * valtext -- XML text to be validated<br>
70
 * action=getdatadoc -- retreive a stored datadocument<br>
71
 * action=getdoctypes -- retreive all doctypes (publicID)<br>
72
 * action=getdataguide -- retreive a Data Guide<br>
73
 * datadoc -- data document name (id)<br>
74
 * <p>
75
 * The particular combination of parameters that are valid for each 
76
 * particular action value is quite specific.  This documentation
77
 * will be reorganized to reflect this information.
78
 */
79
public class MetaCatServlet extends HttpServlet {
80

    
81
  private ServletConfig		config = null;
82
  private ServletContext	context = null;
83
  private Hashtable 		connectionPool = new Hashtable();
84
  private String 		resultStyleURL = null;
85
  private String 		xmlcatalogfile = null;
86
  private String 		saxparser = null;
87
  private String        defaultdatapath = null; 
88
					// path to directory where data files 
89
					// that can be downloaded will be stored
90
  private String        executescript  = null;  
91
					// script to get data file and put it 
92
                    // in defaultdocpath dir
93
  private PropertyResourceBundle options = null;
94

    
95
  private MetaCatUtil util = null;
96

    
97
  /**
98
   * Initialize the servlet by creating appropriate database connections
99
   */
100
  public void init( ServletConfig config ) throws ServletException {
101
    try {
102
      super.init( config );
103
      this.config = config;
104
      this.context = config.getServletContext(); 
105
      System.out.println("MetaCatServlet Initialize");
106

    
107
      util = new MetaCatUtil();
108

    
109
      // Get the configuration file information
110
      resultStyleURL = util.getOption("resultStyleURL");
111
      xmlcatalogfile = util.getOption("xmlcatalogfile");
112
      saxparser = util.getOption("saxparser");
113
      defaultdatapath = util.getOption("defaultdatapath");
114
      executescript = util.getOption("executescript");
115

    
116
      try {
117
        // Open a pool of db connections
118
        connectionPool = util.getConnectionPool();
119
      } catch (Exception e) {
120
        System.err.println("Error creating pool of database connections");
121
        System.err.println(e.getMessage());
122
      }
123
    } catch ( ServletException ex ) {
124
      throw ex;
125
    }
126
  }
127

    
128
  /**
129
   * Close all db connections from the pool
130
   */
131
  public void destroy() {
132
    
133
    if (util != null) {
134
        util.closeConnections();
135
    }
136
  }
137

    
138
  /** Handle "GET" method requests from HTTP clients */
139
  public void doGet (HttpServletRequest request, HttpServletResponse response)
140
    throws ServletException, IOException {
141

    
142
    // Process the data and send back the response
143
    handleGetOrPost(request, response);
144
  }
145

    
146
  /** Handle "POST" method requests from HTTP clients */
147
  public void doPost( HttpServletRequest request, HttpServletResponse response)
148
    throws ServletException, IOException {
149

    
150
    // Process the data and send back the response
151
    handleGetOrPost(request, response);
152
  }
153

    
154
  /**
155
   * Control servlet response depending on the action parameter specified
156
   */
157
  private void handleGetOrPost(HttpServletRequest request, 
158
    HttpServletResponse response) 
159
    throws ServletException, IOException {
160

    
161
    if ( util == null ) {
162
        util = new MetaCatUtil(); 
163
    }
164
    if ( connectionPool == null ) {
165
      try {
166
        // Open a pool of db connections
167
        connectionPool = util.getConnectionPool();
168
      } catch (Exception e) {
169
        System.err.println("Error creating pool of database connections");
170
        System.err.println(e.getMessage());
171
      }
172
    }    
173
    // Get a handle to the output stream back to the client
174
    PrintWriter out = response.getWriter();
175
    //response.setContentType("text/html");
176
  
177
    String name = null;
178
    String[] value = null;
179
    String[] docid = new String[3];
180
    Hashtable params = new Hashtable();
181
    Enumeration paramlist = request.getParameterNames();
182
    while (paramlist.hasMoreElements()) {
183
      name = (String)paramlist.nextElement();
184
      value = request.getParameterValues(name);
185

    
186
      // Decode the docid and mouse click information
187
      if (name.endsWith(".y")) {
188
        docid[0] = name.substring(0,name.length()-2);
189
        //out.println("docid => " + docid[0]);
190
        params.put("docid", docid);
191
        name = "ypos";
192
      }
193
      if (name.endsWith(".x")) {
194
        name = "xpos";
195
      }
196

    
197
      //out.println(name + " => " + value[0]);
198
      params.put(name,value);
199
    }
200

    
201
    // Determine what type of request the user made
202
    // if the action parameter is set, use it as a default
203
    // but if the ypos param is set, calculate the action needed
204
    String action = ((String[])params.get("action"))[0];
205
    long ypos = 0;
206
    try {
207
      ypos = (new Long(((String[])params.get("ypos"))[0]).longValue());
208
      //out.println("<P>YPOS IS " + ypos);
209
      if (ypos <= 13) {
210
        action = "getdocument";
211
      } else if (ypos > 13 && ypos <= 27) {
212
        action = "validate";
213
      } else if (ypos > 27) {
214
        action = "transform";
215
      //} else {
216
      //  action = "";
217
      }
218
    } catch (Exception npe) {
219
      //out.println("<P>Caught exception looking for Y value.");
220
    }
221

    
222
// Jivka added  
223
    // handle login action
224
    if (action.equals("Login") || action.equals("Login Client")) {
225
      handleLoginAction(out, params, request, response);
226
    // handle logout action  
227
    } else if (action.equals("Logout") || action.equals("Logout Client")) {
228
      HttpSession sess = request.getSession(false);
229
      if (sess != null) { sess.invalidate();  }    
230
      if (action.equals("Logout Client")) {
231
        out.println("<?xml version=\"1.0\"?>");
232
        out.println("<success>");
233
        out.println("User logout.");
234
        out.println("</success>");
235
        return;
236
      }    
237
      response.sendRedirect("/xmltodb/index.html"); 
238
    // aware of session expiration on every request  
239
    } else {   
240
      HttpSession sess = request.getSession(true);
241
      if (sess.isNew()) { 
242
        // session expired or has not been stored b/w user requests
243
        // redirect to default page for query only access
244

    
245
      //  response.sendRedirect("/xmltodb/sexpire.html");
246
      } 
247
    }    
248
// End of Jivka added
249

    
250
    if (action.equals("query") || action.equals("squery")) {
251
      handleQueryAction(out, params, response);
252
    } else if (action.equals("getdocument")) {
253
      try {
254
        handleGetDocumentAction(out, params, response);
255
      } catch (ClassNotFoundException e) {
256
        out.println(e.getMessage());
257
      } catch (SQLException se) {
258
        out.println(se.getMessage());
259
      }
260
    } else if (action.equals("insert") || action.equals("update")) {
261
      handleInsertOrUpdateAction(out, params, response);
262
    } else if (action.equals("delete")) {
263
      handleDeleteAction(out, params, response);
264
    } else if (action.equals("validate")) {
265
      handleValidateAction(out, params, response);  
266
    } else if (action.equals("getdatadoc")) {
267
      handleGetDataDocumentAction(out, params, response);  
268
    } else if (action.equals("getdoctypes")) {
269
      handleGetDoctypesAction(out, params, response);  
270
    } else if (action.equals("getdataguide")) {
271
      handleGetDataGuideAction(out, params, response);  
272
    } else if (action.equals("Login") || action.equals("Login Client")) {
273
    } else {
274
      out.println("Error: action not registered.  Please report this error.");
275
    }
276

    
277
    // Close the stream to the client
278
    out.close();
279
  }
280

    
281
// Jivka added
282
  /** 
283
   * Handle the Login request. Create a new session object.
284
   * Make a user authentication through SRB RMI Connection.
285
   */
286

    
287
  private void handleLoginAction(PrintWriter out, Hashtable params, 
288
               HttpServletRequest request, HttpServletResponse response) {
289

    
290
    MetaCatSession sess = null;
291
    String un = ((String[])params.get("username"))[0];
292
    String pw = ((String[])params.get("password"))[0];
293
    String action = ((String[])params.get("action"))[0];
294
    
295
    try {
296
        sess = new MetaCatSession(request, un, pw);
297
    } catch (Exception e) {
298
      out.println(e.getMessage());
299
    }
300

    
301
    if ( un.equals("anonymous") ) {
302
            try {
303
                if (action.equals("Login Client")) {
304
                    out.println("<?xml version=\"1.0\"?>");
305
                    out.println("<success>");
306
                    out.println("User Authentication successful.");
307
                    out.println("</success>");
308
                    return;
309
                } else {
310
                    response.sendRedirect(
311
                      response.encodeRedirectUrl("/berkley/index.html"));
312
                }    
313
            } catch ( java.io.IOException ioe) {
314
                sess.disconnect();            
315
                out.println("<?xml version=\"1.0\"?>");
316
                out.println("<error>");
317
                out.println("MetaCatServlet.handleLoginAction() - " +
318
                            "Error on redirect of HttpServletResponse: " + 
319
                            ioe.getMessage());
320
                out.println("</error>");
321
                return;
322
            }                
323
    }    
324

    
325
    try { 
326
        if (sess.userAuth(un, pw)) {
327
            try {
328
                if (action.equals("Login Client")) {
329
                    out.println("<?xml version=\"1.0\"?>");
330
                    out.println("<success>");
331
                    out.println("User Authentication successful.");
332
                    out.println("</success>");
333
                } else {
334
                    response.sendRedirect(
335

    
336
                    response.encodeRedirectUrl("/berkley/metacat.html"));
337
                }    
338
            } catch ( java.io.IOException ioe) {
339
                sess.disconnect();            
340
                out.println("<?xml version=\"1.0\"?>");
341
                out.println("<error>");
342
                out.println("MetaCatServlet.handleLoginAction() - " +
343
                            "Error on redirect of HttpServletResponse: " + 
344
                            ioe.getMessage());
345
                out.println("</error>");
346
            }                
347
                
348
        } else {  
349
            sess.disconnect();            
350
            out.println("<?xml version=\"1.0\"?>");
351
            out.println("<error>");
352
            out.println("SRB Connection failed. " +
353
                        "SRB RMI Server is not running now or " +
354
                        "user " + un + 
355
                        " has not been authenticated to use the system.");
356
            out.println("</error>");
357
        }    
358
    } catch ( java.rmi.RemoteException re) {
359
            sess.disconnect();            
360
            out.println("<?xml version=\"1.0\"?>");
361
            out.println("<error>");
362
            out.println("SRB Connection failed. " + re.getMessage());
363
            out.println("</error>"); 
364
    }        
365
  }
366

    
367
  /** 
368
    *Create the squery xml and return it as a String.
369
    * @param params is the Hashtable of parameters that should be included
370
    * in the squery.
371
    */
372
  private String handleSQuery(Hashtable params) 
373
  {
374
    //create the squery and return it to be processed
375
    String doctype = null;
376
    String[] doctypeArr = null;
377
    doctypeArr = (String[])params.get("doctype");
378
    doctype = null;
379
    if (doctypeArr != null) 
380
    {
381
      doctype = ((String[])params.get("doctype"))[0]; 
382
    }
383
    else
384
    {
385
      doctype="ANY"; 
386
    }
387
    return DBQuery.createSQuery(params, doctype);
388
  }
389
  
390
   /**
391
    *Create the query xml and return it as a String.
392
    * @param query is the free text query parameter returned through the CGI.
393
    * @param doctype is the doctype parameter returned through the CGI. 
394
    * If no doctype filter is required, set it to null or "".
395
    */
396
  private String handleQuery(Hashtable params)
397
  {
398
    String doctype=null; 
399
    String[] doctypeArr=null; 
400
    String query=null;
401
    if(params.containsKey("query"))
402
    {
403
      query = ((String[])params.get("query"))[0];
404
    }
405
    else
406
    {
407
      query = ""; 
408
    }
409
    
410
    if(params.containsKey("doctype"))
411
    {
412
      doctypeArr = (String[])params.get("doctype");
413
      doctype = null;
414
    }
415
    else
416
    {
417
      doctype = "ANY";  
418
    }
419
    
420
    if (doctypeArr != null) 
421
    {
422
      doctype = ((String[])params.get("doctype"))[0]; 
423
    }
424
    else
425
    {
426
      doctype="ANY"; 
427
    }
428
    return DBQuery.createQuery(query,doctype);
429
  }
430
  
431
  /**
432
    * Run the query and return a hashtable of results.
433
    */
434
  private Hashtable runQuery(StringBuffer xmlquery)
435
  {
436
    Hashtable doclist=null;
437
    Connection conn = null;
438
    try
439
    {
440
        conn = util.getConnection();
441
        DBQuery queryobj = new DBQuery(conn, saxparser);
442
        doclist = queryobj.findDocuments(new StringReader(xmlquery.toString()));
443
        util.returnConnection(conn);
444
        return doclist;
445
    } 
446
    catch (Exception e) 
447
    {
448
      if (conn != null) 
449
      {
450
        util.returnConnection(conn); 
451
      }
452
      util.debugMessage("Error in runQuery: " + e.getMessage());
453
      doclist = null;
454
      return doclist;
455
    }    
456
  }
457
  
458
  private void transformDocument(Hashtable doclist, String qformat, 
459
                                 String xmlquery, PrintWriter out,
460
                                 HttpServletResponse response)
461
  {
462
    // Create a buffer to hold the xml result
463
    StringBuffer resultset = new StringBuffer();
464
 
465
    // Print the resulting root nodes
466
    String docid = null;
467
    String document = null;
468
    resultset.append("<?xml version=\"1.0\"?>\n");
469
    resultset.append("<resultset>\n");
470
    //resultset.append("  <query>" + xmlquery + "</query>");   
471
    Enumeration doclistkeys = doclist.keys(); 
472
    while (doclistkeys.hasMoreElements()) 
473
    {
474
      docid = (String)doclistkeys.nextElement();
475
      document = (String)doclist.get(docid);
476
      resultset.append("  <document>" + document + "</document>");
477
    }
478
    resultset.append("</resultset>");
479

    
480
    if(qformat.equals("xml")) 
481
    {
482
      // set content type and other response header fields first
483
      response.setContentType("text/xml");
484
      out.println(resultset.toString());
485
    } 
486
    else if(qformat.equals("html")) 
487
    {
488
      // set content type and other response header fields first
489
      response.setContentType("text/html");
490
      XMLDocumentFragment htmldoc = null;
491
      try 
492
      {
493
        XSLStylesheet style = new XSLStylesheet(
494
                              new URL(resultStyleURL), null);
495
        htmldoc = (new XSLProcessor()).processXSL(style, 
496
                  (Reader)(new StringReader(resultset.toString())),null);
497
        htmldoc.print(out);
498
      } 
499
      catch (Exception e)   
500
      {
501
        out.println("Error transforming document:\n" + e.getMessage());
502
      }
503
    }
504
  }
505
                              
506
  /** 
507
   * Handle the database query request and return a result set, possibly
508
   * transformed from XML into HTML
509
   */ 
510
  private void handleQueryAction(PrintWriter out, Hashtable params, 
511
                                 HttpServletResponse response)  
512
  {
513
      String action = ((String[])params.get("action"))[0];
514
      Hashtable doclist = null;
515
      String[] doctypeArr = null;
516
      String doctype = null;
517
      StringBuffer xmlquery = null;
518
      Connection conn = null;
519

    
520
      if(action.equals("query"))
521
      {
522
        xmlquery = new StringBuffer(handleQuery(params));
523
      }
524
      else if(action.equals("squery"))
525
      {
526
        xmlquery = new StringBuffer(handleSQuery(params));
527
      }
528
      //System.out.println("Query is: ");
529
      //System.out.println(xmlquery.toString());
530
      
531
      doclist = runQuery(xmlquery);
532
      //System.out.println("result is: " );
533
      //System.out.println(doclist.toString());
534
      String qformat = ((String[])params.get("qformat"))[0]; 
535
      transformDocument(doclist, qformat, xmlquery.toString(), out, response);
536
  }
537

    
538
  /** 
539
   * Handle the database getdocument request and return a XML document, 
540
   * possibly transformed from XML into HTML
541
   */
542
  private void handleGetDocumentAction(PrintWriter out, Hashtable params, 
543
               HttpServletResponse response) 
544
               throws ClassNotFoundException, IOException, SQLException {
545
    String docidstr = null;
546
    String docid = null;
547
    String doc = null;
548
    Connection conn = null;
549
    
550
    try {
551
      // Find the document id number
552
      docidstr = ((String[])params.get("docid"))[0]; 
553
      //docid = (new Long(docidstr)).longValue();
554
      docid = docidstr;
555

    
556
      conn = util.getConnection();
557
      DBReader docreader = new DBReader(conn);
558
      DBTransform dbt = new DBTransform(conn);
559
      
560
      // Get the document indicated fromthe db
561
      doc = docreader.readXMLDocument(docid);
562

    
563
      // Return the document in XML or HTML format
564
      String qformat = ((String[])params.get("qformat"))[0]; 
565
      if (qformat.equals("xml")) {
566
        // set content type and other response header fields first
567
        response.setContentType("text/xml");
568
        out.println(doc);
569
      } else if (qformat.equals("html")) {
570
        // set content type and other response header fields first
571
        response.setContentType("text/html");
572

    
573
        // Look up the document type
574
        String sourcetype = docreader.getDoctypeInfo(docid).getDoctype();
575

    
576
        // Transform the document to the new doctype
577
        dbt.transformXMLDocument(doc, sourcetype, "-//W3C//HTML//EN", out);
578
      }
579
    //} catch (NullPointerException npe) {
580
      //response.setContentType("text/html");
581
      //out.println("Error getting document ID: " + docidstr +" (" + docid + ")");
582
    } catch (McdbException e) {
583
      response.setContentType("text/xml");
584
      e.toXml(out);
585
    } catch (Throwable t) {
586
      response.setContentType("text/html");
587
      out.println(t.getMessage());
588
    } finally {
589
      util.returnConnection(conn);
590
    }    
591

    
592
  }
593

    
594
  /** 
595
   * Handle the database putdocument request and write an XML document 
596
   * to the database connection
597
   */
598
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params, 
599
               HttpServletResponse response) {
600

    
601
    Connection conn = null;
602

    
603
    try {
604
      // Get the document indicated
605
      String[] doctext = (String[])params.get("doctext");
606
      StringReader xml = null;
607
      try {
608
        xml = new StringReader(doctext[0]);
609

    
610
        String[] action = (String[])params.get("action");
611
        String[] docid = (String[])params.get("docid");
612
        String newdocid = null;
613

    
614
        String doAction = null;
615
        if (action[0].equals("insert")) {
616
          doAction = "INSERT";
617
        } else if (action[0].equals("update")) {
618
          doAction = "UPDATE";
619
        }
620

    
621
        try {
622
            // get a connection from the pool
623
            conn = util.getConnection();
624
            // write the document to the database
625
            DBWriter dbw = new DBWriter(conn, saxparser);
626

    
627
            try {
628
                String accNumber = docid[0];
629
                if (accNumber.equals("")) {
630
                    accNumber = null;
631
                }
632
                newdocid = dbw.write(xml, doAction, accNumber);  
633
            } catch (NullPointerException npe) {
634
              newdocid = dbw.write(xml, doAction, null);  
635
            }
636
        } catch (Exception e) {
637
          response.setContentType("text/html");
638
          out.println(e.getMessage());
639
        } finally {
640
          util.returnConnection(conn);
641
        }    
642

    
643
        // set content type and other response header fields first
644
        response.setContentType("text/xml");
645
        out.println("<?xml version=\"1.0\"?>");
646
        out.println("<success>");
647
        out.println("<docid>" + newdocid + "</docid>"); 
648
        out.println("</success>");
649

    
650
      } catch (NullPointerException npe) {
651
        response.setContentType("text/xml");
652
        out.println("<?xml version=\"1.0\"?>");
653
        out.println("<error>");
654
        out.println(npe.getMessage()); 
655
        out.println("</error>");
656
      }
657
    } catch (Exception e) {
658
      response.setContentType("text/xml");
659
      out.println("<?xml version=\"1.0\"?>");
660
      out.println("<error>");
661
      out.println(e.getMessage()); 
662
      if (e instanceof SAXException) {
663
        Exception e2 = ((SAXException)e).getException();
664
        out.println("<error>");
665
        out.println(e2.getMessage()); 
666
        out.println("</error>");
667
      }
668
      //e.printStackTrace(out);
669
      out.println("</error>");
670
    }
671
  }
672

    
673
  /** 
674
   * Handle the database delete request and delete an XML document 
675
   * from the database connection
676
   */
677
  private void handleDeleteAction(PrintWriter out, Hashtable params, 
678
               HttpServletResponse response) {
679

    
680
    String[] docid = (String[])params.get("docid");
681
    Connection conn = null;
682

    
683
    // delete the document from the database
684
    try {
685
      // get a connection from the pool
686
      conn = util.getConnection();
687
      DBWriter dbw = new DBWriter(conn, saxparser);
688
                                      // NOTE -- NEED TO TEST HERE
689
                                      // FOR EXISTENCE OF PARAM
690
                                      // BEFORE ACCESSING ARRAY
691
      try {
692
        dbw.delete(docid[0]);
693
        response.setContentType("text/xml");
694
        out.println("<?xml version=\"1.0\"?>");
695
        out.println("<success>");
696
        out.println("Document deleted."); 
697
        out.println("</success>");
698
      } catch (AccessionNumberException ane) {
699
        response.setContentType("text/xml");
700
        out.println("<?xml version=\"1.0\"?>");
701
        out.println("<error>");
702
        out.println("Error deleting document!!!");
703
        out.println(ane.getMessage()); 
704
        out.println("</error>");
705
      }
706
    } catch (Exception e) {
707
      response.setContentType("text/xml");
708
      out.println("<?xml version=\"1.0\"?>");
709
      out.println("<error>");
710
      out.println(e.getMessage()); 
711
      out.println("</error>");
712
    } finally {
713
      util.returnConnection(conn);
714
    }  
715
  }
716
  
717
  /** 
718
   * Handle the validtion request and return the results to the requestor
719
   */
720
  private void handleValidateAction(PrintWriter out, Hashtable params, 
721
               HttpServletResponse response) {
722

    
723
    // Get the document indicated
724
    String valtext = null;
725
    
726
    try {
727
      valtext = ((String[])params.get("valtext"))[0];
728
    } catch (Exception nullpe) {
729

    
730
      Connection conn = null;
731
      String docid = null;
732
      try {
733
        // Find the document id number
734
        docid = ((String[])params.get("docid"))[0]; 
735

    
736
        // get a connection from the pool
737
        conn = util.getConnection();
738
        DBReader docreader = new DBReader(conn);
739
        // Get the document indicated from the db
740
        valtext = docreader.readXMLDocument(docid);
741

    
742
      } catch (NullPointerException npe) {
743
        response.setContentType("text/xml");
744
        out.println("<error>Error getting document ID: " + docid + "</error>");
745
        if ( conn != null ) { util.returnConnection(conn); }
746
        return; // Jivka added
747
      } catch (Exception e) {
748
        response.setContentType("text/html");
749
        out.println(e.getMessage()); 
750
      } finally {
751
        util.returnConnection(conn);
752
      }  
753
    }
754

    
755
    Connection conn = null;
756
    try {
757
      // get a connection from the pool
758
      conn = util.getConnection();
759
      DBValidate valobj = new DBValidate(saxparser,conn);
760
      boolean valid = valobj.validateString(valtext);
761

    
762
      // set content type and other response header fields first
763
      response.setContentType("text/xml");
764
      out.println(valobj.returnErrors());
765

    
766
    } catch (NullPointerException npe2) {
767
      // set content type and other response header fields first
768
      response.setContentType("text/xml");
769
      out.println("<error>Error validating document.</error>"); 
770
    } catch (Exception e) {
771
      response.setContentType("text/html");
772
      out.println(e.getMessage()); 
773
    } finally {
774
      util.returnConnection(conn);
775
    }  
776
  }
777

    
778
  /** 
779
   * Handle the document request and return the results 
780
   * to the requestor
781
   */
782
  private void handleGetDataDocumentAction(PrintWriter out, Hashtable params, 
783
               HttpServletResponse response) {
784
      boolean error_flag = false;
785
      String error_message = "";
786
      // Get the document indicated
787
      String[] datadoc = (String[])params.get("datadoc");
788
      // defaultdatapath = "C:\\Temp\\";    // for testing only!!!
789
      // executescript = "test.bat";        // for testing only!!!
790
      
791
      // set content type and other response header fields first
792
      response.setContentType("application/octet-stream");
793
      if (defaultdatapath!=null) {
794
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) {
795
          defaultdatapath=defaultdatapath+System.getProperty("file.separator");
796
        }
797
        System.out.println("Path= "+defaultdatapath+datadoc[0]);
798
        if (executescript!=null) {
799
          String command = null;
800
          File scriptfile = new File(executescript);
801
          if (scriptfile.exists()) {
802
            command=executescript+" "+datadoc[0]; // script includes path
803
        } else {     // look in defaultdatapath
804
            // on Win98 one MUST include the .bat extender
805
            command = defaultdatapath+executescript+" "+datadoc[0];  
806
        }
807
      System.out.println(command);
808
      try {
809
      Process proc = Runtime.getRuntime().exec(command);
810
      proc.waitFor();
811
      }
812
      catch (Exception eee) {
813
        System.out.println("Error running process!");
814
        error_flag = true;
815
        error_message = "Error running process!";}
816
      } // end executescript not null if
817
      File datafile = new File(defaultdatapath+datadoc[0]);
818
      try {
819
      FileInputStream fw = new FileInputStream(datafile);
820
      int x;
821
      while ((x = fw.read())!=-1) {
822
        out.write(x); }
823
        fw.close();
824
      } catch (Exception e) {
825
        System.out.println("Error in returning file\n"+e.getMessage());
826
        error_flag=true;
827
        error_message = error_message+"\nError in returning file\n"+
828
                        e.getMessage();
829
      }
830
    } // end defaultdatapath not null if
831
  }
832
  
833
  /** 
834
   * Handle the getdoctypes Action.
835
   * Read all doctypes from db connection in XML format
836
   */
837

    
838
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params, 
839
                                       HttpServletResponse response) {
840

    
841
    Connection conn = null;
842
    
843
    try {
844

    
845
        // get connection from the pool
846
        conn = util.getConnection();
847
        DBUtil dbutil = new DBUtil(conn);
848
        String doctypes = dbutil.readDoctypes();
849
        out.println(doctypes);
850

    
851
    } catch (Exception e) {
852
      out.println("<?xml version=\"1.0\"?>");
853
      out.println("<error>");
854
      out.println(e.getMessage());
855
      out.println("</error>");
856
    } finally {
857
      util.returnConnection(conn);
858
    }  
859
    
860
  }
861

    
862
  /** 
863
   * Handle the getdataguide Action.
864
   * Read Data Guide for a given doctype from db connection in XML format
865
   */
866

    
867
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
868
                                        HttpServletResponse response) {
869

    
870
    Connection conn = null;
871
    String doctype = null;
872
    String[] doctypeArr = (String[])params.get("doctype");
873

    
874
    // get only the first doctype specified in the list of doctypes
875
    // it could be done for all doctypes in that list
876
    if (doctypeArr != null) {
877
        doctype = ((String[])params.get("doctype"))[0]; 
878
    }
879

    
880
    try {
881

    
882
        // get connection from the pool
883
        conn = util.getConnection();
884
        DBUtil dbutil = new DBUtil(conn);
885
        String dataguide = dbutil.readDataGuide(doctype);
886
        out.println(dataguide);
887

    
888
    } catch (Exception e) {
889
      out.println("<?xml version=\"1.0\"?>");
890
      out.println("<error>");
891
      out.println(e.getMessage());
892
      out.println("</error>");
893
    } finally {
894
      util.returnConnection(conn);
895
    }  
896
    
897
  }
898

    
899
}
900

    
901
/**
902
 * '$Log$
903
 * 'Revision 1.67  2000/08/14 20:43:27  jones
904
 * 'Updated build process to now use a copy of the source files so that keyword
905
 * 'substitution can ocur before the build.  This allows for substitution of
906
 * 'hardcoded values into the source before the compile.  Currently, I am
907
 * 'using this feature to do the following:
908
 * '
909
 * '	1) Substitute a "Release" number into the code
910
 * '	2) Substitute a hardcoded servlet path into the code and html files
911
 * '
912
 * 'By changing the value of "servlet-path" and "installdir" properties in
913
 * 'build.xml, one can now easily install a new version of the servlet in a
914
 * 'different location by simply using "ant install".
915
 * '
916
 * 'Revision 1.66  2000/08/14 18:27:37  bojilova
917
 * 'added Logout handling
918
 * '
919
 * 'Revision 1.64  2000/08/11 22:20:04  jones
920
 * 'Changed exception handling mechanisms for DBReader
921
 * '
922
 * 'Revision 1.63  2000/08/11 18:25:26  berkley
923
 * 'broke up handleQueryAction into handleQuery, handleSQuery, runQuery and transformDocument
924
 * '
925
 * 'Revision 1.61  2000/08/10 18:56:48  bojilova
926
 * 'added "anonymous" user connection
927
 * '
928
 * 'Revision 1.60  2000/08/09 00:39:47  jones
929
 * '-Reorganized xmltodb module to support new install process for the new
930
 * 'linux server (dev.nceas.ucsb.edu).  Added "build.sh" shell script that
931
 * 'calls ant withthe proper umask set for installation.  Use:
932
 * '
933
 * '  ./build.sh install
934
 * '
935
 * 'to post a new copy of the servlet and its supporting files to the install
936
 * 'directory defined in build.xml.
937
 * '
938
 * '-Updated the servlet to use a new servlet prefix that we'll use with the
939
 * 'Tomcat servlet engine.
940
 * '
941
 * '-Update bin dir shell scripts to reflect new locations of relevant jar files.
942
 * '
943
 * 'Revision 1.59  2000/08/08 00:31:20  bojilova
944
 * 'rearrange html pages for login and metacat access
945
 * '
946
 * 'Revision 1.58  2000/08/04 23:34:09  bojilova
947
 * 'more precise handling of the Connection Pool
948
 * '
949
 * 'Revision 1.57  2000/08/03 23:20:31  bojilova
950
 * 'Changes related to "getdataguide" action
951
 * '
952
 * 'Revision 1.55  2000/08/01 18:26:50  bojilova
953
 * 'added Pool of Connections
954
 * 'DBQuery, DBReader, DBTransform, DBUtil are created on every request and use the connections from the Pool
955
 * 'same with DBWriter and DBValidate
956
 * '
957
 * 'Revision 1.54  2000/07/27 23:12:21  bojilova
958
 * 'Added "getdoctypes" and "getdataguide" action handlers
959
 * '
960
 * 'Revision 1.53  2000/07/26 20:48:29  bojilova
961
 * 'Added "Login Client" action for login from the Desktop Client
962
 * '
963
 * 'Revision 1.52  2000/07/26 20:38:40  higgins
964
 * 'no message
965
 * '
966
 * 'Revision 1.51  2000/07/01 01:09:44  jones
967
 * 'MetaCatServlet.java
968
 * '
969
 * 'Revision 1.50  2000/06/30 23:42:33  bojilova
970
 * 'finished user auth & session tracking
971
 * '
972
 * 'Revision 1.49  2000/06/29 23:27:08  jones
973
 * 'Fixed bug in DBEntityResolver so that it now properly delegates to
974
 * 'the system id found inthe database.
975
 * 'Changed DBValidate to use DBEntityResolver, rather than the OASIS
976
 * 'catalog, and to return validation results in XML format.
977
 * '
978
 * 'Revision 1.48  2000/06/29 20:04:51  bojilova
979
 * 'testing login
980
 * '
981
 * 'Revision 1.36  2000/06/28 02:36:26  jones
982
 * 'Added feature to now ouput COMMENTs and PIs when the document is
983
 * 'read from the database with DBReader.
984
 * '
985
 * 'Revision 1.35  2000/06/28 00:00:47  bojilova
986
 * 'changed to
987
 * 'response.sendRedirect(response.encodeRedirectUrl("/xmltodb/lib/index.html"));
988
 * '
989
 * 'Revision 1.33  2000/06/27 04:50:33  jones
990
 * 'Updated javadoc documentation.
991
 * '
992
 * 'Revision 1.32  2000/06/27 04:31:07  jones
993
 * 'Fixed bugs associated with the new UPDATE and DELETE functions of
994
 * 'DBWriter.  There were problematic interactions between some static
995
 * 'variables used in DBEntityResolver and the way in which the
996
 * 'Servlet objects are re-used across multiple client invocations.
997
 * '
998
 * 'Generally cleaned up error reporting.  Now all errors and success
999
 * 'results are reported as XML documents from MetaCatServlet.  Need
1000
 * 'to make the command line tools do the same.
1001
 * '
1002
 * 'Revision 1.31  2000/06/26 10:35:05  jones
1003
 * 'Merged in substantial changes to DBWriter and associated classes and to
1004
 * 'the MetaCatServlet in order to accomodate the new UPDATE and DELETE
1005
 * 'functions.  The command line tools and the parameters for the
1006
 * 'servlet have changed substantially.
1007
 * '
1008
 * 'Revision 1.30.2.6  2000/06/26 10:18:06  jones
1009
 * 'Partial fix for MetaCatServlet INSERT?UPDATE bug.  Only will work on
1010
 * 'the first call to the servlet.  Subsequent calls fail.  Seems to be
1011
 * 'related to exception handling.  Multiple successive DELETE actions
1012
 * 'work fine.
1013
 * '
1014
 * 'Revision 1.30.2.5  2000/06/26 09:09:53  jones
1015
 * 'Modified MetaCatServlet and associated files to handle the UPDATE
1016
 * 'and DELETE actions for DBWriter.
1017
 * '
1018
 * 'Revision 1.30.2.4  2000/06/26 00:51:06  jones
1019
 * 'If docid passed to DBWriter.write() is not unique, classes now generate
1020
 * 'an AccessionNumberException containing the new docid generated as a
1021
 * 'replacement.  The docid is then extracted from the exception and
1022
 * 'returned to the calling application for user feedback or client processing.
1023
 * '
1024
 * 'Revision 1.30.2.3  2000/06/25 23:38:17  jones
1025
 * 'Added RCSfile keyword
1026
 * '
1027
 * 'Revision 1.30.2.2  2000/06/25 23:34:18  jones
1028
 * 'Changed documentation formatting, added log entries at bottom of source files
1029
 * ''
1030
 */
(21-21/27)