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: berkley $'
10
 *     '$Date: 2000-08-16 11:48:57 -0700 (Wed, 16 Aug 2000) $'
11
 * '$Revision: 370 $'
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
import java.lang.reflect.*;
34

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

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

    
50
import org.xml.sax.SAXException;
51

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

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

    
98
  private MetaCatUtil util = null;
99

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

    
110
      util = new MetaCatUtil();
111

    
112
      // Get the configuration file information
113
      resultStyleURL = util.getOption("resultStyleURL");
114
      xmlcatalogfile = util.getOption("xmlcatalogfile");
115
      saxparser = util.getOption("saxparser");
116
      defaultdatapath = util.getOption("defaultdatapath");
117
      executescript = util.getOption("executescript");
118
      servletpath = util.getOption("servletpath");
119
      htmlpath = util.getOption("htmlpath");
120

    
121
      try {
122
        // Open a pool of db connections
123
        connectionPool = util.getConnectionPool();
124
      } catch (Exception e) {
125
        System.err.println("Error creating pool of database connections");
126
        System.err.println(e.getMessage());
127
      }
128
    } catch ( ServletException ex ) {
129
      throw ex;
130
    }
131
  }
132

    
133
  /**
134
   * Close all db connections from the pool
135
   */
136
  public void destroy() {
137
    
138
    if (util != null) {
139
        util.closeConnections();
140
    }
141
  }
142

    
143
  /** Handle "GET" method requests from HTTP clients */
144
  public void doGet (HttpServletRequest request, HttpServletResponse response)
145
    throws ServletException, IOException {
146

    
147
    // Process the data and send back the response
148
    handleGetOrPost(request, response);
149
  }
150

    
151
  /** Handle "POST" method requests from HTTP clients */
152
  public void doPost( HttpServletRequest request, HttpServletResponse response)
153
    throws ServletException, IOException {
154

    
155
    // Process the data and send back the response
156
    handleGetOrPost(request, response);
157
  }
158

    
159
  /**
160
   * Control servlet response depending on the action parameter specified
161
   */
162
  private void handleGetOrPost(HttpServletRequest request, 
163
    HttpServletResponse response) 
164
    throws ServletException, IOException 
165
 {
166

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

    
192
      // Decode the docid and mouse click information
193
      if (name.endsWith(".y")) {
194
        docid[0] = name.substring(0,name.length()-2);
195
        //out.println("docid => " + docid[0]);
196
        params.put("docid", docid);
197
        name = "ypos";
198
      }
199
      if (name.endsWith(".x")) {
200
        name = "xpos";
201
      }
202

    
203
      //out.println(name + " => " + value[0]);
204
      params.put(name,value);
205
    }
206
    
207
    //if the user clicked on the input images, decode which image
208
    //was clicked then set the action.
209
    String action = decodeMouseAction(params);
210
    if(action.equals("error"))
211
    {
212
      action = ((String[])params.get("action"))[0];  
213
    }
214
    
215
// Jivka added  
216
    // handle login action
217
    if (action.equals("Login") || action.equals("Login Client")) {
218
      handleLoginAction(out, params, request, response);
219
    // handle logout action  
220
    } else if (action.equals("Logout") || action.equals("Logout Client")) {
221
      HttpSession sess = request.getSession(false);
222
      if (sess != null) { sess.invalidate();  }    
223
      if (action.equals("Logout Client")) {
224
        out.println("<?xml version=\"1.0\"?>");
225
        out.println("<success>");
226
        out.println("User logout.");
227
        out.println("</success>");
228
        return;
229
      }    
230

    
231
      response.sendRedirect(htmlpath + "/index.html"); 
232

    
233
    // aware of session expiration on every request  
234
    } else {   
235
      HttpSession sess = request.getSession(true);
236
      if (sess.isNew()) { 
237
        // session expired or has not been stored b/w user requests
238
        // redirect to default page for query only access
239

    
240

    
241
      //  response.sendRedirect(htmlpath + "/sexpire.html");
242

    
243
      } 
244
    }    
245
// End of Jivka added
246

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

    
280
    // Close the stream to the client
281
    out.close();
282
  }
283
  
284
  /**
285
   * decodes the mouse click information coming from the client.
286
   * This function may be overwritten to provide specific functionality
287
   * for different applications.
288
   * @param params the parameters from the CGI
289
   * @return action the action to be performed or "error" if an error was
290
   * generated
291
   */
292
  private String decodeMouseAction(Hashtable params)
