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-10-24 13:03:07 -0700 (Tue, 24 Oct 2000) $'
11
 * '$Revision: 503 $'
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
   * Initialize the servlet by creating appropriate database connections
108
   */
109
  public void init( ServletConfig config ) throws ServletException {
110
    try {
111
      super.init( config );
112
      this.config = config;
113
      this.context = config.getServletContext(); 
114
      System.out.println("MetaCatServlet Initialize");
115

    
116
      util = new MetaCatUtil();
117

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

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

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

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

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

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

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

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

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

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

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

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

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

    
258
    // Now that we know the session is valid, we can delegate the request
259
    // to a particular action handler
260
    if(action.equals("query"))
261
    {
262
      handleQuery(response.getWriter(), params, response, username, groupname); 
263
    } 
264
    else if(action.equals("squery"))
265
    {
266
      if(params.containsKey("query"))
267
      {
268
        handleSQuery(response.getWriter(), params, response, username, groupname); 
269
      }
270
      else
271
      {
272
        PrintWriter out = response.getWriter();
273
        out.println("Illegal action squery without \"query\" parameter");
274
      }
275
    }
276
    else if (action.equals("getdocument")) {
277
      PrintWriter out = response.getWriter();
278
      try {
279
        handleGetDocumentAction(out, params, response);
280
      } catch (ClassNotFoundException e) {
281
        out.println(e.getMessage());
282
      } catch (SQLException se) {
283
        out.println(se.getMessage());
284
      }
285
    } 
286
    else if (action.equals("getrelateddocument")) {
287
      PrintWriter out = response.getWriter();
288
      try {
289
        handleGetRelatedDocumentAction(out, params, response);
290
      } catch (ClassNotFoundException e) {
291
        out.println(e.getMessage());
292
      } catch (SQLException se) {
293
        out.println(se.getMessage());
294
      }
295
    }
296
    else if (action.equals("insert") || action.equals("update")) {
297
      PrintWriter out = response.getWriter();
298
      if ( !username.equals("public") && (username != null) ) {
299
        handleInsertOrUpdateAction(out, params, response, username, groupname);
300
      } else {  
301
        out.println("Permission denied for " + action);
302
      }  
303
    } else if (action.equals("delete")) {
304
      PrintWriter out = response.getWriter();
305
      if ( !username.equals("public") && (username != null) ) {
306
        handleDeleteAction(out, params, response, username, groupname);
307
      } else {  
308
        out.println("Permission denied for " + action);
309
      }  
310
    } else if (action.equals("validate")) {
311
      PrintWriter out = response.getWriter();
312
      handleValidateAction(out, params, response); 
313
    } else if (action.equals("getabstract")) {
314
      PrintWriter out = response.getWriter();
315
      try{
316
        handleViewAbstractAction(out, params, response);
317
      }
318
      catch(Exception e)
319
      {
320
        out.println("error viewing abstract: " + e.getMessage());
321
      }
322
    } else if (action.equals("getdatadoc")) {
323
      response.setContentType("application/zip");
324
      ServletOutputStream out = response.getOutputStream();
325
      handleGetDataDocumentAction(out, params, response);  
326
    } else if (action.equals("getdoctypes")) {
327
      PrintWriter out = response.getWriter();
328
      handleGetDoctypesAction(out, params, response);  
329
    } else if (action.equals("getdataguide")) {
330
      PrintWriter out = response.getWriter();
331
      handleGetDataGuideAction(out, params, response);  
332
    } else if (action.equals("Login") || action.equals("Login Client")) {
333
    } else {
334
      PrintWriter out = response.getWriter();
335
      out.println("Error: action not registered.  Please report this error.");
336
    }
337
    util.closeConnections();
338
    // Close the stream to the client
339
    //out.close();
340
  }
341
  
342
  /**
343
   * decodes the mouse click information coming from the client.
344
   * This function may be overwritten to provide specific functionality
345
   * for different applications.
346
   * @param params the parameters from the CGI
347
   * @return action the action to be performed or "error" if an error was
348
   * generated
349
   */
350
  protected String decodeMouseAction(Hashtable params)
351
  {
352
    // Determine what type of request the user made
353
    // if the action parameter is set, use it as a default
354
    // but if the ypos param is set, calculate the action needed
355
    String action=null;
356
    long ypos = 0;
357
    try {
358
      ypos = (new Long(((String[])params.get("ypos"))[0]).longValue());
359
      //out.println("<P>YPOS IS " + ypos);
360
      if (ypos <= 13) {
361
        action = "getdocument";
362
      } else if (ypos > 13 && ypos <= 27) {
363
        action = "validate";
364
      } else if (ypos > 27) {
365
        action = "transform";
366
      }
367
      return action;
368
    } catch (Exception npe) {
369
      //
370
      // MBJ -- NOTE that this should be handled more gracefully with
371
      //        the new exception infrastructure -- this "error" return
372
      //        value is inappropriate
373
      //out.println("<P>Caught exception looking for Y value.");
374
      return "error";
375
    }  
376
  }
377

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

    
385
    AuthSession sess = null;
386
    String un = ((String[])params.get("username"))[0];
387
    String pw = ((String[])params.get("password"))[0];
388
    String action = ((String[])params.get("action"))[0];
389
    
390
    try {
391
      sess = new AuthSession(request, un, pw);
392
    } catch (Exception e) {
393
      out.println(e.getMessage());
394
    }
395
    
396
    String output = null;
397
    boolean isValid = sess.authenticate();
398
    if (action.equals("Login Client")) {
399
      out.println(sess.getMessage());
400
    } else {
401
      try {
402
        if (isValid) {
403
          if (un.equals("public")) {
404
            response.sendRedirect(
405
                   response.encodeRedirectUrl(htmlpath + "/index.html"));
406
          } else {
407
            response.sendRedirect(
408
                   response.encodeRedirectUrl(htmlpath + "/metacat.html"));
409
          }
410
        } else {
411
          response.sendRedirect(
412
                   response.encodeRedirectUrl(htmlpath + "/login.html"));
413
        }
414
      } catch ( java.io.IOException ioe) {
415
        String message = "handleLoginAction() - " +
416
                    "Error on redirect of HttpServletResponse: " + 
417
                    ioe.getMessage();
418
        out.println(message);
419
      }                
420
    }
421
  }    
