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: bojilova $'
10
 *     '$Date: 2000-09-20 13:25:39 -0700 (Wed, 20 Sep 2000) $'
11
 * '$Revision: 462 $'
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.io.FileOutputStream;
24
import java.io.InputStreamReader;
25
import java.io.DataInputStream;
26
import java.util.Enumeration;
27
import java.util.Hashtable;
28
import java.util.ResourceBundle; 
29
import java.util.PropertyResourceBundle;
30
import java.net.URL;
31
import java.net.MalformedURLException;
32
import java.sql.PreparedStatement;
33
import java.sql.ResultSet;
34
import java.sql.Connection;
35
import java.sql.SQLException;
36
import java.lang.reflect.*;
37
import java.net.*;
38
import java.util.zip.*;
39

    
40
import javax.servlet.ServletConfig;
41
import javax.servlet.ServletContext;
42
import javax.servlet.ServletException;
43
import javax.servlet.ServletInputStream;
44
import javax.servlet.http.HttpServlet;
45
import javax.servlet.http.HttpServletRequest;
46
import javax.servlet.http.HttpServletResponse;
47
import javax.servlet.http.HttpSession;
48
import javax.servlet.http.HttpUtils;
49
import javax.servlet.ServletOutputStream;
50

    
51
import oracle.xml.parser.v2.XSLStylesheet;
52
import oracle.xml.parser.v2.XSLException;
53
import oracle.xml.parser.v2.XMLDocumentFragment;
54
import oracle.xml.parser.v2.XSLProcessor;
55

    
56
import org.xml.sax.SAXException;
57

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

    
88
  private ServletConfig config = null;
89
  private ServletContext context = null;
90
  private Hashtable connectionPool = new Hashtable();
91
  private String resultStyleURL = null;
92
  private String xmlcatalogfile = null;
93
  private String saxparser = null;
94
  private String defaultdatapath = null; 
95
  private String servletpath = null; 
96
  private PropertyResourceBundle options = null;
97
  private MetaCatUtil util = null;
98

    
99
  // path to directory where data files 
100
  // that can be downloaded will be stored
101
  private String htmlpath = null; 
102
  // script to get data file and put it 
103
  // in defaultdocpath dir
104
  private String executescript  = null;  
105

    
106

    
107
  /**
108
   * Initialize the servlet by creating appropriate database connections
109
   */
110
  public void init( ServletConfig config ) throws ServletException {
111
    try {
112
      super.init( config );
113
      this.config = config;
114
      this.context = config.getServletContext(); 
115
      System.out.println("MetaCatServlet Initialize");
116

    
117
      util = new MetaCatUtil();
118

    
119
      // Get the configuration file information
120
      resultStyleURL = util.getOption("resultStyleURL");
121
      xmlcatalogfile = util.getOption("xmlcatalogfile");
122
      saxparser = util.getOption("saxparser");
123
      defaultdatapath = util.getOption("defaultdatapath");
124
      executescript = util.getOption("executescript");
125
      servletpath = util.getOption("servletpath");
126
      htmlpath = util.getOption("htmlpath");
127

    
128
      try {
129
        // Open a pool of db connections
130
        connectionPool = util.getConnectionPool();
131
      } catch (Exception e) {
132
        System.err.println("Error creating pool of database connections");
133
        System.err.println(e.getMessage());
134
      }
135
    } catch ( ServletException ex ) {
136
      throw ex;
137
    }
138
  }
139

    
140
  /**
141
   * Close all db connections from the pool
142
   */
143
  public void destroy() {
144
    
145
    if (util != null) {
146
        util.closeConnections();
147
    }
148
  }
149

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

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

    
158
  /** Handle "POST" method requests from HTTP clients */
159
  public void doPost( HttpServletRequest request, HttpServletResponse response)
160
    throws ServletException, IOException {
161

    
162
    // Process the data and send back the response
163
    handleGetOrPost(request, response);
164
  }
165

    
166
  /**
167
   * Control servlet response depending on the action parameter specified
168
   */
169
  private void handleGetOrPost(HttpServletRequest request, 
170
    HttpServletResponse response) 
171
    throws ServletException, IOException 
172
 {
173

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

    
199
      // Decode the docid and mouse click information
200
      if (name.endsWith(".y")) {
201
        docid[0] = name.substring(0,name.length()-2);
202
        //out.println("docid => " + docid[0]);
203
        params.put("docid", docid);
204
        name = "ypos";
205
      }
206
      if (name.endsWith(".x")) {
207
        name = "xpos";
208
      } 
209

    
210
      //out.println(name + " => " + value[0]);
211
      params.put(name,value); 
212
    }  
213
    
214
    //if the user clicked on the input images, decode which image
215
    //was clicked then set the action.
216
    String action = decodeMouseAction(params);
217
    if(action.equals("error"))
218
    {
219
      action = ((String[])params.get("action"))[0];  
220
    }