293
  {
294
    // Determine what type of request the user made
295
    // if the action parameter is set, use it as a default
296
    // but if the ypos param is set, calculate the action needed
297
    String action=null;
298
    long ypos = 0;
299
    try {
300
      ypos = (new Long(((String[])params.get("ypos"))[0]).longValue());
301
      //out.println("<P>YPOS IS " + ypos);
302
      if (ypos <= 13) {
303
        action = "getdocument";
304
      } else if (ypos > 13 && ypos <= 27) {
305
        action = "validate";
306
      } else if (ypos > 27) {
307
        action = "transform";
308
      }
309
      return action;
310
    } catch (Exception npe) {
311
      //out.println("<P>Caught exception looking for Y value.");
312
      return "error";
313
    } 
314
  }
315

    
316
// Jivka added
317
  /** 
318
   * Handle the Login request. Create a new session object.
319
   * Make a user authentication through SRB RMI Connection.
320
   */
321

    
322
  private void handleLoginAction(PrintWriter out, Hashtable params, 
323
               HttpServletRequest request, HttpServletResponse response) {
324

    
325
    MetaCatSession sess = null;
326
    String un = ((String[])params.get("username"))[0];
327
    String pw = ((String[])params.get("password"))[0];
328
    String action = ((String[])params.get("action"))[0];
329
    
330
    try {
331
        sess = new MetaCatSession(request, un, pw);
332
    } catch (Exception e) {
333
      out.println(e.getMessage());
334
    }
335

    
336
    if ( un.equals("anonymous") ) {
337
            try {
338
                if (action.equals("Login Client")) {
339
                    out.println("<?xml version=\"1.0\"?>");
340
                    out.println("<success>");
341
                    out.println("User Authentication successful.");
342
                    out.println("</success>");
343
                    return;
344
                } else {
345
                    response.sendRedirect(
346
                      response.encodeRedirectUrl(htmlpath + "/index.html"));
347
                }    
348
            } catch ( java.io.IOException ioe) {
349
                sess.disconnect();            
350
                out.println("<?xml version=\"1.0\"?>");
351
                out.println("<error>");
352
                out.println("MetaCatServlet.handleLoginAction() - " +
353
                            "Error on redirect of HttpServletResponse: " + 
354
                            ioe.getMessage());
355
                out.println("</error>");
356
                return;
357
            }                
358
    }    
359

    
360
    try { 
361
        if (sess.userAuth(un, pw)) {
362
            try {
363
                if (action.equals("Login Client")) {
364
                    out.println("<?xml version=\"1.0\"?>");
365
                    out.println("<success>");
366
                    out.println("User Authentication successful.");
367
                    out.println("</success>");
368
                } else {
369
                    response.sendRedirect(
370

    
371
                    response.encodeRedirectUrl(htmlpath + "/metacat.html"));
372
                }    
373
            } catch ( java.io.IOException ioe) {
374
                sess.disconnect();            
375
                out.println("<?xml version=\"1.0\"?>");
376
                out.println("<error>");
377
                out.println("MetaCatServlet.handleLoginAction() - " +
378
                            "Error on redirect of HttpServletResponse: " + 
379
                            ioe.getMessage());
380
                out.println("</error>");
381
            }                
382
                
383
        } else {  
384
            sess.disconnect();            
385
            out.println("<?xml version=\"1.0\"?>");
386
            out.println("<error>");
387
            out.println("SRB Connection failed. " +
388
                        "SRB RMI Server is not running now or " +
389
                        "user " + un + 
390
                        " has not been authenticated to use the system.");
391
            out.println("</error>");
392
        }    
393
    } catch ( java.rmi.RemoteException re) {
394
            sess.disconnect();            
395
            out.println("<?xml version=\"1.0\"?>");
396
            out.println("<error>");
397
            out.println("SRB Connection failed. " + re.getMessage());
398
            out.println("</error>"); 
399
    }             
400
  }    
401
  
402
  /**  
403
    *Create the squery xml, execute it and display it
404
    * @param out is the output stream to the client
405
    * @param params is the Hashtable of parameters that should be included
406
    * in the squery.
407
    * @param response is the response object linked to the client
408
    * @param conn the database connection 
409
    */
410
  private void handleSQuery(PrintWriter out, Hashtable params,  
411
                            HttpServletResponse response)    