422
  
423
  /**      
424
   * Retreive the squery xml, execute it and display it
425
   *
426
   * @param out the output stream to the client
427
   * @param params the Hashtable of parameters that should be included
428
   * in the squery.
429
   * @param response the response object linked to the client
430
   * @param conn the database connection 
431
   */
432
  protected void handleSQuery(PrintWriter out, Hashtable params, 
433
                 HttpServletResponse response, String user, String group)
434
  { 
435
    String xmlquery = ((String[])params.get("query"))[0];
436
    String qformat = ((String[])params.get("qformat"))[0];
437
    String resultdoc = null;
438
    String[] returndoc = null;
439
    if(params.contains("returndoc"))
440
    {
441
      returndoc = (String[])params.get("returndoc");
442
    }
443
    
444
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
445
    //String resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
446

    
447
    resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
448
    
449
    //format and transform the results                                        
450
    if(qformat.equals("html")) {
451
      transformResultset(resultdoc, response, out);
452
    } else if(qformat.equals("xml")) {
453
      response.setContentType("text/xml");
454
      out.println(resultdoc);
455
    } else {
456
      out.println("invalid qformat: " + qformat); 
457
    }
458
  }
459
  
460
   /**
461
    * Create the xml query, execute it and display the results.
462
    *
463
    * @param out the output stream to the client
464
    * @param params the Hashtable of parameters that should be included
465
    * in the squery.
466
    * @param response the response object linked to the client
467
    */ 
468
  protected void handleQuery(PrintWriter out, Hashtable params, 
469
                 HttpServletResponse response, String user, String group)
470
  {
471
    //create the query and run it
472
    String[] returndoc = null;
473
    if(params.containsKey("returndoc"))
474
    {
475
      returndoc = (String[])params.get("returndoc");
476
    }
477
    String xmlquery = DBQuery.createSQuery(params);
478
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
479
    String qformat = ((String[])params.get("qformat"))[0];
480
    String resultdoc = null;
481
    
482
    resultdoc = createResultDocument(doclist, transformQuery(params));
483

    
484
    //format and transform the results                                        
485
    if(qformat.equals("html")) {
486
      transformResultset(resultdoc, response, out);
487
    } else if(qformat.equals("xml")) {
488
      response.setContentType("text/xml");
489
      out.println(resultdoc);
490
    } else { 
491
      out.println("invalid qformat: " + qformat); 
492
    }
493
  }
494
  