221
    
222
    // This block handles session management for the servlet
223
    // by looking up the current session information for all actions
224
    // other than "Login" and "Logout"
225
    // handle login action
226
    String username = null;
227
    String groupname = null;
228
    if (action.equals("Login") || action.equals("Login Client")) {
229
      handleLoginAction(response.getWriter(), params, request, response);
230
    // handle logout action  
231
    } else if (action.equals("Logout") || action.equals("Logout Client")) {
232
      HttpSession sess = request.getSession(false);
233
      if (sess != null) { sess.invalidate();  }    
234
      if (action.equals("Logout Client")) {
235
        PrintWriter out = response.getWriter();
236
        out.println("<?xml version=\"1.0\"?>");
237
        out.println("<success>");
238
        out.println("User logout.");
239
        out.println("</success>");
240
        return;
241
      }    
242

    
243
      response.sendRedirect(htmlpath + "/index.html"); 
244

    
245
    // aware of session expiration on every request  
246
    } else {   
247
      HttpSession sess = request.getSession(true);
248
      if (sess.isNew()) { 
249
        // session expired or has not been stored b/w user requests
250
        // redirect to default page for query only access
251
        //  response.sendRedirect(htmlpath + "/sexpire.html");
252
        username = "public";
253
      } else {
254
        username = (String)sess.getAttribute("username");
255
        groupname = (String)sess.getAttribute("groupname");
256
      }  
257
    }    
258

    
259
    // Now that we know the session is valid, we can delegate the request
260
    // to a particular action handler
261
    if(action.equals("query"))
262
    {
263
      handleQuery(response.getWriter(), params, response, username, groupname); 
264
    } 
265
    else if(action.equals("squery"))
266
    {
267
      if(params.containsKey("query"))
268
      {
269
        handleSQuery(response.getWriter(), params, response, username, groupname); 
270
      }
271
      else
272
      {
273
        PrintWriter out = response.getWriter();
274
        out.println("Illegal action squery without \"query\" parameter");
275
      }
276
    }
277
    else if (action.equals("getdocument")) {
278
      PrintWriter out = response.getWriter();
279
      try {
280
        handleGetDocumentAction(out, params, response);
281
      } catch (ClassNotFoundException e) {
282
        out.println(e.getMessage());
283
      } catch (SQLException se) {
284
        out.println(se.getMessage());
285
      }
286
    } 
287
    else if (action.equals("getrelateddocument")) {
288
      PrintWriter out = response.getWriter();
289
      try {
290
        handleGetRelatedDocumentAction(out, params, response);
291
      } catch (ClassNotFoundException e) {
292
        out.println(e.getMessage());
293
      } catch (SQLException se) {
294
        out.println(se.getMessage());
295
      }
296
    }
297
    else if (action.equals("insert") || action.equals("update")) {
298
      PrintWriter out = response.getWriter();
299
      if ( !username.equals("public") && (username != null) ) {
300
        handleInsertOrUpdateAction(out, params, response, username, groupname);
301
      } else {  
302
        out.println("Permission denied for " + action);
303
      }  
304
    } else if (action.equals("delete")) {
305
      PrintWriter out = response.getWriter();
306
      if ( !username.equals("public") && (username != null) ) {
307
        handleDeleteAction(out, params, response, username, groupname);
308
      } else {  
309
        out.println("Permission denied for " + action);
310
      }  
311
    } else if (action.equals("validate")) {
312
      PrintWriter out = response.getWriter();
313
      handleValidateAction(out, params, response); 
314
    } else if (action.equals("getabstract")) {
315
      PrintWriter out = response.getWriter();
316
      try{
317
        handleViewAbstractAction(out, params, response);
318
      }
319
      catch(Exception e)
320
      {
321
        out.println("error viewing abstract: " + e.getMessage());
322
      }
323
    } else if (action.equals("getdatadoc")) {
324
      response.setContentType("application/zip");
325
      ServletOutputStream out = response.getOutputStream();
326
      handleGetDataDocumentAction(out, params, response);  
327
    } else if (action.equals("getdoctypes")) {
328
      PrintWriter out = response.getWriter();
329
      handleGetDoctypesAction(out, params, response);  
330
    } else if (action.equals("getdataguide")) {
331
      PrintWriter out = response.getWriter();
332
      handleGetDataGuideAction(out, params, response);  
333
    } else if (action.equals("Login") || action.equals("Login Client")) {
334
    } else {
335
      PrintWriter out = response.getWriter();
336
      out.println("Error: action not registered.  Please report this error.");
337
    }
338

    
339
    // Close the stream to the client
340
    //out.close();
341
  }
342
  
343
  /**
344
   * decodes the mouse click information coming from the client.
345
   * This function may be overwritten to provide specific functionality
346
   * for different applications.
347
   * @param params the parameters from the CGI
348
   * @return action the action to be performed or "error" if an error was
349
   * generated
350
   */