412
  {  
413
    //create the squery and return it to be processed
414
    String doctype = null;
415
    String[] doctypeArr = null;
416
    Connection conn = null;
417
    doctypeArr = (String[])params.get("doctype");
418
    doctype = null;
419
    if (doctypeArr != null) 
420
    {
421
      doctype = ((String[])params.get("doctype"))[0]; 
422
    }
423
    else
424
    {
425
      doctype="ANY"; 
426
    }
427
    String xmlquery = DBQuery .createSQuery(params, doctype);
428
    Hashtable doclist = runQuery(xmlquery);
429
    String qformat = ((String[])params.get("qformat"))[0];
430
    String resultdoc = createResultDocument(doclist, qformat, xmlquery, 
431
                                            out, response);
432
    if(qformat.equals("html"))
433
    {
434
      transformResultset(resultdoc, response, out);
435
    }
436
    else if(qformat.equals("xml"))
437
    {
438
      response.setContentType("text/xml");
439
      out.println(resultdoc);
440
    }
441
    else
442
    {
443
      out.println("invalid qformat: " + qformat); 
444
    }
445
    //conn.close();
446
  }
447
  
448
   /**
449
    *Create the xml query, execute it and display the results.
450
    * @param out is the output stream to the client
451
    * @param params is the Hashtable of parameters that should be included
452
    * in the squery.
453
    * @param response is the response object linked to the client
454
    */ 
455
  private void handleQuery(PrintWriter out, Hashtable params, 
456
                           HttpServletResponse response)
457
  {
458
    String doctype=null; 
459
    String[] doctypeArr=null; 
460
    String query=null;
461
    Connection conn = null;
462
    
463
    if(params.containsKey("query"))
464
    { //get the query parameter
465
      query = ((String[])params.get("query"))[0];
466
    }
467
    else
468
    {
469
      query = ""; 
470
    }
471
    
472
    if(params.containsKey("doctype"))
473
    { //check for the doctype
474
      doctypeArr = (String[])params.get("doctype");
475
      doctype = null;
476
    }
477
    else
478
    {
479
      doctype = "ANY";  
480
    }
481
    
482
    if (doctypeArr != null) 
483
    {
484
      doctype = ((String[])params.get("doctype"))[0]; 
485
    }
486
    else
487
    {
488
      doctype="ANY"; 
489
    }
490
    
491
    //create the query and run it
492
    String xmlquery = DBQuery.createQuery(query, doctype);
493
    Hashtable doclist = runQuery(xmlquery);
494
    String qformat = ((String[])params.get("qformat"))[0]; 
495
    String resultdoc = createResultDocument(doclist, qformat, xmlquery, 
496
                                            out, response);
497
    //format and transform the results                                        
498
    if(qformat.equals("html"))
499
    {
500
      transformResultset(resultdoc, response, out);
501
    }
502
    else if(qformat.equals("xml"))
503
    {
504
      response.setContentType("text/xml");
505
      out.println(resultdoc);
506
    }
507
    else
508
    {
509
      out.println("invalid qformat: " + qformat); 
510
    }
511
    //conn.close();
512
  }
513
  
514
  /**
515
    * Run the query and return a hashtable of results.
516
    * @param xmlquery the query to run
517
    */
518
  private Hashtable runQuery(String xmlquery)
519
  {
520
    Hashtable doclist=null;
521
    Connection conn = null;
522
    try
523
    {
524
        conn = util.getConnection();
525
        DBQuery queryobj = new DBQuery(conn, saxparser);
526
        doclist = queryobj.findDocuments(new StringReader(xmlquery));
527
        util.returnConnection(conn);
528
        return doclist;
529
    } 
530
    catch (Exception e) 
531
    {
532
      if (conn != null) 
533
      {
534
        util.returnConnection(conn); 
535
      }
536
      util.debugMessage("Error in runQuery: " + e.getMessage());
537
      doclist = null;
538
      return doclist;
539
    }    
540
  }
541
  
542
   /**
543
   * Transorms an xml resultset document to html and sends it to the browser
544
   * @param resultdoc the string representation of the document that needs
545
   * to be transformed.
546
   * @param response the HttpServletResponse object bound to the client.
547
   * @param out the output stream to the client
548
   */
549
  private void transformResultset(String resultdoc, 
550
                                  HttpServletResponse response,
551
                                  PrintWriter out)
552
  {
553
    Connection conn = null;
554
    try
555
    {
556
      conn = util.getConnection();
557
      DBTransform trans = new DBTransform(conn);
558
      response.setContentType("text/html");
559
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN", 
560
                                 "-//W3C//HTML//EN", out);
561
    }
562
    catch(Exception e)
563
    {
564
      if (conn != null) 
565
      {
566
        util.returnConnection(conn); 
567
      }
568
    } 
569
    //conn.close();
570
  }
571
  