495
  /**
496
   * Removes the <?xml version="x"?> tag from the beginning of xmlquery
497
   * so it can properly be placed in the <query> tag of the resultset.
498
   * This method is overwritable so that other applications can customize
499
   * the structure of what is in the <query> tag.
500
   * 
501
   * @param xmlquery is the query to remove the <?xml version="x"?> tag from.
502
   */
503
  protected String transformQuery(Hashtable params)
504
  {
505
    //DBQuery.createSQuery is a re-calling of a previously called 
506
    //function but it is necessary
507
    //so that overriding methods have access to the params hashtable
508
    String xmlquery = DBQuery.createSQuery(params);
509
    //the <?xml version="1.0"?> tag is the first 22 characters of the
510
    xmlquery = xmlquery.trim();
511
    int index = xmlquery.indexOf("?>");
512
    return xmlquery.substring(index + 2, xmlquery.length());
513
  }
514
  
515
  /**
516
   * removes the <?xml version="1.0"?> tag from the beginning.  This takes a
517
   * string as a param instead of a hashtable.
518
   * 
519
   * @param xmlquery a string representing a query.
520
   */
521
  protected String transformQuery(String xmlquery)
522
  {
523
    xmlquery = xmlquery.trim();
524
    int index = xmlquery.indexOf("?>");
525
    return xmlquery.substring(index + 2, xmlquery.length());
526
  }
527
  
528
  /**
529
   * Run the query and return a hashtable of results.
530
   *
531
   * @param xmlquery the query to run
532
   */
533
  private Hashtable runQuery(String xmlquery, String user, String group, 
534
                             String[] returndoc)
535
  {
536
    Hashtable doclist=null;
537
    Connection conn = null;
538
    try
539
    {
540
      conn = util.getConnection();
541
      DBQuery queryobj = new DBQuery(conn, saxparser);
542
      doclist = queryobj.findDocuments(new StringReader(xmlquery),user,group,
543
                                       returndoc);
544
      util.returnConnection(conn);
545
      return doclist;
546
    } 
547
    catch (Exception e) 
548
    {
549
      util.returnConnection(conn); 
550
      util.debugMessage("Error in runQuery: " + e.getMessage());
551
      doclist = null;
552
      return doclist;
553
    }    
554
  }
555
  
556
  /**
557
   * Transorms an xml resultset document to html and sends it to the browser
558
   *
559
   * @param resultdoc the string representation of the document that needs
560
   * to be transformed.
561
   * @param response the HttpServletResponse object bound to the client.
562
   * @param out the output stream to the client
563
   */ 
564
  protected void transformResultset(String resultdoc, 
565
                                    HttpServletResponse response,
566
                                    PrintWriter out)
567
  {
568
    Connection conn = null;
569
    try {
570
      conn = util.getConnection();
571
      DBTransform trans = new DBTransform(conn);
572
      response.setContentType("text/html");
573
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN", 
574
                                 "-//W3C//HTML//EN", out);
575
      util.returnConnection(conn); 
576
    }
577
    catch(Exception e)
578
    {
579
      util.returnConnection(conn); 
580
    } 
581
  }
582
  
583
  /**
584
   * Transforms a hashtable of documents to an xml or html result.
585
   * If there is a returndoc, then it only displays documents of
586
   * whatever type returndoc represents.  If a result is found in a document
587
   * that is not of type returndoc then this attempts to find a relation 
588
   * between this document and one that satifies the returndoc doctype.
589
   *
590
   * @param doclist- the hashtable to transform
591
   * @param xmlquery- the query that returned the dolist result
592
   * @param resultdoc- the document type to backtrack to.
593
   */
594
  protected String createResultDocument(Hashtable doclist, String xmlquery)
595
  {
596
    // Create a buffer to hold the xml result
597
    StringBuffer resultset = new StringBuffer();
598
 
599
    // Print the resulting root nodes 
600
    String docid = null;
601
    String document = null;
602
    resultset.append("<?xml version=\"1.0\"?>\n");
603
    resultset.append("<resultset>\n");
604
      
605
    resultset.append("  <query>" + xmlquery + "</query>");   
606

    
607
    if(doclist != null)
608
    {
609
      Enumeration doclistkeys = doclist.keys(); 
610
      while (doclistkeys.hasMoreElements()) 
611
      {
612
        docid = (String)doclistkeys.nextElement();
613
        document = (String)doclist.get(docid);
614
        resultset.append("  <document>" + document + "</document>");
615
      }
616
    }
617

    
618
    resultset.append("</resultset>");
619
    //System.out.println(resultset.toString());
620
    return resultset.toString();
621
  }