351
  protected String decodeMouseAction(Hashtable params)
352
  {
353
    // Determine what type of request the user made
354
    // if the action parameter is set, use it as a default
355
    // but if the ypos param is set, calculate the action needed
356
    String action=null;
357
    long ypos = 0;
358
    try {
359
      ypos = (new Long(((String[])params.get("ypos"))[0]).longValue());
360
      //out.println("<P>YPOS IS " + ypos);
361
      if (ypos <= 13) {
362
        action = "getdocument";
363
      } else if (ypos > 13 && ypos <= 27) {
364
        action = "validate";
365
      } else if (ypos > 27) {
366
        action = "transform";
367
      }
368
      return action;
369
    } catch (Exception npe) {
370
      //
371
      // MBJ -- NOTE that this should be handled more gracefully with
372
      //        the new exception infrastructure -- this "error" return
373
      //        value is inappropriate
374
      //out.println("<P>Caught exception looking for Y value.");
375
      return "error";
376
    }  
377
  }
378

    
379
  /** 
380
   * Handle the Login request. Create a new session object.
381
   * Make a user authentication through SRB RMI Connection.
382
   */
383
  private void handleLoginAction(PrintWriter out, Hashtable params, 
384
               HttpServletRequest request, HttpServletResponse response) {
385

    
386
    MetaCatSession sess = null;
387
    String un = ((String[])params.get("username"))[0];
388
    String pw = ((String[])params.get("password"))[0];
389
    String action = ((String[])params.get("action"))[0];
390
    
391
    try {
392
        sess = new MetaCatSession(request, un, pw);
393
    } catch (Exception e) {
394
      out.println(e.getMessage());
395
    }
396
    
397
    String output = null;
398
    output = sess.userLogin(response, un, pw, action, htmlpath);
399
    out.println(output);
400

    
401
  }    
402
  
403
  /**      
404
   * Retreive the squery xml, execute it and display it
405
   *
406
   * @param out the output stream to the client
407
   * @param params the Hashtable of parameters that should be included
408
   * in the squery.
409
   * @param response the response object linked to the client
410
   * @param conn the database connection 
411
   */
412
  protected void handleSQuery(PrintWriter out, Hashtable params, 
413
                 HttpServletResponse response, String user, String group)
414
  { 
415
    String xmlquery = ((String[])params.get("query"))[0];
416
    String qformat = ((String[])params.get("qformat"))[0];
417
    Hashtable doclist = runQuery(xmlquery, user, group);
418
    String resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
419

    
420
    //format and transform the results                                        
421
    if(qformat.equals("html")) {
422
      transformResultset(resultdoc, response, out);
423
    } else if(qformat.equals("xml")) {
424
      response.setContentType("text/xml");
425
      out.println(resultdoc);
426
    } else {
427
      out.println("invalid qformat: " + qformat); 
428
    }
429
  }
430
  
431
   /**
432
    * Create the xml query, execute it and display the results.
433
    *
434
    * @param out the output stream to the client
435
    * @param params the Hashtable of parameters that should be included
436
    * in the squery.
437
    * @param response the response object linked to the client
438
    */ 
439
  protected void handleQuery(PrintWriter out, Hashtable params, 
440
                 HttpServletResponse response, String user, String group)
441
  {
442
    //create the query and run it
443
    String xmlquery = DBQuery.createSQuery(params);
444
    Hashtable doclist = runQuery(xmlquery, user, group);
445
    String qformat = ((String[])params.get("qformat"))[0]; 
446
    String resultdoc = createResultDocument(doclist, transformQuery(params));
447

    
448
    //format and transform the results                                        
449
    if(qformat.equals("html")) {
450
      transformResultset(resultdoc, response, out);
451
    } else if(qformat.equals("xml")) {
452
      response.setContentType("text/xml");
453
      out.println(resultdoc);
454
    } else { 
455
      out.println("invalid qformat: " + qformat); 
456
    }
457
  }
458
  
459
  /**
460
   * Removes the <?xml version="x"?> tag from the beginning of xmlquery
461
   * so it can properly be placed in the <query> tag of the resultset.
462
   * This method is overwritable so that other applications can customize
463
   * the structure of what is in the <query> tag.
464
   * 
465
   * @param xmlquery is the query to remove the <?xml version="x"?> tag from.
466
   */
467
  protected String transformQuery(Hashtable params)
468
  {
469
    //DBQuery.createSQuery is a re-calling of a previously called 
470
    //function but it is necessary
471
    //so that overriding methods have access to the params hashtable
472
    String xmlquery = DBQuery.createSQuery(params);
473
    //the <?xml version="1.0"?> tag is the first 22 characters of the
474
    xmlquery = xmlquery.trim();
475
    int index = xmlquery.indexOf("?>");
476
    return xmlquery.substring(index + 2, xmlquery.length());
477
  }