572
  /**
573
   * Transforms a hashtable of documents to an xml or html result.
574
   * @param doclist- the hashtable to transform
575
   * @param qformat- the format to transform the results into
576
   * @param xmlquery- the query that returned the dolist result
577
   * @param out- the printwriter object used to write to the client
578
   * @param response- the response stream to write back to the client.
579
   */
580
  private String createResultDocument(Hashtable doclist, String qformat, 
581
                                 String xmlquery, PrintWriter out,
582
                                 HttpServletResponse response)
583
  {
584
    // Create a buffer to hold the xml result
585
    StringBuffer resultset = new StringBuffer();
586
 
587
    // Print the resulting root nodes
588
    String docid = null;
589
    String document = null;
590
    resultset.append("<?xml version=\"1.0\"?>\n");
591
    resultset.append("<resultset>\n");
592
    //resultset.append("  <query>" + xmlquery + "</query>");   
593
    Enumeration doclistkeys = doclist.keys(); 
594
    while (doclistkeys.hasMoreElements()) 
595
    {
596
      docid = (String)doclistkeys.nextElement();
597
      document = (String)doclist.get(docid);
598
      resultset.append("  <document>" + document + "</document>");
599
    }
600
    resultset.append("</resultset>");
601
    return resultset.toString();
602
    /*
603
    if(qformat.equals("xml")) 
604
    {
605
      // set content type and other response header fields first
606
      response.setContentType("text/xml");
607
      out.println(resultset.toString());
608
    } 
609
    else if(qformat.equals("html")) 
610
    {
611
      // set content type and other response header fields first
612
      response.setContentType("text/html");
613
      XMLDocumentFragment htmldoc = null;
614
      try 
615
      {
616
        XSLStylesheet style = new XSLStylesheet(
617
                              new URL(resultStyleURL), null);
618
        htmldoc = (new XSLProcessor()).processXSL(style, 
619
                  (Reader)(new StringReader(resultset.toString())),null);
620
        htmldoc.print(out);
621
      } 
622
      catch (Exception e)   
623
      {
624
        out.println("Error transforming document:\n" + e.getMessage());
625
      }
626
    }
627
    */
628
  }
629

    
630
  /** 
631
   * Handle the database getdocument request and return a XML document, 
632
   * possibly transformed from XML into HTML
633
   */
634
  private void handleGetDocumentAction(PrintWriter out, Hashtable params, 
635
               HttpServletResponse response) 
636
               throws ClassNotFoundException, IOException, SQLException {
637
    String docidstr = null;
638
    String docid = null;
639
    String doc = null;
640
    Connection conn = null;
641
    
642
    try {
643
      // Find the document id number
644
      docidstr = ((String[])params.get("docid"))[0]; 
645
      //docid = (new Long(docidstr)).longValue();
646
      docid = docidstr;
647

    
648
      conn = util.getConnection();
649
      DBReader docreader = new DBReader(conn);
650
      DBTransform dbt = new DBTransform(conn);
651
      
652
      // Get the document indicated fromthe db
653
      doc = docreader.readXMLDocument(docid);
654

    
655
      // Return the document in XML or HTML format
656
      String qformat = ((String[])params.get("qformat"))[0]; 
657
      if (qformat.equals("xml")) {
658
        // set content type and other response header fields first
659
        response.setContentType("text/xml");
660
        out.println(doc);
661
      } else if (qformat.equals("html")) {
662
        // set content type and other response header fields first
663
        response.setContentType("text/html");
664

    
665
        // Look up the document type
666
        String sourcetype = docreader.getDoctypeInfo(docid).getDoctype();
667

    
668
        // Transform the document to the new doctype
669
        dbt.transformXMLDocument(doc, sourcetype, "-//W3C//HTML//EN", out);
670
      }
671
    //} catch (NullPointerException npe) {
672
      //response.setContentType("text/html");
673
      //out.println("Error getting document ID: " + docidstr +" (" + docid + ")");
674
    } catch (McdbException e) {
675
      response.setContentType("text/xml");
676
      e.toXml(out);
677
    } catch (Throwable t) {
678
      response.setContentType("text/html");
679
      out.println(t.getMessage());
680
    } finally {
681
      util.returnConnection(conn);
682
    }    
683

    
684
  }
685

    
686
  /** 
687
   * Handle the database putdocument request and write an XML document 
688
   * to the database connection
689
   */