622
  
623
  /**
624
   * Handle the request to view the abstract of a document.
625
   * The abstractpath CGI parameter gives the xml path to the abstract
626
   * node.  
627
   */
628
  private void handleViewAbstractAction(PrintWriter out, Hashtable params,
629
               HttpServletResponse response) throws IOException, SQLException
630
  {
631
    String abstractpath = null;
632
    String docid = null;
633
    Connection conn = null;
634
    response.setContentType("text/html");
635
    try
636
    {
637
      docid = ((String[])params.get("docid"))[0];
638
      if(params.containsKey("abstractpath"))
639
      {
640
        //the CGI parameter abstractpath holds the path to the abstract
641
        //that should be displayed.
642
        abstractpath = ((String[])params.get("abstractpath"))[0];
643
      }
644
      else
645
      {
646
        out.println("error: no abstractpath parameter"); 
647
      }
648
      conn = util.getConnection();
649
    
650
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid, conn);
651
    
652
      out.println("<html><head><title>Abstract</title></head>");
653
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
654
      for(int i=0; i<abstracts.length; i++)
655
      {
656
        out.println("<p>" + (String)abstracts[i] + "</p>");
657
      }
658
      out.println("</body></html>");
659
    }
660
    catch (IOException ioe)
661
    {
662
       util.debugMessage("error in handlegetabstract: " + ioe.getMessage());
663
    }
664
    catch(SQLException sqle)
665
    {
666
      util.debugMessage("error in handlegetabstract: " + sqle.getMessage()); 
667
    }
668
    catch(Exception e)
669
    {
670
      util.debugMessage("error in handlegetabstract: " + e.getMessage());
671
    }
672
    
673
    util.returnConnection(conn);
674
  }
675

    
676
  /** 
677
   * Handle the database getrelateddocument request and return a XML document, 
678
   * possibly transformed from XML into HTML
679
   */
680
  private void handleGetRelatedDocumentAction(PrintWriter out, Hashtable params, 
681
               HttpServletResponse response) 
682
               throws ClassNotFoundException, IOException, SQLException 
683
  {
684
    String docid = null;
685
    Connection conn = null;
686
      
687
    if(params.containsKey("url"))
688
    {//the identifier for the related document is contained in the URL param
689
      try
690
      {
691
        DocumentImpl xmldoc=null;
692
        metacatURL murl = new metacatURL(((String[])params.get("url"))[0]);
693
        if(murl.getURLType().equals("metacat"))
694
        {//get the document from the database if it is the right type of url
695
          Hashtable murlParams = murl.getHashParams();
696
          if(murlParams.containsKey("docid"))
697
          {//the docid should be first
698
            docid = (String)murlParams.get("docid"); //get the docid value
699
            conn = util.getConnection();
700
            xmldoc = new DocumentImpl(conn, docid);
701
            String qformat = ((String[])params.get("qformat"))[0];
702
            if (qformat.equals("xml")) 
703
            { 
704
              // set content type and other response header fields first
705
              response.setContentType("text/xml");
706
              xmldoc.toXml(out);
707
              //out.println(xmldoc);
708
            } 
709
            else if (qformat.equals("html")) 
710
            {
711
              response.setContentType("text/html");
712
              // Look up the document type
713
              String sourcetype = xmldoc.getDoctype();
714
              // Transform the document to the new doctype
715
              DBTransform dbt = new DBTransform(conn);
716
              dbt.transformXMLDocument(xmldoc.toString(), sourcetype, 
717
                                 "-//W3C//HTML//EN", out);
718
            }
719

    
720
            util.returnConnection(conn);
721
          }
722
          else
723
          {
724
            //throw new Exception("handleGetDocument: bad URL");
725
            System.err.println("handleGetDocument: bad URL");
726
          }
727
        }
728
        else if(murl.getURLType().equals("http"))
729
        {//get the document from the internet
730
          Hashtable murlParams = murl.getHashParams();
731
          if(murlParams.containsKey("httpurl"))
732
          {//httpurl is the param name for an http url.
733
            URL urlconn = new URL((String)murlParams.get("httpurl"));  
734
            //create a new url obj.
735
            //DataInputStream htmldoc = new DataInputStream(urlconn.openStream());
736
            BufferedReader htmldoc = new BufferedReader(
737
                                   new InputStreamReader(urlconn.openStream()));
738
            //bind a data stream.
739
            try
740
            { //display the document
741
              String line=null;
742
              while((line = htmldoc.readLine()) != null)
743
              {
744
                out.println(line); 
745
              }
746
            }
747
            catch(Exception e)
748
            {
749
              util.debugMessage("error viewing html document"); 
750
            }
751
          }
752
        }
753
      }
754
      catch (McdbException e) {
755
        response.setContentType("text/xml");
756
        e.toXml(out);
757
      } catch   (Throwable t) {
758
        response.setContentType("text/html");
759
        out.println(t.getMessage());
760
      } finally {
761
        util.returnConnection(conn);
762
      }
763
    }
764
  }   