478
  
479
  /**
480
   * removes the <?xml version="1.0"?> tag from the beginning.  This takes a
481
   * string as a param instead of a hashtable.
482
   * 
483
   * @param xmlquery a string representing a query.
484
   */
485
  protected String transformQuery(String xmlquery)
486
  {
487
    xmlquery = xmlquery.trim();
488
    int index = xmlquery.indexOf("?>");
489
    return xmlquery.substring(index + 2, xmlquery.length());
490
  }
491
  
492
  /**
493
   * Run the query and return a hashtable of results.
494
   *
495
   * @param xmlquery the query to run
496
   */
497
  private Hashtable runQuery(String xmlquery, String user, String group)
498
  {
499
    Hashtable doclist=null;
500
    Connection conn = null;
501
    try
502
    {
503
      conn = util.getConnection();
504
      DBQuery queryobj = new DBQuery(conn, saxparser);
505
      doclist = queryobj.findDocuments(new StringReader(xmlquery),user,group);
506
      util.returnConnection(conn);
507
      return doclist;
508
    } 
509
    catch (Exception e) 
510
    {
511
      util.returnConnection(conn); 
512
      util.debugMessage("Error in runQuery: " + e.getMessage());
513
      doclist = null;
514
      return doclist;
515
    }    
516
  }
517
  
518
  /**
519
   * Transorms an xml resultset document to html and sends it to the browser
520
   *
521
   * @param resultdoc the string representation of the document that needs
522
   * to be transformed.
523
   * @param response the HttpServletResponse object bound to the client.
524
   * @param out the output stream to the client
525
   */ 
526
  protected void transformResultset(String resultdoc, 
527
                                    HttpServletResponse response,
528
                                    PrintWriter out)
529
  {
530
    Connection conn = null;
531
    try {
532
      conn = util.getConnection();
533
      DBTransform trans = new DBTransform(conn);
534
      response.setContentType("text/html");
535
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN", 
536
                                 "-//W3C//HTML//EN", out);
537
      util.returnConnection(conn); 
538
    }
539
    catch(Exception e)
540
    {
541
      util.returnConnection(conn); 
542
    } 
543
  }
544
  
545
  /**
546
   * Transforms a hashtable of documents to an xml or html result.
547
   *
548
   * @param doclist- the hashtable to transform
549
   * @param xmlquery- the query that returned the dolist result
550
   */
551
  protected String createResultDocument(Hashtable doclist, String xmlquery)
552
  {
553
    // Create a buffer to hold the xml result
554
    StringBuffer resultset = new StringBuffer();
555
 
556
    // Print the resulting root nodes 
557
    String docid = null;
558
    String document = null;
559
    resultset.append("<?xml version=\"1.0\"?>\n");
560
    resultset.append("<resultset>\n");
561
    
562
    resultset.append("  <query>" + xmlquery + "</query>");   
563
 
564
    Enumeration doclistkeys = doclist.keys(); 
565
    while (doclistkeys.hasMoreElements()) 
566
    {
567
      docid = (String)doclistkeys.nextElement();
568
      document = (String)doclist.get(docid);
569
      resultset.append("  <document>" + document + "</document>");
570
    } 
571
    resultset.append("</resultset>");
572
    //System.out.println(resultset.toString());
573
    return resultset.toString();
574
  }
575
  
576
  /**
577
   * Handle the request to view the abstract of a document.
578
   * The abstractpath CGI parameter gives the xml path to the abstract
579
   * node.  
580
   */
581
  private void handleViewAbstractAction(PrintWriter out, Hashtable params,
582
               HttpServletResponse response) throws IOException, SQLException
583
  {
584
    String abstractpath = null;
585
    String docid = null;
586
    Connection conn = null;
587
    response.setContentType("text/html");
588
    try
589
    {
590
      docid = ((String[])params.get("docid"))[0];
591
      if(params.containsKey("abstractpath"))
592
      {
593
        //the CGI parameter abstractpath holds the path to the abstract
594
        //that should be displayed.
595
        abstractpath = ((String[])params.get("abstractpath"))[0];
596
      }
597
      else
598
      {
599
        out.println("error: no abstractpath parameter"); 
600
      }
601
      conn = util.getConnection();
602
    
603
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid, conn);
604
    
605
      out.println("<html><head><title>Abstract</title></head>");
606
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
607
      for(int i=0; i<abstracts.length; i++)
608
      {
609
        out.println("<p>" + (String)abstracts[i] + "</p>");
610
      }
611
      out.println("</body></html>");
612
    }
613
    catch (IOException ioe)
614
    {
615
       util.debugMessage("error in handlegetabstract: " + ioe.getMessage());
616
    }
617
    catch(SQLException sqle)
618
    {
619
      util.debugMessage("error in handlegetabstract: " + sqle.getMessage()); 
620
    }
621
    catch(Exception e)