690
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params, 
691
               HttpServletResponse response) {
692

    
693
    Connection conn = null;
694

    
695
    try {
696
      // Get the document indicated
697
      String[] doctext = (String[])params.get("doctext");
698
      StringReader xml = null;
699
      try {
700
        xml = new StringReader(doctext[0]);
701

    
702
        String[] action = (String[])params.get("action");
703
        String[] docid = (String[])params.get("docid");
704
        String newdocid = null;
705

    
706
        String doAction = null;
707
        if (action[0].equals("insert")) {
708
          doAction = "INSERT";
709
        } else if (action[0].equals("update")) {
710
          doAction = "UPDATE";
711
        }
712

    
713
        try {
714
            // get a connection from the pool
715
            conn = util.getConnection();
716
            // write the document to the database
717
            DBWriter dbw = new DBWriter(conn, saxparser);
718

    
719
            try {
720
                String accNumber = docid[0];
721
                if (accNumber.equals("")) {
722
                    accNumber = null;
723
                }
724
                newdocid = dbw.write(xml, doAction, accNumber);  
725
            } catch (NullPointerException npe) {
726
              newdocid = dbw.write(xml, doAction, null);  
727
            }
728
        } catch (Exception e) {
729
          response.setContentType("text/html");
730
          out.println(e.getMessage());
731
        } finally {
732
          util.returnConnection(conn);
733
        }    
734

    
735
        // set content type and other response header fields first
736
        response.setContentType("text/xml");
737
        out.println("<?xml version=\"1.0\"?>");
738
        out.println("<success>");
739
        out.println("<docid>" + newdocid + "</docid>"); 
740
        out.println("</success>");
741

    
742
      } catch (NullPointerException npe) {
743
        response.setContentType("text/xml");
744
        out.println("<?xml version=\"1.0\"?>");
745
        out.println("<error>");
746
        out.println(npe.getMessage()); 
747
        out.println("</error>");
748
      }
749
    } catch (Exception e) {
750
      response.setContentType("text/xml");
751
      out.println("<?xml version=\"1.0\"?>");
752
      out.println("<error>");
753
      out.println(e.getMessage()); 
754
      if (e instanceof SAXException) {
755
        Exception e2 = ((SAXException)e).getException();
756
        out.println("<error>");
757
        out.println(e2.getMessage()); 
758
        out.println("</error>");
759
      }
760
      //e.printStackTrace(out);
761
      out.println("</error>");
762
    }
763
  }
764

    
765
  /** 
766
   * Handle the database delete request and delete an XML document 
767
   * from the database connection
768
   */
769
  private void handleDeleteAction(PrintWriter out, Hashtable params, 
770
               HttpServletResponse response) {
771

    
772
    String[] docid = (String[])params.get("docid");
773
    Connection conn = null;
774

    
775
    // delete the document from the database
776
    try {
777
      // get a connection from the pool
778
      conn = util.getConnection();
779
      DBWriter dbw = new DBWriter(conn, saxparser);
780
                                      // NOTE -- NEED TO TEST HERE
781
                                      // FOR EXISTENCE OF PARAM
782
                                      // BEFORE ACCESSING ARRAY
783
      try {
784
        dbw.delete(docid[0]);
785
        response.setContentType("text/xml");
786
        out.println("<?xml version=\"1.0\"?>");
787
        out.println("<success>");
788
        out.println("Document deleted."); 
789
        out.println("</success>");
790
      } catch (AccessionNumberException ane) {
791
        response.setContentType("text/xml");
792
        out.println("<?xml version=\"1.0\"?>");
793
        out.println("<error>");
794
        out.println("Error deleting document!!!");
795
        out.println(ane.getMessage()); 
796
        out.println("</error>");
797
      }
798
    } catch (Exception e) {
799
      response.setContentType("text/xml");
800
      out.println("<?xml version=\"1.0\"?>");
801
      out.println("<error>");
802
      out.println(e.getMessage()); 
803
      out.println("</error>");
804
    } finally {
805
      util.returnConnection(conn);
806
    }  
807
  }
808
  
809
  /** 
810
   * Handle the validtion request and return the results to the requestor
811
   */