765
  
766
  /** 
767
   * Handle the database getdocument request and return a XML document, 
768
   * possibly transformed from XML into HTML
769
   */
770
  private void handleGetDocumentAction(PrintWriter out, Hashtable params, 
771
               HttpServletResponse response) 
772
               throws ClassNotFoundException, IOException, SQLException {
773
    String docidstr = null;
774
    String docid = null;
775
    String doc = null;
776
    Connection conn = null;
777
    
778
    try {
779
      // Find the document id number
780
      docidstr = ((String[])params.get("docid"))[0]; 
781
      docid = docidstr;
782
      conn = util.getConnection();
783
      DocumentImpl xmldoc = new DocumentImpl(conn, docid);
784
      // Get the document indicated from the db
785
      //doc = docreader.readXMLDocument(docid);
786

    
787
      // Return the document in XML or HTML format
788
      String qformat=null;
789
      if(params.containsKey("qformat"))
790
      {
791
        qformat = ((String[])params.get("qformat"))[0];
792
      }
793
      else
794
      {
795
        qformat = "html";        
796
      }
797
      if (qformat.equals("xml")) { 
798
        // set content type and other response header fields first
799
        response.setContentType("text/xml");
800
        xmldoc.toXml(out);
801
        //out.println(xmldoc);
802
      } else if (qformat.equals("html")) {
803
        response.setContentType("text/html");
804
        // Look up the document type
805
        String sourcetype = xmldoc.getDoctype();
806
        // Transform the document to the new doctype
807
        DBTransform dbt = new DBTransform(conn);
808
        dbt.transformXMLDocument(xmldoc.toString(), sourcetype, 
809
                                 "-//W3C//HTML//EN", out);
810
      }
811
    } catch (McdbException e) {
812
      response.setContentType("text/xml");
813
      e.toXml(out);
814
    } catch (Throwable t) {
815
      response.setContentType("text/html");
816
      out.println(t.getMessage());
817
    } finally {
818
      util.returnConnection(conn);
819
    }    
820

    
821
  }
822

    
823
  /** 
824
   * Handle the database putdocument request and write an XML document 
825
   * to the database connection
826
   */
827
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params, 
828
               HttpServletResponse response, String user, String group) {
829

    
830
    Connection conn = null;
831

    
832
    try {
833
      // Get the document indicated
834
      String[] doctext = (String[])params.get("doctext");
835
      StringReader xml = null;
836
      try {
837
        xml = new StringReader(doctext[0]);
838

    
839
        String[] action = (String[])params.get("action");
840
        String[] docid = (String[])params.get("docid");
841
        String newdocid = null;
842

    
843
        String doAction = null;
844
        if (action[0].equals("insert")) {
845
          doAction = "INSERT";
846
        } else if (action[0].equals("update")) {
847
          doAction = "UPDATE";
848
        }
849

    
850
        try {
851
            // get a connection from the pool
852
            conn = util.getConnection();
853

    
854
            // write the document to the database
855
            try {
856
                String accNumber = docid[0];
857
                if (accNumber.equals("")) {
858
                    accNumber = null;
859
                }
860
                newdocid = DocumentImpl.write(conn, xml, doAction, accNumber, 
861
                                              user, group);
862
                
863
            } catch (NullPointerException npe) {
864
              newdocid = DocumentImpl.write(conn,xml,doAction,null,user,group);
865
            }
866
//        } catch (Exception e) {
867
//          response.setContentType("text/html");
868
//          out.println(e.getMessage());
869
        } finally {
870
          util.returnConnection(conn);
871
        }    
872

    
873
        // set content type and other response header fields first
874
        response.setContentType("text/xml");
875
        out.println("<?xml version=\"1.0\"?>");
876
        out.println("<success>");
877
        out.println("<docid>" + newdocid + "</docid>"); 
878
        out.println("</success>");
879

    
880
      } catch (NullPointerException npe) {
881
        response.setContentType("text/xml");
882
        out.println("<?xml version=\"1.0\"?>");
883
        out.println("<error>");
884
        out.println(npe.getMessage()); 
885
        out.println("</error>");
886
      }
887
    } catch (Exception e) {
888
      response.setContentType("text/xml");
889
      out.println("<?xml version=\"1.0\"?>");
890
      out.println("<error>");
891
      out.println(e.getMessage()); 
892
      if (e instanceof SAXException) {
893
        Exception e2 = ((SAXException)e).getException();
894
        out.println("<error>");
895
        out.println(e2.getMessage()); 
896
        out.println("</error>");
897
      }
898
      //e.printStackTrace(out);
899
      out.println("</error>");
900
    }
901
  }