622
    {
623
      util.debugMessage("error in handlegetabstract: " + e.getMessage());
624
    }
625
    
626
    util.returnConnection(conn);
627
  }
628

    
629
  /** 
630
   * Handle the database getrelateddocument request and return a XML document, 
631
   * possibly transformed from XML into HTML
632
   */
633
  private void handleGetRelatedDocumentAction(PrintWriter out, Hashtable params, 
634
               HttpServletResponse response) 
635
               throws ClassNotFoundException, IOException, SQLException 
636
  {
637
    String docid = null;
638
    Connection conn = null;
639
      
640
    if(params.containsKey("url"))
641
    {//the identifier for the related document is contained in the URL param
642
      try
643
      {
644
        DocumentImpl xmldoc=null;
645
        metacatURL murl = new metacatURL(((String[])params.get("url"))[0]);
646
        if(murl.getURLType().equals("metacat"))
647
        {//get the document from the database if it is the right type of url
648
          String[] murlParams = murl.getParam(0);
649
          if(murlParams[0].equals("docid"))
650
          {//the docid should be first
651
            murl.printParams();
652
            docid = murlParams[1]; //get the docid value
653
            conn = util.getConnection();
654
            xmldoc = new DocumentImpl(conn, docid);
655
            
656
            //**************************************************
657
            //the style sheet handling code needs to be put here. 
658
            out.println(xmldoc.toString());
659
            //**************************************************
660
          }
661
          else
662
          {
663
            //throw new Exception("handleGetDocument: bad URL");
664
            System.err.println("handleGetDocument: bad URL");
665
          }
666
        }
667
        else if(murl.getURLType().equals("http"))
668
        {//get the document from the internet
669
          String[] murlParams = murl.getParam(0);
670
          if(murlParams[0].equals("httpurl"))
671
          {//httpurl is the param name for an http url.
672
            URL urlconn = new URL(murlParams[1]);  //create a new url obj.
673
            //DataInputStream htmldoc = new DataInputStream(urlconn.openStream());
674
            BufferedReader htmldoc = new BufferedReader(
675
                                   new InputStreamReader(urlconn.openStream()));
676
            //bind a data stream.
677
            try
678
            { //display the document
679
              String line=null;
680
              while((line = htmldoc.readLine()) != null)
681
              {
682
                out.println(line); 
683
              }
684
            }
685
            catch(Exception e)
686
            {
687
              util.debugMessage("error viewing html document"); 
688
            }
689
          }
690
        }
691
      }
692
      catch (McdbException e) {
693
        response.setContentType("text/xml");
694
        e.toXml(out);
695
      } catch   (Throwable t) {
696
        response.setContentType("text/html");
697
        out.println(t.getMessage());
698
      } finally {
699
        util.returnConnection(conn);
700
      }
701
    }
702
  }   
703
  
704
  /** 
705
   * Handle the database getdocument request and return a XML document, 
706
   * possibly transformed from XML into HTML
707
   */
708
  private void handleGetDocumentAction(PrintWriter out, Hashtable params, 
709
               HttpServletResponse response) 
710
               throws ClassNotFoundException, IOException, SQLException {
711
    String docidstr = null;
712
    String docid = null;
713
    String doc = null;
714
    Connection conn = null;
715
    
716
    try {
717
      // Find the document id number
718
      docidstr = ((String[])params.get("docid"))[0]; 
719
      docid = docidstr;
720
      conn = util.getConnection();
721
      DocumentImpl xmldoc = new DocumentImpl(conn, docid);
722
      // Get the document indicated from the db
723
      //doc = docreader.readXMLDocument(docid);
724

    
725
      // Return the document in XML or HTML format
726
      String qformat=null;
727
      if(params.containsKey("qformat"))
728
      {
729
        qformat = ((String[])params.get("qformat"))[0];
730
      }
731
      else
732
      {
733
        qformat = "html";        
734
      }
735
      if (qformat.equals("xml")) { 
736
        // set content type and other response header fields first
737
        response.setContentType("text/xml");
738
        xmldoc.toXml(out);
739
        //out.println(xmldoc);
740
      } else if (qformat.equals("html")) {
741
        response.setContentType("text/html");
742
        // Look up the document type
743
        String sourcetype = xmldoc.getDoctype();
744
        // Transform the document to the new doctype
745
        DBTransform dbt = new DBTransform(conn);
746
        dbt.transformXMLDocument(xmldoc.toString(), sourcetype, 
747
                                 "-//W3C//HTML//EN", out);
748
      }
749
    } catch (McdbException e) {
750
      response.setContentType("text/xml");
751
      e.toXml(out);
752
    } catch (Throwable t) {
753
      response.setContentType("text/html");
754
      out.println(t.getMessage());
755
    } finally {
756
      util.returnConnection(conn);
757
    }    
758

    
759
  }