812
  private void handleValidateAction(PrintWriter out, Hashtable params, 
813
               HttpServletResponse response) {
814

    
815
    // Get the document indicated
816
    String valtext = null;
817
    
818
    try {
819
      valtext = ((String[])params.get("valtext"))[0];
820
    } catch (Exception nullpe) {
821

    
822
      Connection conn = null;
823
      String docid = null;
824
      try {
825
        // Find the document id number
826
        docid = ((String[])params.get("docid"))[0]; 
827

    
828
        // get a connection from the pool
829
        conn = util.getConnection();
830
        DBReader docreader = new DBReader(conn);
831
        // Get the document indicated from the db
832
        valtext = docreader.readXMLDocument(docid);
833

    
834
      } catch (NullPointerException npe) {
835
        response.setContentType("text/xml");
836
        out.println("<error>Error getting document ID: " + docid + "</error>");
837
        if ( conn != null ) { util.returnConnection(conn); }
838
        return; // Jivka added
839
      } catch (Exception e) {
840
        response.setContentType("text/html");
841
        out.println(e.getMessage()); 
842
      } finally {
843
        util.returnConnection(conn);
844
      }  
845
    }
846

    
847
    Connection conn = null;
848
    try {
849
      // get a connection from the pool
850
      conn = util.getConnection();
851
      DBValidate valobj = new DBValidate(saxparser,conn);
852
      boolean valid = valobj.validateString(valtext);
853

    
854
      // set content type and other response header fields first
855
      response.setContentType("text/xml");
856
      out.println(valobj.returnErrors());
857

    
858
    } catch (NullPointerException npe2) {
859
      // set content type and other response header fields first
860
      response.setContentType("text/xml");
861
      out.println("<error>Error validating document.</error>"); 
862
    } catch (Exception e) {
863
      response.setContentType("text/html");
864
      out.println(e.getMessage()); 
865
    } finally {
866
      util.returnConnection(conn);
867
    }  
868
  }
869

    
870
  /** 
871
   * Handle the document request and return the results 
872
   * to the requestor
873
   */
874
  private void handleGetDataDocumentAction(PrintWriter out, Hashtable params, 
875
               HttpServletResponse response) {
876
      boolean error_flag = false;
877
      String error_message = "";
878
      // Get the document indicated
879
      String[] datadoc = (String[])params.get("datadoc");
880
      // defaultdatapath = "C:\\Temp\\";    // for testing only!!!
881
      // executescript = "test.bat";        // for testing only!!!
882
      
883
      // set content type and other response header fields first
884
      response.setContentType("application/octet-stream");
885
      if (defaultdatapath!=null) {
886
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) {
887
          defaultdatapath=defaultdatapath+System.getProperty("file.separator");
888
        }
889
        System.out.println("Path= "+defaultdatapath+datadoc[0]);
890
        if (executescript!=null) {
891
          String command = null;
892
          File scriptfile = new File(executescript);
893
          if (scriptfile.exists()) {
894
            command=executescript+" "+datadoc[0]; // script includes path
895
        } else {     // look in defaultdatapath
896
            // on Win98 one MUST include the .bat extender
897
            command = defaultdatapath+executescript+" "+datadoc[0];  
898
        }
899
      System.out.println(command);
900
      try {
901
      Process proc = Runtime.getRuntime().exec(command);
902
      proc.waitFor();
903
      }
904
      catch (Exception eee) {
905
        System.out.println("Error running process!");
906
        error_flag = true;
907
        error_message = "Error running process!";}
908
      } // end executescript not null if
909
      File datafile = new File(defaultdatapath+datadoc[0]);
910
      try {
911
      FileInputStream fw = new FileInputStream(datafile);
912
      int x;
913
      while ((x = fw.read())!=-1) {
914
        out.write(x); }
915
        fw.close();
916
      } catch (Exception e) {
917
        System.out.println("Error in returning file\n"+e.getMessage());
918
        error_flag=true;
919
        error_message = error_message+"\nError in returning file\n"+
920
                        e.getMessage();
921
      }
922
    } // end defaultdatapath not null if
923
  }
924
  
925
  /** 
926
   * Handle the getdoctypes Action.
927
   * Read all doctypes from db connection in XML format
928
   */
929

    
930
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params, 
931
                                       HttpServletResponse response) {
932

    
933
    Connection conn = null;
934
    
935
    try {
936

    
937
        // get connection from the pool
938
        conn = util.getConnection();
939
        DBUtil dbutil = new DBUtil(conn);
940
        String doctypes = dbutil.readDoctypes();
941
        out.println(doctypes);
942

    
943
    } catch (Exception e) {
944
      out.println("<?xml version=\"1.0\"?>");
945
      out.println("<error>");
946
      out.println(e.getMessage());
947
      out.println("</error>");
948
    } finally {
949
      util.returnConnection(conn);
950
    }  
951
    
952
  }
953

    
954
  /** 
955
   * Handle the getdataguide Action.
956
   * Read Data Guide for a given doctype from db connection in XML format
957
   */