902

    
903
  /** 
904
   * Handle the database delete request and delete an XML document 
905
   * from the database connection
906
   */
907
  private void handleDeleteAction(PrintWriter out, Hashtable params, 
908
               HttpServletResponse response, String user, String group) {
909

    
910
    String[] docid = (String[])params.get("docid");
911
    Connection conn = null;
912

    
913
    // delete the document from the database
914
    try {
915
      // get a connection from the pool
916
      conn = util.getConnection();
917
                                      // NOTE -- NEED TO TEST HERE
918
                                      // FOR EXISTENCE OF DOCID PARAM
919
                                      // BEFORE ACCESSING ARRAY
920
      try { 
921
        DocumentImpl.delete(conn, docid[0], user, group);
922
        response.setContentType("text/xml");
923
        out.println("<?xml version=\"1.0\"?>");
924
        out.println("<success>");
925
        out.println("Document deleted."); 
926
        out.println("</success>");
927
      } catch (AccessionNumberException ane) {
928
        response.setContentType("text/xml");
929
        out.println("<?xml version=\"1.0\"?>");
930
        out.println("<error>");
931
        out.println("Error deleting document!!!");
932
        out.println(ane.getMessage()); 
933
        out.println("</error>");
934
      }
935
    } catch (Exception e) {
936
      response.setContentType("text/xml");
937
      out.println("<?xml version=\"1.0\"?>");
938
      out.println("<error>");
939
      out.println(e.getMessage()); 
940
      out.println("</error>");
941
    } finally {
942
      util.returnConnection(conn);
943
    }  
944
  }
945
  
946
  /** 
947
   * Handle the validation request and return the results to the requestor
948
   */
949
  private void handleValidateAction(PrintWriter out, Hashtable params, 
950
               HttpServletResponse response) {
951

    
952
    // Get the document indicated
953
    String valtext = null;
954
    
955
    try {
956
      valtext = ((String[])params.get("valtext"))[0];
957
    } catch (Exception nullpe) {
958

    
959
      Connection conn = null;
960
      String docid = null;
961
      try {
962
        // Find the document id number
963
        docid = ((String[])params.get("docid"))[0]; 
964

    
965
        // get a connection from the pool
966
        conn = util.getConnection();
967

    
968
        // Get the document indicated from the db
969
        DocumentImpl xmldoc = new DocumentImpl(conn, docid);
970
        valtext = xmldoc.toString();
971

    
972
      } catch (NullPointerException npe) {
973
        response.setContentType("text/xml");
974
        out.println("<error>Error getting document ID: " + docid + "</error>");
975
        if ( conn != null ) { util.returnConnection(conn); }
976
        return;
977
      } catch (Exception e) {
978
        response.setContentType("text/html");
979
        out.println(e.getMessage()); 
980
      } finally {
981
        util.returnConnection(conn);
982
      }  
983
    }
984

    
985
    Connection conn = null;
986
    try {
987
      // get a connection from the pool
988
      conn = util.getConnection();
989
      DBValidate valobj = new DBValidate(saxparser,conn);
990
      boolean valid = valobj.validateString(valtext);
991

    
992
      // set content type and other response header fields first
993
      response.setContentType("text/xml");
994
      out.println(valobj.returnErrors());
995

    
996
    } catch (NullPointerException npe2) {
997
      // set content type and other response header fields first
998
      response.setContentType("text/xml");
999
      out.println("<error>Error validating document.</error>"); 
1000
    } catch (Exception e) {
1001
      response.setContentType("text/html");
1002
      out.println(e.getMessage()); 
1003
    } finally {
1004
      util.returnConnection(conn);
1005
    }  
1006
  }