760

    
761
  /** 
762
   * Handle the database putdocument request and write an XML document 
763
   * to the database connection
764
   */
765
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params, 
766
               HttpServletResponse response, String user, String group) {
767

    
768
    Connection conn = null;
769

    
770
    try {
771
      // Get the document indicated
772
      String[] doctext = (String[])params.get("doctext");
773
      StringReader xml = null;
774
      try {
775
        xml = new StringReader(doctext[0]);
776

    
777
        String[] action = (String[])params.get("action");
778
        String[] docid = (String[])params.get("docid");
779
        String newdocid = null;
780

    
781
        String doAction = null;
782
        if (action[0].equals("insert")) {
783
          doAction = "INSERT";
784
        } else if (action[0].equals("update")) {
785
          doAction = "UPDATE";
786
        }
787

    
788
        try {
789
            // get a connection from the pool
790
            conn = util.getConnection();
791

    
792
            // write the document to the database
793
            try {
794
                String accNumber = docid[0];
795
                if (accNumber.equals("")) {
796
                    accNumber = null;
797
                }
798
                newdocid = DocumentImpl.write(conn, xml, doAction, accNumber, 
799
                                                                  user, group);
800
            } catch (NullPointerException npe) {
801
              newdocid = DocumentImpl.write(conn,xml,doAction,null,user,group);
802
            }
803
//        } catch (Exception e) {
804
//          response.setContentType("text/html");
805
//          out.println(e.getMessage());
806
        } finally {
807
          util.returnConnection(conn);
808
        }    
809

    
810
        // set content type and other response header fields first
811
        response.setContentType("text/xml");
812
        out.println("<?xml version=\"1.0\"?>");
813
        out.println("<success>");
814
        out.println("<docid>" + newdocid + "</docid>"); 
815
        out.println("</success>");
816

    
817
      } catch (NullPointerException npe) {
818
        response.setContentType("text/xml");
819
        out.println("<?xml version=\"1.0\"?>");
820
        out.println("<error>");
821
        out.println(npe.getMessage()); 
822
        out.println("</error>");
823
      }
824
    } catch (Exception e) {
825
      response.setContentType("text/xml");
826
      out.println("<?xml version=\"1.0\"?>");
827
      out.println("<error>");
828
      out.println(e.getMessage()); 
829
      if (e instanceof SAXException) {
830
        Exception e2 = ((SAXException)e).getException();
831
        out.println("<error>");
832
        out.println(e2.getMessage()); 
833
        out.println("</error>");
834
      }
835
      //e.printStackTrace(out);
836
      out.println("</error>");
837
    }
838
  }
839

    
840
  /** 
841
   * Handle the database delete request and delete an XML document 
842
   * from the database connection
843
   */
844
  private void handleDeleteAction(PrintWriter out, Hashtable params, 
845
               HttpServletResponse response, String user, String group) {
846

    
847
    String[] docid = (String[])params.get("docid");
848
    Connection conn = null;
849

    
850
    // delete the document from the database
851
    try {
852
      // get a connection from the pool
853
      conn = util.getConnection();
854
                                      // NOTE -- NEED TO TEST HERE
855
                                      // FOR EXISTENCE OF DOCID PARAM
856
                                      // BEFORE ACCESSING ARRAY
857
      try { 
858
        DocumentImpl.delete(conn, docid[0], user, group);
859
        response.setContentType("text/xml");
860
        out.println("<?xml version=\"1.0\"?>");
861
        out.println("<success>");
862
        out.println("Document deleted."); 
863
        out.println("</success>");
864
      } catch (AccessionNumberException ane) {
865
        response.setContentType("text/xml");
866
        out.println("<?xml version=\"1.0\"?>");
867
        out.println("<error>");
868
        out.println("Error deleting document!!!");
869
        out.println(ane.getMessage()); 
870
        out.println("</error>");
871
      }
872
    } catch (Exception e) {
873
      response.setContentType("text/xml");
874
      out.println("<?xml version=\"1.0\"?>");
875
      out.println("<error>");
876
      out.println(e.getMessage()); 
877
      out.println("</error>");
878
    } finally {
879
      util.returnConnection(conn);
880
    }  
881
  }
882
  
883
  /** 
884
   * Handle the validation request and return the results to the requestor
885
   */