958

    
959
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
960
                                        HttpServletResponse response) {
961

    
962
    Connection conn = null;
963
    String doctype = null;
964
    String[] doctypeArr = (String[])params.get("doctype");
965

    
966
    // get only the first doctype specified in the list of doctypes
967
    // it could be done for all doctypes in that list
968
    if (doctypeArr != null) {
969
        doctype = ((String[])params.get("doctype"))[0]; 
970
    }
971

    
972
    try {
973

    
974
        // get connection from the pool
975
        conn = util.getConnection();
976
        DBUtil dbutil = new DBUtil(conn);
977
        String dataguide = dbutil.readDataGuide(doctype);
978
        out.println(dataguide);
979

    
980
    } catch (Exception e) {
981
      out.println("<?xml version=\"1.0\"?>");
982
      out.println("<error>");
983
      out.println(e.getMessage());
984
      out.println("</error>");
985
    } finally {
986
      util.returnConnection(conn);
987
    }  
988
    
989
  }
990

    
991
}
992

    
993
/**
994
 * '$Log$
995
 * 'Revision 1.71  2000/08/15 20:48:05  berkley
996
 * 'remove handleQueryAction() in favor of directly calling handleQuery() and handleSQuery() from doGetOrPost()
997
 * '
998
 * 'Revision 1.70  2000/08/15 20:02:15  bojilova
999
 * 'Cleared hardcoded paths for the location of .html files and use
1000
 * 'the new "htmlpath" property from metacat.properties file
1001
 * '
1002
 * 'Revision 1.69  2000/08/15 15:58:03  berkley
1003
 * 'Added decodeMouseAction(Hashtable) to decode the mouse click action outside of handleGetOrPost to allow for easy modification of images in a different application.
1004
 * '
1005
 * 'Revision 1.68  2000/08/14 21:28:54  berkley
1006
 * 'Broke up handleQueryAction into handleQuery, handleSQuery, runQuery and transformDocument.  handleQueryAction is now a base function which makes calls to each of these functions to create, run and transform a query from CGI parameters.
1007
 * '
1008
 * 'Revision 1.67  2000/08/14 20:43:27  jones
1009
 * 'Updated build process to now use a copy of the source files so that keyword
1010
 * 'substitution can ocur before the build.  This allows for substitution of
1011
 * 'hardcoded values into the source before the compile.  Currently, I am
1012
 * 'using this feature to do the following:
1013
 * '
1014
 * '	1) Substitute a "Release" number into the code
1015
 * '	2) Substitute a hardcoded servlet path into the code and html files
1016
 * '
1017
 * 'By changing the value of "servlet-path" and "installdir" properties in
1018
 * 'build.xml, one can now easily install a new version of the servlet in a
1019
 * 'different location by simply using "ant install".
1020
 * '
1021
 * 'Revision 1.66  2000/08/14 18:27:37  bojilova
1022
 * 'added Logout handling
1023
 * '
1024
 * 'Revision 1.64  2000/08/11 22:20:04  jones
1025
 * 'Changed exception handling mechanisms for DBReader
1026
 * '
1027
 * 'Revision 1.63  2000/08/11 18:25:26  berkley
1028
 * 'broke up handleQueryAction into handleQuery, handleSQuery, runQuery and transformDocument
1029
 * '
1030
 * 'Revision 1.61  2000/08/10 18:56:48  bojilova
1031
 * 'added "anonymous" user connection
1032
 * '
1033
 * 'Revision 1.60  2000/08/09 00:39:47  jones
1034
 * '-Reorganized xmltodb module to support new install process for the new
1035
 * 'linux server (dev.nceas.ucsb.edu).  Added "build.sh" shell script that
1036
 * 'calls ant withthe proper umask set for installation.  Use:
1037
 * '
1038
 * '  ./build.sh install
1039
 * '
1040
 * 'to post a new copy of the servlet and its supporting files to the install
1041
 * 'directory defined in build.xml.
1042
 * '
1043
 * '-Updated the servlet to use a new servlet prefix that we'll use with the
1044
 * 'Tomcat servlet engine.
1045
 * '
1046
 * '-Update bin dir shell scripts to reflect new locations of relevant jar files.
1047
 * '
1048
 * 'Revision 1.59  2000/08/08 00:31:20  bojilova
1049
 * 'rearrange html pages for login and metacat access
1050
 * '
1051
 * 'Revision 1.58  2000/08/04 23:34:09  bojilova
1052
 * 'more precise handling of the Connection Pool
1053
 * '
1054
 * 'Revision 1.57  2000/08/03 23:20:31  bojilova
1055
 * 'Changes related to "getdataguide" action
1056
 * '
1057
 * 'Revision 1.55  2000/08/01 18:26:50  bojilova
1058
 * 'added Pool of Connections
1059
 * 'DBQuery, DBReader, DBTransform, DBUtil are created on every request and use the connections from the Pool
1060
 * 'same with DBWriter and DBValidate
1061
 * '
1062
 * 'Revision 1.54  2000/07/27 23:12:21  bojilova
1063
 * 'Added "getdoctypes" and "getdataguide" action handlers
1064
 * '
1065
 * 'Revision 1.53  2000/07/26 20:48:29  bojilova
1066
 * 'Added "Login Client" action for login from the Desktop Client
1067
 * '
1068
 * 'Revision 1.52  2000/07/26 20:38:40  higgins
1069
 * 'no message
1070
 * '
1071
 * 'Revision 1.51  2000/07/01 01:09:44  jones
1072
 * 'MetaCatServlet.java
1073
 * '
1074
 * 'Revision 1.50  2000/06/30 23:42:33  bojilova
1075
 * 'finished user auth & session tracking
1076
 * '
1077
 * 'Revision 1.49  2000/06/29 23:27:08  jones
1078
 * 'Fixed bug in DBEntityResolver so that it now properly delegates to
1079
 * 'the system id found inthe database.
1080
 * 'Changed DBValidate to use DBEntityResolver, rather than the OASIS
1081
 * 'catalog, and to return validation results in XML format.
1082
 * '
1083
 * 'Revision 1.48  2000/06/29 20:04:51  bojilova
1084
 * 'testing login
1085
 * '
1086
 * 'Revision 1.36  2000/06/28 02:36:26  jones
1087
 * 'Added feature to now ouput COMMENTs and PIs when the document is
1088
 * 'read from the database with DBReader.
1089
 * '
1090
 * 'Revision 1.35  2000/06/28 00:00:47  bojilova
1091
 * 'changed to
1092
 * 'response.sendRedirect(response.encodeRedirectUrl("/xmltodb/lib/index.html"));
1093
 * '
1094
 * 'Revision 1.33  2000/06/27 04:50:33  jones
1095
 * 'Updated javadoc documentation.
1096
 * '
1097
 * 'Revision 1.32  2000/06/27 04:31:07  jones
1098
 * 'Fixed bugs associated with the new UPDATE and DELETE functions of
1099
 * 'DBWriter.  There were problematic interactions between some static
1100
 * 'variables used in DBEntityResolver and the way in which the
1101
 * 'Servlet objects are re-used across multiple client invocations.
1102
 * '
1103
 * 'Generally cleaned up error reporting.  Now all errors and success
1104
 * 'results are reported as XML documents from MetaCatServlet.  Need
1105
 * 'to make the command line tools do the same.
1106
 * '
1107
 * 'Revision 1.31  2000/06/26 10:35:05  jones
1108
 * 'Merged in substantial changes to DBWriter and associated classes and to
1109
 * 'the MetaCatServlet in order to accomodate the new UPDATE and DELETE
1110
 * 'functions.  The command line tools and the parameters for the
1111
 * 'servlet have changed substantially.
1112
 * '
1113
 * 'Revision 1.30.2.6  2000/06/26 10:18:06  jones
1114
 * 'Partial fix for MetaCatServlet INSERT?UPDATE bug.  Only will work on
1115
 * 'the first call to the servlet.  Subsequent calls fail.  Seems to be
1116
 * 'related to exception handling.  Multiple successive DELETE actions
1117
 * 'work fine.
1118
 * '
1119
 * 'Revision 1.30.2.5  2000/06/26 09:09:53  jones
1120
 * 'Modified MetaCatServlet and associated files to handle the UPDATE
1121
 * 'and DELETE actions for DBWriter.
1122
 * '
1123
 * 'Revision 1.30.2.4  2000/06/26 00:51:06  jones
1124
 * 'If docid passed to DBWriter.write() is not unique, classes now generate
1125
 * 'an AccessionNumberException containing the new docid generated as a
1126
 * 'replacement.  The docid is then extracted from the exception and
1127
 * 'returned to the calling application for user feedback or client processing.
1128
 * '
1129
 * 'Revision 1.30.2.3  2000/06/25 23:38:17  jones
1130
 * 'Added RCSfile keyword
1131
 * '
1132
 * 'Revision 1.30.2.2  2000/06/25 23:34:18  jones
1133
 * 'Changed documentation formatting, added log entries at bottom of source files
1134
 * ''
1135
 */
(21-21/27)