1007

    
1008
  /** 
1009
   * Handle the document request and return the results to the requestor
1010
   * If a docid is passed in through the params then that document
1011
   * will be retrieved form the DB and put in the zip file.
1012
   * In addition if 1 or more relations parameters are passed, those file
1013
   * will be zipped as well.  Currently this is only implemented for 
1014
   * metacat:// and http:// files.  Support should be added for srb:// files
1015
   * as well.
1016
   */
1017
  private void handleGetDataDocumentAction(ServletOutputStream out, 
1018
               Hashtable params, 
1019
               HttpServletResponse response) {
1020
  //find the related files, get them from their source and zip them into 
1021
  //a zip file.
1022
  try
1023
  {
1024
    Connection conn = util.getConnection();
1025
    String currentDocid = ((String[])params.get("docid"))[0];
1026
    ZipOutputStream zout = new ZipOutputStream(out);
1027
    byte[] bytestring = null;
1028
    ZipEntry zentry = null;
1029
    DocumentImpl xmldoc = null;
1030
    String[] reldocs = null;
1031
    
1032
    if(params.containsKey("relation"))
1033
    { //get the relations from the parameters.
1034
      reldocs = ((String[])params.get("relation"));
1035
    }
1036
    else
1037
    { //let the for loop know that there are no relations to zip
1038
      reldocs = new String[0];
1039
    }
1040

    
1041
    //write the base file to the zip file.
1042
    xmldoc = new DocumentImpl(conn, currentDocid);
1043
    bytestring = (xmldoc.toString()).getBytes();
1044
    zentry = new ZipEntry(currentDocid + ".xml");
1045
    //create a new zip entry and write the file to the stream
1046
    zentry.setSize(bytestring.length);
1047
    zout.putNextEntry(zentry);
1048
    zout.write(bytestring, 0, bytestring.length);
1049
    zout.closeEntry(); //get ready for the next entry. 
1050

    
1051
    //zip up the related documents
1052
    for(int i=0; i<reldocs.length; i++)
1053
    {
1054
      metacatURL murl = new metacatURL(((String)reldocs[i]));
1055
      if(murl.getURLType().equals("metacat"))
1056
      {
1057
        //get the document from the database
1058
        xmldoc = new DocumentImpl(conn, (String)murl.getHashParam("docid"));
1059
        bytestring = (xmldoc.toString()).getBytes();
1060
        zentry = new ZipEntry(murl.getHashParam("docid") + ".xml");
1061
        //create a new zip entry and write the file to the stream
1062
        zentry.setSize(bytestring.length);
1063
        zout.putNextEntry(zentry);
1064
        zout.write(bytestring, 0, bytestring.length);
1065
        zout.closeEntry(); //get ready for the next entry.
1066
      }
1067
      else if(murl.getURLType().equals("http"))
1068
      {
1069
        Hashtable murlParams = murl.getHashParams();
1070
        if(murlParams.containsKey("httpurl"))
1071
        {//httpurl is the param name for an http url.
1072
          URL urlconn = new URL((String)murlParams.get("httpurl"));  
1073
          //create a new url obj.
1074
          BufferedReader htmldoc = new BufferedReader(
1075
                                   new InputStreamReader(urlconn.openStream()));
1076
          //get the data from the web server
1077
          try
1078
          { //zip the document
1079
            String line=null;
1080
            zentry = new ZipEntry((String)murlParams.get("filename"));
1081
            //get just the filename from the URL.
1082
            zout.putNextEntry(zentry);
1083
            //make a new entry in the zip file stream
1084
            while((line = htmldoc.readLine()) != null)
1085
            {
1086
              bytestring = (line.toString()).getBytes();
1087
              zout.write(bytestring, 0, bytestring.length);
1088
              //write out the file line by line
1089
            }
1090
            zout.closeEntry(); //close the entry in the file
1091
          }
1092
          catch(Exception e)
1093
          {
1094
            util.debugMessage("error downloading html document"); 
1095
          }
1096
        }
1097
      }
1098
    }
1099
    zout.finish();  //terminate the zip file
1100
    zout.close();   //close the stream.
1101
    util.returnConnection(conn); //return the connection to the pool
1102
  }
1103
  catch(Exception e)
1104
  {
1105
    System.out.println("Error creating zip file: " + e.getMessage()); 
1106
    e.printStackTrace(System.out);
1107
  }
1108
           
1109
   /*
1110
   //////////old code using a shell script/////////////////////////////////
1111
   
1112
      boolean error_flag = false;
1113
      String error_message = "";
1114
      // Get the document indicated
1115
      String[] datadoc = (String[])params.get("datadoc");
1116
      // defaultdatapath = "C:\\Temp\\";    // for testing only!!!
1117
      // executescript = "test.bat";        // for testing only!!!
1118
      
1119
      // set content type and other response header fields first
1120
      response.setContentType("application/octet-stream");
1121
      if (defaultdatapath!=null) {
1122
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) {
1123
          defaultdatapath=defaultdatapath+System.getProperty("file.separator");
1124
        }
1125
        System.out.println("Path= "+defaultdatapath+datadoc[0]);
1126
        if (executescript!=null) {
1127
          String command = null;
1128
          File scriptfile = new File(executescript);
1129
          if (scriptfile.exists()) {
1130
            command=executescript+" "+datadoc[0]; // script includes path
1131
        } else {     // look in defaultdatapath
1132
            // on Win98 one MUST include the .bat extender
1133
            command = defaultdatapath+executescript+" "+datadoc[0];  
1134
        }
1135
      System.out.println(command);
1136
      try {
1137
      Process proc = Runtime.getRuntime().exec(command);
1138
      proc.waitFor();
1139
      }
1140
      catch (Exception eee) {
1141
        System.out.println("Error running process!");
1142
        error_flag = true;
1143
        error_message = "Error running process!";}
1144
      } // end executescript not null if
1145
      File datafile = new File(defaultdatapath+datadoc[0]);
1146
      try {
1147
      FileInputStream fw = new FileInputStream(datafile);
1148
      int x;
1149
      while ((x = fw.read())!=-1) {
1150
        out.write(x); }
1151
        fw.close();
1152
      } catch (Exception e) {
1153
        System.out.println("Error in returning file\n"+e.getMessage());
1154
        error_flag=true;
1155
        error_message = error_message+"\nError in returning file\n"+
1156
                        e.getMessage();
1157
      }
1158
    } // end defaultdatapath not null if
1159
    */
1160
  }