886
  private void handleValidateAction(PrintWriter out, Hashtable params, 
887
               HttpServletResponse response) {
888

    
889
    // Get the document indicated
890
    String valtext = null;
891
    
892
    try {
893
      valtext = ((String[])params.get("valtext"))[0];
894
    } catch (Exception nullpe) {
895

    
896
      Connection conn = null;
897
      String docid = null;
898
      try {
899
        // Find the document id number
900
        docid = ((String[])params.get("docid"))[0]; 
901

    
902
        // get a connection from the pool
903
        conn = util.getConnection();
904

    
905
        // Get the document indicated from the db
906
        DocumentImpl xmldoc = new DocumentImpl(conn, docid);
907
        valtext = xmldoc.toString();
908

    
909
      } catch (NullPointerException npe) {
910
        response.setContentType("text/xml");
911
        out.println("<error>Error getting document ID: " + docid + "</error>");
912
        if ( conn != null ) { util.returnConnection(conn); }
913
        return;
914
      } catch (Exception e) {
915
        response.setContentType("text/html");
916
        out.println(e.getMessage()); 
917
      } finally {
918
        util.returnConnection(conn);
919
      }  
920
    }
921

    
922
    Connection conn = null;
923
    try {
924
      // get a connection from the pool
925
      conn = util.getConnection();
926
      DBValidate valobj = new DBValidate(saxparser,conn);
927
      boolean valid = valobj.validateString(valtext);
928

    
929
      // set content type and other response header fields first
930
      response.setContentType("text/xml");
931
      out.println(valobj.returnErrors());
932

    
933
    } catch (NullPointerException npe2) {
934
      // set content type and other response header fields first
935
      response.setContentType("text/xml");
936
      out.println("<error>Error validating document.</error>"); 
937
    } catch (Exception e) {
938
      response.setContentType("text/html");
939
      out.println(e.getMessage()); 
940
    } finally {
941
      util.returnConnection(conn);
942
    }  
943
  }
944

    
945
  /** 
946
   * Handle the document request and return the results to the requestor
947
   * If a docid is passed in through the params then that document
948
   * will be retrieved form the DB and put in the zip file.
949
   * In addition if 1 or more relations parameters are passed, those file
950
   * will be zipped as well.  Currently this is only implemented for 
951
   * metacat:// and http:// files.  Support should be added for srb:// files
952
   * as well.
953
   */
954
  private void handleGetDataDocumentAction(ServletOutputStream out, 
955
               Hashtable params, 
956
               HttpServletResponse response) {
957
  //find the related files, get them from their source and zip them into 
958
  //a zip file.
959
  try
960
  {
961
    Connection conn = util.getConnection();
962
    String currentDocid = ((String[])params.get("docid"))[0];
963
    ZipOutputStream zout = new ZipOutputStream(out);
964
    byte[] bytestring = null;
965
    ZipEntry zentry = null;
966
    DocumentImpl xmldoc = null;
967
    String[] reldocs = null;
968
    
969
    if(params.containsKey("relation"))
970
    { //get the relations from the parameters.
971
      reldocs = ((String[])params.get("relation"));
972
    }
973
    else
974
    { //let the for loop know that there are no relations to zip
975
      reldocs = new String[0];
976
    }
977

    
978
    //write the base file to the zip file.
979
    xmldoc = new DocumentImpl(conn, currentDocid);
980
    bytestring = (xmldoc.toString()).getBytes();
981
    zentry = new ZipEntry(currentDocid + ".xml");
982
    //create a new zip entry and write the file to the stream
983
    zentry.setSize(bytestring.length);
984
    zout.putNextEntry(zentry);
985
    zout.write(bytestring, 0, bytestring.length);
986
    zout.closeEntry(); //get ready for the next entry. 
987

    
988
    //zip up the related documents
989
    for(int i=0; i<reldocs.length; i++)
990
    {
991
      metacatURL murl = new metacatURL(((String)reldocs[i]));
992
      if(murl.getURLType().equals("metacat"))
993
      {
994
        //get the document from the database
995
        xmldoc = new DocumentImpl(conn, (murl.getParam(0))[1]);
996
        bytestring = (xmldoc.toString()).getBytes();
997
        zentry = new ZipEntry((murl.getParam(0))[1] + ".xml");
998
        //create a new zip entry and write the file to the stream
999
        zentry.setSize(bytestring.length);
1000
        zout.putNextEntry(zentry);
1001
        zout.write(bytestring, 0, bytestring.length);
1002
        zout.closeEntry(); //get ready for the next entry.
1003
      }
1004
      else if(murl.getURLType().equals("http"))
1005
      {
1006
        String[] murlParams = murl.getParam(0);
1007
        if(murlParams[0].equals("httpurl"))
1008
        {//httpurl is the param name for an http url.
1009
          URL urlconn = new URL(murlParams[1]);  //create a new url obj.
1010
          BufferedReader htmldoc = new BufferedReader(
1011
                                   new InputStreamReader(urlconn.openStream()));
1012
          //get the data from the web server
1013
          try
1014
          { //zip the document
1015
            String line=null;
1016
            zentry = new ZipEntry((murl.getParam(1))[1]);
1017
            //get just the filename from the URL.
1018
            zout.putNextEntry(zentry);
1019
            //make a new entry in the zip file stream
1020
            while((line = htmldoc.readLine()) != null)
1021
            {
1022
              bytestring = (line.toString()).getBytes();
1023
              zout.write(bytestring, 0, bytestring.length);
1024
              //write out the file line by line
1025
            }
1026
            zout.closeEntry(); //close the entry in the file
1027
          }
1028
          catch(Exception e)
1029
          {
1030
            util.debugMessage("error downloading html document"); 
1031
          }
1032
        }
1033
      }
1034
    }
1035
    zout.finish();  //terminate the zip file
1036
    zout.close();   //close the stream.
1037
    util.returnConnection(conn); //return the connection to the pool
1038
  }
1039
  catch(Exception e)
1040
  {
1041
    System.out.println("Error creating zip file: " + e.getMessage()); 
1042
    e.printStackTrace(System.out);
1043
  }
1044
           
1045
   /*
1046
   //////////old code using a shell script/////////////////////////////////
1047
   
1048
      boolean error_flag = false;
1049
      String error_message = "";
1050
      // Get the document indicated
1051
      String[] datadoc = (String[])params.get("datadoc");
1052
      // defaultdatapath = "C:\\Temp\\";    // for testing only!!!
1053
      // executescript = "test.bat";        // for testing only!!!
1054
      
1055
      // set content type and other response header fields first
1056
      response.setContentType("application/octet-stream");
1057
      if (defaultdatapath!=null) {
1058
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) {
1059
          defaultdatapath=defaultdatapath+System.getProperty("file.separator");
1060
        }
1061
        System.out.println("Path= "+defaultdatapath+datadoc[0]);
1062
        if (executescript!=null) {
1063
          String command = null;
1064
          File scriptfile = new File(executescript);
1065
          if (scriptfile.exists()) {
1066
            command=executescript+" "+datadoc[0]; // script includes path
1067
        } else {     // look in defaultdatapath
1068
            // on Win98 one MUST include the .bat extender
1069
            command = defaultdatapath+executescript+" "+datadoc[0];  
1070
        }
1071
      System.out.println(command);
1072
      try {
1073
      Process proc = Runtime.getRuntime().exec(command);
1074
      proc.waitFor();
1075
      }
1076
      catch (Exception eee) {
1077
        System.out.println("Error running process!");
1078
        error_flag = true;
1079
        error_message = "Error running process!";}
1080
      } // end executescript not null if
1081
      File datafile = new File(defaultdatapath+datadoc[0]);
1082
      try {
1083
      FileInputStream fw = new FileInputStream(datafile);
1084
      int x;
1085
      while ((x = fw.read())!=-1) {
1086
        out.write(x); }
1087
        fw.close();
1088
      } catch (Exception e) {
1089
        System.out.println("Error in returning file\n"+e.getMessage());
1090
        error_flag=true;
1091
        error_message = error_message+"\nError in returning file\n"+
1092
                        e.getMessage();
1093
      }
1094
    } // end defaultdatapath not null if
1095
    */
1096
  }