1161
  
1162
  /** 
1163
   * Handle the getdoctypes Action.
1164
   * Read all doctypes from db connection in XML format
1165
   */
1166
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params, 
1167
                                       HttpServletResponse response) {
1168

    
1169
    Connection conn = null;
1170
    
1171
    try {
1172

    
1173
        // get connection from the pool
1174
        conn = util.getConnection();
1175
        DBUtil dbutil = new DBUtil(conn);
1176
        String doctypes = dbutil.readDoctypes();
1177
        out.println(doctypes);
1178

    
1179
    } catch (Exception e) {
1180
      out.println("<?xml version=\"1.0\"?>");
1181
      out.println("<error>");
1182
      out.println(e.getMessage());
1183
      out.println("</error>");
1184
    } finally {
1185
      util.returnConnection(conn);
1186
    }  
1187
    
1188
  }
1189

    
1190
  /** 
1191
   * Handle the getdataguide Action.
1192
   * Read Data Guide for a given doctype from db connection in XML format
1193
   */
1194
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
1195
                                        HttpServletResponse response) {
1196

    
1197
    Connection conn = null;
1198
    String doctype = null;
1199
    String[] doctypeArr = (String[])params.get("doctype");
1200

    
1201
    // get only the first doctype specified in the list of doctypes
1202
    // it could be done for all doctypes in that list
1203
    if (doctypeArr != null) {
1204
        doctype = ((String[])params.get("doctype"))[0]; 
1205
    }
1206

    
1207
    try {
1208

    
1209
        // get connection from the pool
1210
        conn = util.getConnection();
1211
        DBUtil dbutil = new DBUtil(conn);
1212
        String dataguide = dbutil.readDataGuide(doctype);
1213
        out.println(dataguide);
1214

    
1215
    } catch (Exception e) {
1216
      out.println("<?xml version=\"1.0\"?>");
1217
      out.println("<error>");
1218
      out.println(e.getMessage());
1219
      out.println("</error>");
1220
    } finally {
1221
      util.returnConnection(conn);
1222
    }  
1223
    
1224
  }
1225

    
1226
}
(22-22/32)