1097
  
1098
  /** 
1099
   * Handle the getdoctypes Action.
1100
   * Read all doctypes from db connection in XML format
1101
   */
1102
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params, 
1103
                                       HttpServletResponse response) {
1104

    
1105
    Connection conn = null;
1106
    
1107
    try {
1108

    
1109
        // get connection from the pool
1110
        conn = util.getConnection();
1111
        DBUtil dbutil = new DBUtil(conn);
1112
        String doctypes = dbutil.readDoctypes();
1113
        out.println(doctypes);
1114

    
1115
    } catch (Exception e) {
1116
      out.println("<?xml version=\"1.0\"?>");
1117
      out.println("<error>");
1118
      out.println(e.getMessage());
1119
      out.println("</error>");
1120
    } finally {
1121
      util.returnConnection(conn);
1122
    }  
1123
    
1124
  }
1125

    
1126
  /** 
1127
   * Handle the getdataguide Action.
1128
   * Read Data Guide for a given doctype from db connection in XML format
1129
   */
1130
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
1131
                                        HttpServletResponse response) {
1132

    
1133
    Connection conn = null;
1134
    String doctype = null;
1135
    String[] doctypeArr = (String[])params.get("doctype");
1136

    
1137
    // get only the first doctype specified in the list of doctypes
1138
    // it could be done for all doctypes in that list
1139
    if (doctypeArr != null) {
1140
        doctype = ((String[])params.get("doctype"))[0]; 
1141
    }
1142

    
1143
    try {
1144

    
1145
        // get connection from the pool
1146
        conn = util.getConnection();
1147
        DBUtil dbutil = new DBUtil(conn);
1148
        String dataguide = dbutil.readDataGuide(doctype);
1149
        out.println(dataguide);
1150

    
1151
    } catch (Exception e) {
1152
      out.println("<?xml version=\"1.0\"?>");
1153
      out.println("<error>");
1154
      out.println(e.getMessage());
1155
      out.println("</error>");
1156
    } finally {
1157
      util.returnConnection(conn);
1158
    }  
1159
    
1160
  }
1161

    
1162
}
(19-19/28)