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: jones $'
10
 *     '$Date: 2000-11-27 13:55:08 -0800 (Mon, 27 Nov 2000) $'
11
 * '$Revision: 566 $'
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=read -- 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
 * acl - xml access file for a document to load into the database<br>
76
 * query -- actual query text (to go with 'action=query' or 'action=squery')<br>
77
 * valtext -- XML text to be validated<br>
78
 * action=getdatadoc -- retreive a stored datadocument<br>
79
 * action=getdoctypes -- retreive all doctypes (publicID)<br>
80
 * action=getdataguide -- retreive a Data Guide<br>
81
 * datadoc -- data document name (id)<br>
82
 * <p>
83
 * The particular combination of parameters that are valid for each 
84
 * particular action value is quite specific.  This documentation
85
 * will be reorganized to reflect this information.
86
 */
87
public class MetaCatServlet extends HttpServlet {
88

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

    
100
  // path to directory where data files 
101
  // that can be downloaded will be stored
102
  private String htmlpath = null; 
103
  // script to get data file and put it 
104
  // in defaultdocpath dir
105
  private String executescript  = null;  
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 pwout = 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
      //pwout.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 = ((String[])params.get("action"))[0];  
217
    util.debugMessage("Line 213: Action is: " + action);
218

    
219
    //MBJELIMINATE String action = decodeMouseAction(params);
220
    //if(action.equals("error"))
221
    //{
222
      //util.debugMessage("Line 218: Action is: " + action);
223
      //action = ((String[])params.get("action"))[0];  
224
    //}
225
    
226
    // This block handles session management for the servlet
227
    // by looking up the current session information for all actions
228
    // other than "login" and "logout"
229
    String username = null;
230
    String groupname = null;
231

    
232
    // handle login action
233
    if (action.equals("login")) {
234

    
235
      handleLoginAction(response.getWriter(), params, request, response);
236

    
237
    // handle logout action  
238
    } else if (action.equals("logout")) {
239

    
240
      handleLogoutAction(response.getWriter(), params, request, response);
241

    
242
    // aware of session expiration on every request  
243
    } else {   
244

    
245
      HttpSession sess = request.getSession(true);
246
      if (sess.isNew()) { 
247
        // session expired or has not been stored b/w user requests
248
        username = "public";
249
      } else {
250
        username = (String)sess.getAttribute("username");
251
        groupname = (String)sess.getAttribute("groupname");
252
      }  
253
    }    
254

    
255
    // Now that we know the session is valid, we can delegate the request
256
    // to a particular action handler
257
    if(action.equals("query"))
258
    {
259
      handleQuery(response.getWriter(), params, response, username, groupname); 
260
    } 
261
    else if(action.equals("squery"))
262
    {
263
      if(params.containsKey("query"))
264
      {
265
        handleSQuery(response.getWriter(), params, response, username, groupname); 
266
      }
267
      else
268
      {
269
        PrintWriter out = response.getWriter();
270
        out.println("Illegal action squery without \"query\" parameter");
271
      }
272
    }
273
    else if (action.equals("read")) {
274
      PrintWriter out = response.getWriter();
275
      try {
276
        handleReadAction(out, params, response);
277
      } catch (ClassNotFoundException e) {
278
        out.println(e.getMessage());
279
      } catch (SQLException se) {
280
        out.println(se.getMessage());
281
      }
282
    } 
283
/*
284
    else if (action.equals("getrelateddocument")) {
285
      PrintWriter out = response.getWriter();
286
      try {
287
        handleGetRelatedDocumentAction(out, params, response);
288
      } catch (ClassNotFoundException e) {
289
        out.println(e.getMessage());
290
      } catch (SQLException se) {
291
        out.println(se.getMessage());
292
      }
293
    }
294
*/
295
    else if (action.equals("insert") || action.equals("update")) {
296
      PrintWriter out = response.getWriter();
297
      if ( (username != null) &&  !username.equals("public") ) {
298
        handleInsertOrUpdateAction(out, params, response, username, groupname);
299
      } else {  
300
        out.println("Permission denied for " + action);
301
      }  
302
    } else if (action.equals("delete")) {
303
      PrintWriter out = response.getWriter();
304
      if ( (username != null) &&  !username.equals("public") ) {
305
        handleDeleteAction(out, params, response, username, groupname);
306
      } else {  
307
        out.println("Permission denied for " + action);
308
      }  
309
    } else if (action.equals("validate")) {
310
      PrintWriter out = response.getWriter();
311
      handleValidateAction(out, params, response); 
312
    } else if (action.equals("getabstract")) {
313
      PrintWriter out = response.getWriter();
314
      try{
315
        handleViewAbstractAction(out, params, response);
316
      }
317
      catch(Exception e)
318
      {
319
        out.println("error viewing abstract: " + e.getMessage());
320
      }
321
    } else if (action.equals("getdatadoc")) {
322
      response.setContentType("application/zip");
323
      ServletOutputStream out = response.getOutputStream();
324
      handleGetDataDocumentAction(out, params, response);  
325
    } else if (action.equals("getdoctypes")) {
326
      PrintWriter out = response.getWriter();
327
      handleGetDoctypesAction(out, params, response);  
328
    } else if (action.equals("getdataguide")) {
329
      PrintWriter out = response.getWriter();
330
      handleGetDataGuideAction(out, params, response);  
331
    } else if (action.equals("login") || action.equals("logout")) {
332
    } else if (action.equals("protocoltest")) {
333
      String testURL = "metacat://dev.nceas.ucsb.edu/NCEAS.897766.9";
334
      try {
335
        testURL = ((String[])params.get("url"))[0];
336
      } catch (Throwable t) {
337
      }
338
      String phandler = System.getProperty("java.protocol.handler.pkgs");
339
      response.setContentType("text/html");
340
      PrintWriter out = response.getWriter();
341
      out.println("<body bgcolor=\"white\">");
342
      out.println("<p>Handler property: <code>" + phandler + "</code></p>");
343
      out.println("<p>Starting test for:<br>");
344
      out.println("    " + testURL + "</p>");
345
      try {
346
        URL u = new URL(testURL);
347
        out.println("<pre>");
348
        out.println("Protocol: " + u.getProtocol());
349
        out.println("    Host: " + u.getHost());
350
        out.println("    Port: " + u.getPort());
351
        out.println("    Path: " + u.getPath());
352
        out.println("     Ref: " + u.getRef());
353
        String pquery = u.getQuery();
354
        out.println("   Query: " + pquery);
355
        out.println("  Params: ");
356
        if (pquery != null) {
357
          Hashtable qparams = util.parseQuery(u.getQuery());
358
          for (Enumeration en = qparams.keys(); en.hasMoreElements(); ) {
359
            String pname = (String)en.nextElement();
360
            String pvalue = (String)qparams.get(pname);
361
            out.println("    " + pname + ": " + pvalue);
362
          }
363
        }
364
        out.println("</pre>");
365
        out.println("</body>");
366
        out.close();
367
      } catch (MalformedURLException mue) {
368
        out.println(mue.getMessage());
369
        mue.printStackTrace(out);
370
        out.close();
371
      }
372
    } else {
373
      PrintWriter out = response.getWriter();
374
      out.println("Error: action not registered.  Please report this error.");
375
    }
376
    util.closeConnections();
377
    // Close the stream to the client
378
    //out.close();
379
  }
380
  
381
  /**
382
   * decodes the mouse click information coming from the client.
383
   * This function may be overwritten to provide specific functionality
384
   * for different applications.
385
   * @param params the parameters from the CGI
386
   * @return action the action to be performed or "error" if an error was
387
   * generated
388
   */
389
  protected String decodeMouseAction(Hashtable params)
390
  {
391
    // Determine what type of request the user made
392
    // if the action parameter is set, use it as a default
393
    // but if the ypos param is set, calculate the action needed
394
    String action=null;
395
    long ypos = 0;
396
    try {
397
      ypos = (new Long(((String[])params.get("ypos"))[0]).longValue());
398
      //out.println("<P>YPOS IS " + ypos);
399
      if (ypos <= 13) {
400
        action = "read";
401
      } else if (ypos > 13 && ypos <= 27) {
402
        action = "validate";
403
      } else if (ypos > 27) {
404
        action = "transform";
405
      }
406
      return action;
407
    } catch (Exception npe) {
408
      //
409
      // MBJ -- NOTE that this should be handled more gracefully with
410
      //        the new exception infrastructure -- this "error" return
411
      //        value is inappropriate
412
      //out.println("<P>Caught exception looking for Y value.");
413
      return "error";
414
    }  
415
  }
416

    
417
  /** 
418
   * Handle the login request. Create a new session object.
419
   * Do user authentication through the session.
420
   */
421
  private void handleLoginAction(PrintWriter out, Hashtable params, 
422
               HttpServletRequest request, HttpServletResponse response) {
423

    
424
    AuthSession sess = null;
425
    String un = ((String[])params.get("username"))[0];
426
    String pw = ((String[])params.get("password"))[0];
427
    String action = ((String[])params.get("action"))[0];
428
    String qformat = ((String[])params.get("qformat"))[0];
429
    
430
    try {
431
      sess = new AuthSession();
432
    } catch (Exception e) {
433
      out.println(e.getMessage());
434
      return;
435
    }
436
    
437
    boolean isValid = sess.authenticate(request, un, pw);
438

    
439
    // format and transform the output
440
    if (qformat.equals("html")) {
441
      Connection conn = null;
442
      try {
443
        conn = util.getConnection();
444
        DBTransform trans = new DBTransform(conn);
445
        response.setContentType("text/html");
446
        trans.transformXMLDocument(sess.getMessage(), "-//NCEAS//login//EN",
447
                                   "-//W3C//HTML//EN", out);
448
        util.returnConnection(conn); 
449
      } catch(Exception e) {
450
        util.returnConnection(conn); 
451
      } 
452
      
453
    // any output is returned  
454
    } else {
455
      response.setContentType("text/xml");
456
      out.println(sess.getMessage()); 
457
    }
458
        
459
/* WITHOUT XSLT transformation
460
    // redirects response to html page
461
    if (qformat.equals("html")) {
462
      // user authentication successful
463
      if (isValid) {
464
        response.sendRedirect(
465
                 response.encodeRedirectUrl(htmlpath + "/metacat.html"));
466
      // unsuccessful user authentication 
467
      } else {
468
        response.sendRedirect(htmlpath + "/login.html");
469
      }
470
    // any output is returned  
471
    } else {
472
      response.setContentType("text/xml");
473
      out.println(sess.getMessage()); 
474
    }
475
*/        
476

    
477
  }    
478

    
479
  /** 
480
   * Handle the logout request. Close the connection.
481
   */
482
  private void handleLogoutAction(PrintWriter out, Hashtable params, 
483
               HttpServletRequest request, HttpServletResponse response) {
484

    
485
    String qformat = ((String[])params.get("qformat"))[0];
486

    
487
    // close the connection
488
    HttpSession sess = request.getSession(false);
489
    if (sess != null) { sess.invalidate();  }    
490

    
491
    // produce output
492
    StringBuffer output = new StringBuffer();
493
    output.append("<?xml version=\"1.0\"?>");
494
    output.append("<logout>");
495
    output.append("User logged out");
496
    output.append("</logout>");
497

    
498
    //format and transform the output
499
    if (qformat.equals("html")) {
500
      Connection conn = null;
501
      try {
502
        conn = util.getConnection();
503
        DBTransform trans = new DBTransform(conn);
504
        response.setContentType("text/html");
505
        trans.transformXMLDocument(output.toString(), "-//NCEAS//login//EN", 
506
                                   "-//W3C//HTML//EN", out);
507
        util.returnConnection(conn); 
508
      } catch(Exception e) {
509
        util.returnConnection(conn); 
510
      } 
511
    // any output is returned  
512
    } else {
513
      response.setContentType("text/xml");
514
      out.println(output.toString()); 
515
    }
516

    
517
/* WITHOUT XSLT transformation
518
    // redirects response to html page
519
    if (qformat.equals("html")) {
520
        response.sendRedirect(htmlpath + "/index.html"); 
521
      } catch(Exception e) {
522
        util.returnConnection(conn); 
523
      } 
524
    // any output is returned  
525
    } else {
526
      response.setContentType("text/xml");
527
      out.println(output.toString()); 
528
    }
529
*/
530
  }
531

    
532
  
533
  /**      
534
   * Retreive the squery xml, execute it and display it
535
   *
536
   * @param out the output stream to the client
537
   * @param params the Hashtable of parameters that should be included
538
   * in the squery.
539
   * @param response the response object linked to the client
540
   * @param conn the database connection 
541
   */
542
  protected void handleSQuery(PrintWriter out, Hashtable params, 
543
                 HttpServletResponse response, String user, String group)
544
  { 
545
    String xmlquery = ((String[])params.get("query"))[0];
546
    String qformat = ((String[])params.get("qformat"))[0];
547
    String resultdoc = null;
548
    String[] returndoc = null;
549
    if(params.contains("returndoc"))
550
    {
551
      returndoc = (String[])params.get("returndoc");
552
    }
553
    
554
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
555
    //String resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
556

    
557
    resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
558
    
559
    //format and transform the results                                        
560
    if(qformat.equals("html")) {
561
      transformResultset(resultdoc, response, out);
562
    } else if(qformat.equals("xml")) {
563
      response.setContentType("text/xml");
564
      out.println(resultdoc);
565
    } else {
566
      out.println("invalid qformat: " + qformat); 
567
    }
568
  }
569
  
570
   /**
571
    * Create the xml query, execute it and display the results.
572
    *
573
    * @param out the output stream to the client
574
    * @param params the Hashtable of parameters that should be included
575
    * in the squery.
576
    * @param response the response object linked to the client
577
    */ 
578
  protected void handleQuery(PrintWriter out, Hashtable params, 
579
                 HttpServletResponse response, String user, String group)
580
  {
581
    //create the query and run it
582
    String[] returndoc = null;
583
    if(params.containsKey("returndoc"))
584
    {
585
      returndoc = (String[])params.get("returndoc");
586
    }
587
    String xmlquery = DBQuery.createSQuery(params);
588
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
589
    String qformat = ((String[])params.get("qformat"))[0];
590
    String resultdoc = null;
591
    
592
    resultdoc = createResultDocument(doclist, transformQuery(params));
593

    
594
    //format and transform the results                                        
595
    if(qformat.equals("html")) {
596
      transformResultset(resultdoc, response, out);
597
    } else if(qformat.equals("xml")) {
598
      response.setContentType("text/xml");
599
      out.println(resultdoc);
600
    } else { 
601
      out.println("invalid qformat: " + qformat); 
602
    }
603
  }
604
  
605
  /**
606
   * Removes the <?xml version="x"?> tag from the beginning of xmlquery
607
   * so it can properly be placed in the <query> tag of the resultset.
608
   * This method is overwritable so that other applications can customize
609
   * the structure of what is in the <query> tag.
610
   * 
611
   * @param xmlquery is the query to remove the <?xml version="x"?> tag from.
612
   */
613
  protected String transformQuery(Hashtable params)
614
  {
615
    //DBQuery.createSQuery is a re-calling of a previously called 
616
    //function but it is necessary
617
    //so that overriding methods have access to the params hashtable
618
    String xmlquery = DBQuery.createSQuery(params);
619
    //the <?xml version="1.0"?> tag is the first 22 characters of the
620
    xmlquery = xmlquery.trim();
621
    int index = xmlquery.indexOf("?>");
622
    return xmlquery.substring(index + 2, xmlquery.length());
623
  }
624
  
625
  /**
626
   * removes the <?xml version="1.0"?> tag from the beginning.  This takes a
627
   * string as a param instead of a hashtable.
628
   * 
629
   * @param xmlquery a string representing a query.
630
   */
631
  protected String transformQuery(String xmlquery)
632
  {
633
    xmlquery = xmlquery.trim();
634
    int index = xmlquery.indexOf("?>");
635
    return xmlquery.substring(index + 2, xmlquery.length());
636
  }
637
  
638
  /**
639
   * Run the query and return a hashtable of results.
640
   *
641
   * @param xmlquery the query to run
642
   */
643
  private Hashtable runQuery(String xmlquery, String user, String group, 
644
                             String[] returndoc)
645
  {
646
    Hashtable doclist=null;
647
    Connection conn = null;
648
    try
649
    {
650
      conn = util.getConnection();
651
      DBQuery queryobj = new DBQuery(conn, saxparser);
652
      doclist = queryobj.findDocuments(new StringReader(xmlquery),user,group,
653
                                       returndoc);
654
      util.returnConnection(conn);
655
      return doclist;
656
    } 
657
    catch (Exception e) 
658
    {
659
      util.returnConnection(conn); 
660
      util.debugMessage("Error in runQuery: " + e.getMessage());
661
      doclist = null;
662
      return doclist;
663
    }    
664
  }
665
  
666
  /**
667
   * Transorms an xml resultset document to html and sends it to the browser
668
   *
669
   * @param resultdoc the string representation of the document that needs
670
   * to be transformed.
671
   * @param response the HttpServletResponse object bound to the client.
672
   * @param out the output stream to the client
673
   */ 
674
  protected void transformResultset(String resultdoc, 
675
                                    HttpServletResponse response,
676
                                    PrintWriter out)
677
  {
678
    Connection conn = null;
679
    try {
680
      conn = util.getConnection();
681
      DBTransform trans = new DBTransform(conn);
682
      response.setContentType("text/html");
683
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN", 
684
                                 "-//W3C//HTML//EN", out);
685
      util.returnConnection(conn); 
686
    }
687
    catch(Exception e)
688
    {
689
      util.returnConnection(conn); 
690
    } 
691
  }
692
  
693
  /**
694
   * Transforms a hashtable of documents to an xml or html result.
695
   * If there is a returndoc, then it only displays documents of
696
   * whatever type returndoc represents.  If a result is found in a document
697
   * that is not of type returndoc then this attempts to find a relation 
698
   * between this document and one that satifies the returndoc doctype.
699
   *
700
   * @param doclist- the hashtable to transform
701
   * @param xmlquery- the query that returned the dolist result
702
   * @param resultdoc- the document type to backtrack to.
703
   */
704
  protected String createResultDocument(Hashtable doclist, String xmlquery)
705
  {
706
    // Create a buffer to hold the xml result
707
    StringBuffer resultset = new StringBuffer();
708
 
709
    // Print the resulting root nodes 
710
    String docid = null;
711
    String document = null;
712
    resultset.append("<?xml version=\"1.0\"?>\n");
713
    resultset.append("<resultset>\n");
714
      
715
    resultset.append("  <query>" + xmlquery + "</query>");   
716

    
717
    if(doclist != null)
718
    {
719
      Enumeration doclistkeys = doclist.keys(); 
720
      while (doclistkeys.hasMoreElements()) 
721
      {
722
        docid = (String)doclistkeys.nextElement();
723
        document = (String)doclist.get(docid);
724
        resultset.append("  <document>" + document + "</document>");
725
      }
726
    }
727

    
728
    resultset.append("</resultset>");
729
    //System.out.println(resultset.toString());
730
    return resultset.toString();
731
  }
732
  
733
  /**
734
   * Handle the request to view the abstract of a document.
735
   * The abstractpath CGI parameter gives the xml path to the abstract
736
   * node.  
737
   */
738
  private void handleViewAbstractAction(PrintWriter out, Hashtable params,
739
               HttpServletResponse response) throws IOException, SQLException
740
  {
741
    String abstractpath = null;
742
    String docid = null;
743
    Connection conn = null;
744
    response.setContentType("text/html");
745
    try
746
    {
747
      docid = ((String[])params.get("docid"))[0];
748
      if(params.containsKey("abstractpath"))
749
      {
750
        //the CGI parameter abstractpath holds the path to the abstract
751
        //that should be displayed.
752
        abstractpath = ((String[])params.get("abstractpath"))[0];
753
      }
754
      else
755
      {
756
        out.println("error: no abstractpath parameter"); 
757
      }
758
      conn = util.getConnection();
759
    
760
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid, conn);
761
    
762
      out.println("<html><head><title>Abstract</title></head>");
763
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
764
      for(int i=0; i<abstracts.length; i++)
765
      {
766
        out.println("<p>" + (String)abstracts[i] + "</p>");
767
      }
768
      out.println("</body></html>");
769
    }
770
    catch (IOException ioe)
771
    {
772
       util.debugMessage("error in handlegetabstract: " + ioe.getMessage());
773
    }
774
    catch(SQLException sqle)
775
    {
776
      util.debugMessage("error in handlegetabstract: " + sqle.getMessage()); 
777
    }
778
    catch(Exception e)
779
    {
780
      util.debugMessage("error in handlegetabstract: " + e.getMessage());
781
    }
782
    
783
    util.returnConnection(conn);
784
  }
785

    
786
  /** 
787
   * Handle the database getrelateddocument request and return a XML document, 
788
   * possibly transformed from XML into HTML
789
   */
790
  private void handleGetRelatedDocumentAction(PrintWriter out, Hashtable params,
791
               HttpServletResponse response, URL murl) 
792
               throws ClassNotFoundException, IOException, SQLException 
793
  {
794
    String docid = null;
795
    Connection conn = null;
796
      
797
    //if(params.containsKey("url"))
798
    //{//the identifier for the related document is contained in the URL param
799
      try
800
      {
801
        DocumentImpl xmldoc=null;
802
        //MetacatURL murl = new MetacatURL(((String[])params.get("url"))[0]);
803
        if(murl.getProtocol().equals("metacat"))
804
        {//get the document from the database if it is the right type of url
805
          //Hashtable murlParams = murl.getHashParams();
806
          Hashtable murlParams = util.parseQuery(murl.getQuery());
807
          if(murlParams.containsKey("docid"))
808
          {//the docid should be first
809
            docid = (String)murlParams.get("docid"); //get the docid value
810
            conn = util.getConnection();
811
            xmldoc = new DocumentImpl(conn, docid);
812
            String qformat = ((String[])params.get("qformat"))[0];
813
            if (qformat.equals("xml")) 
814
            { 
815
              // set content type and other response header fields first
816
              response.setContentType("text/xml");
817
              xmldoc.toXml(out);
818
              //out.println(xmldoc);
819
            } 
820
            else if (qformat.equals("html")) 
821
            {
822
              response.setContentType("text/html");
823
              // Look up the document type
824
              String sourcetype = xmldoc.getDoctype();
825
              // Transform the document to the new doctype
826
              DBTransform dbt = new DBTransform(conn);
827
              dbt.transformXMLDocument(xmldoc.toString(), sourcetype, 
828
                                 "-//W3C//HTML//EN", out);
829
            }
830

    
831
            util.returnConnection(conn);
832
          }
833
          else
834
          {
835
            //throw new Exception("handleGetDocument: bad URL");
836
            System.err.println("handleGetDocument: bad URL");
837
          }
838
        }
839
        else if(murl.getProtocol().equals("http"))
840
        {//get the document from the internet
841
          //Hashtable murlParams = murl.getHashParams();
842
          Hashtable murlParams = util.parseQuery(murl.getQuery());
843
          if(murlParams.containsKey("httpurl"))
844
          {//httpurl is the param name for an http url.
845
            URL urlconn = new URL((String)murlParams.get("httpurl"));  
846
            //create a new url obj.
847
            //DataInputStream htmldoc = new DataInputStream(urlconn.openStream());
848
            BufferedReader htmldoc = new BufferedReader(
849
                                   new InputStreamReader(urlconn.openStream()));
850
            //bind a data stream.
851
            try
852
            { //display the document
853
              String line=null;
854
              while((line = htmldoc.readLine()) != null)
855
              {
856
                out.println(line); 
857
              }
858
            }
859
            catch(Exception e)
860
            {
861
              util.debugMessage("error viewing html document"); 
862
            }
863
          }
864
        }
865
      }
866
      catch (McdbException e) {
867
        response.setContentType("text/xml");
868
        e.toXml(out);
869
      } catch   (Throwable t) {
870
        response.setContentType("text/html");
871
        out.println(t.getMessage());
872
      } finally {
873
        util.returnConnection(conn);
874
      }
875
    //} // end if
876
  }   
877
  
878
  /** 
879
   * Handle the database read request and return an XML document, 
880
   * possibly transformed from XML into HTML
881
   */
882
  private void handleReadAction(PrintWriter out, Hashtable params, 
883
               HttpServletResponse response) 
884
               throws ClassNotFoundException, IOException, SQLException 
885
  {
886
    out.println(((String[])params.get("docid"))[0]);
887
    try {
888
      //MetacatURL murl = new MetacatURL(((String[])params.get("docid"))[0]);
889
      URL murl = new URL(((String[])params.get("docid"))[0]);
890
      handleGetRelatedDocumentAction(out, params, response, murl);
891
    } catch (MalformedURLException mue) {
892
      handleGetDocumentAction(out, params, response);
893
    }
894
  }
895

    
896
  /** 
897
   * Handle the database read request and return an XML document, 
898
   * possibly transformed from XML into HTML
899
   */
900
  private void handleGetDocumentAction(PrintWriter out, Hashtable params, 
901
               HttpServletResponse response) 
902
               throws ClassNotFoundException, IOException, SQLException {
903
    String docidstr = null;
904
    String docid = null;
905
    String doc = null;
906
    Connection conn = null;
907
    
908
    try {
909
      // Find the document id number
910
      docidstr = ((String[])params.get("docid"))[0]; 
911
      docid = docidstr;
912
      conn = util.getConnection();
913
      DocumentImpl xmldoc = new DocumentImpl(conn, docid);
914
      // Get the document indicated from the db
915
      //doc = docreader.readXMLDocument(docid);
916

    
917
      // Return the document in XML or HTML format
918
      String qformat=null;
919
      if(params.containsKey("qformat"))
920
      {
921
        qformat = ((String[])params.get("qformat"))[0];
922
      }
923
      else
924
      {
925
        qformat = "html";        
926
      }
927
      if (qformat.equals("xml")) { 
928
        // set content type and other response header fields first
929
        response.setContentType("text/xml");
930
        xmldoc.toXml(out);
931
        //out.println(xmldoc);
932
      } else if (qformat.equals("html")) {
933
        response.setContentType("text/html");
934
        // Look up the document type
935
        String sourcetype = xmldoc.getDoctype();
936
        // Transform the document to the new doctype
937
        DBTransform dbt = new DBTransform(conn);
938
        dbt.transformXMLDocument(xmldoc.toString(), sourcetype, 
939
                                 "-//W3C//HTML//EN", out);
940
      }
941
    } catch (McdbException e) {
942
      response.setContentType("text/xml");
943
      e.toXml(out);
944
    } catch (Throwable t) {
945
      response.setContentType("text/html");
946
      out.println(t.getMessage());
947
    } finally {
948
      util.returnConnection(conn);
949
    }    
950

    
951
  }
952

    
953
  /** 
954
   * Handle the database putdocument request and write an XML document 
955
   * to the database connection
956
   */
957
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params, 
958
               HttpServletResponse response, String user, String group) {
959

    
960
    Connection conn = null;
961

    
962
    try {
963
      // Get the document indicated
964
      String[] doctext = (String[])params.get("doctext");
965
      String[] acltext = null;
966

    
967
      StringReader acl = null;
968
      if(params.contains("acl"))
969
      {
970
        acltext = (String[])params.get("acl");
971
        try {
972
          acl = new StringReader(acltext[0]);
973
        } catch (NullPointerException npe) {}
974
      }
975
      
976
      StringReader xml = null;
977
      try {
978
        xml = new StringReader(doctext[0]);
979

    
980
        String[] action = (String[])params.get("action");
981
        String[] docid = (String[])params.get("docid");
982
        String newdocid = null;
983

    
984
        String doAction = null;
985
        if (action[0].equals("insert")) {
986
          doAction = "INSERT";
987
        } else if (action[0].equals("update")) {
988
          doAction = "UPDATE";
989
        }
990

    
991
        try {
992
            // get a connection from the pool
993
            conn = util.getConnection();
994

    
995
            // write the document to the database
996
            try {
997
                String accNumber = docid[0];
998
                if (accNumber.equals("")) {
999
                    accNumber = null;
1000
                }
1001
                newdocid = DocumentImpl.write(conn, xml, acl, doAction,
1002
                                              accNumber, user, group);
1003
                
1004
            } catch (NullPointerException npe) {
1005
              newdocid = DocumentImpl.write(conn, xml, acl, doAction,
1006
                                            null, user, group);
1007
            }
1008
//        } catch (Exception e) {
1009
//          response.setContentType("text/html");
1010
//          out.println(e.getMessage());
1011
        } finally {
1012
          util.returnConnection(conn);
1013
        }    
1014

    
1015
        // set content type and other response header fields first
1016
        response.setContentType("text/xml");
1017
        out.println("<?xml version=\"1.0\"?>");
1018
        out.println("<success>");
1019
        out.println("<docid>" + newdocid + "</docid>"); 
1020
        out.println("</success>");
1021

    
1022
      } catch (NullPointerException npe) {
1023
        response.setContentType("text/xml");
1024
        out.println("<?xml version=\"1.0\"?>");
1025
        out.println("<error>");
1026
        out.println(npe.getMessage()); 
1027
        out.println("</error>");
1028
      }
1029
    } catch (Exception e) {
1030
      response.setContentType("text/xml");
1031
      out.println("<?xml version=\"1.0\"?>");
1032
      out.println("<error>");
1033
      out.println(e.getMessage()); 
1034
      if (e instanceof SAXException) {
1035
        Exception e2 = ((SAXException)e).getException();
1036
        out.println("<error>");
1037
        out.println(e2.getMessage()); 
1038
        out.println("</error>");
1039
      }
1040
      //e.printStackTrace(out);
1041
      out.println("</error>");
1042
    }
1043
  }
1044

    
1045
  /** 
1046
   * Handle the database delete request and delete an XML document 
1047
   * from the database connection
1048
   */
1049
  private void handleDeleteAction(PrintWriter out, Hashtable params, 
1050
               HttpServletResponse response, String user, String group) {
1051

    
1052
    String[] docid = (String[])params.get("docid");
1053
    Connection conn = null;
1054

    
1055
    // delete the document from the database
1056
    try {
1057
      // get a connection from the pool
1058
      conn = util.getConnection();
1059
                                      // NOTE -- NEED TO TEST HERE
1060
                                      // FOR EXISTENCE OF DOCID PARAM
1061
                                      // BEFORE ACCESSING ARRAY
1062
      try { 
1063
        DocumentImpl.delete(conn, docid[0], user, group);
1064
        response.setContentType("text/xml");
1065
        out.println("<?xml version=\"1.0\"?>");
1066
        out.println("<success>");
1067
        out.println("Document deleted."); 
1068
        out.println("</success>");
1069
      } catch (AccessionNumberException ane) {
1070
        response.setContentType("text/xml");
1071
        out.println("<?xml version=\"1.0\"?>");
1072
        out.println("<error>");
1073
        out.println("Error deleting document!!!");
1074
        out.println(ane.getMessage()); 
1075
        out.println("</error>");
1076
      }
1077
    } catch (Exception e) {
1078
      response.setContentType("text/xml");
1079
      out.println("<?xml version=\"1.0\"?>");
1080
      out.println("<error>");
1081
      out.println(e.getMessage()); 
1082
      out.println("</error>");
1083
    } finally {
1084
      util.returnConnection(conn);
1085
    }  
1086
  }
1087
  
1088
  /** 
1089
   * Handle the validation request and return the results to the requestor
1090
   */
1091
  private void handleValidateAction(PrintWriter out, Hashtable params, 
1092
               HttpServletResponse response) {
1093

    
1094
    // Get the document indicated
1095
    String valtext = null;
1096
    
1097
    try {
1098
      valtext = ((String[])params.get("valtext"))[0];
1099
    } catch (Exception nullpe) {
1100

    
1101
      Connection conn = null;
1102
      String docid = null;
1103
      try {
1104
        // Find the document id number
1105
        docid = ((String[])params.get("docid"))[0]; 
1106

    
1107
        // get a connection from the pool
1108
        conn = util.getConnection();
1109

    
1110
        // Get the document indicated from the db
1111
        DocumentImpl xmldoc = new DocumentImpl(conn, docid);
1112
        valtext = xmldoc.toString();
1113

    
1114
      } catch (NullPointerException npe) {
1115
        response.setContentType("text/xml");
1116
        out.println("<error>Error getting document ID: " + docid + "</error>");
1117
        if ( conn != null ) { util.returnConnection(conn); }
1118
        return;
1119
      } catch (Exception e) {
1120
        response.setContentType("text/html");
1121
        out.println(e.getMessage()); 
1122
      } finally {
1123
        util.returnConnection(conn);
1124
      }  
1125
    }
1126

    
1127
    Connection conn = null;
1128
    try {
1129
      // get a connection from the pool
1130
      conn = util.getConnection();
1131
      DBValidate valobj = new DBValidate(saxparser,conn);
1132
      boolean valid = valobj.validateString(valtext);
1133

    
1134
      // set content type and other response header fields first
1135
      response.setContentType("text/xml");
1136
      out.println(valobj.returnErrors());
1137

    
1138
    } catch (NullPointerException npe2) {
1139
      // set content type and other response header fields first
1140
      response.setContentType("text/xml");
1141
      out.println("<error>Error validating document.</error>"); 
1142
    } catch (Exception e) {
1143
      response.setContentType("text/html");
1144
      out.println(e.getMessage()); 
1145
    } finally {
1146
      util.returnConnection(conn);
1147
    }  
1148
  }
1149

    
1150
  /** 
1151
   * Handle the document request and return the results to the requestor
1152
   * If a docid is passed in through the params then that document
1153
   * will be retrieved form the DB and put in the zip file.
1154
   * In addition if 1 or more relations parameters are passed, those file
1155
   * will be zipped as well.  Currently this is only implemented for 
1156
   * metacat:// and http:// files.  Support should be added for srb:// files
1157
   * as well.
1158
   */
1159
  private void handleGetDataDocumentAction(ServletOutputStream out, 
1160
               Hashtable params, 
1161
               HttpServletResponse response) {
1162
  //find the related files, get them from their source and zip them into 
1163
  //a zip file.
1164
  try
1165
  {
1166
    Connection conn = util.getConnection();
1167
    String currentDocid = ((String[])params.get("docid"))[0];
1168
    ZipOutputStream zout = new ZipOutputStream(out);
1169
    byte[] bytestring = null;
1170
    ZipEntry zentry = null;
1171
    DocumentImpl xmldoc = null;
1172
    String[] reldocs = null;
1173
    
1174
    if(params.containsKey("relation"))
1175
    { //get the relations from the parameters.
1176
      reldocs = ((String[])params.get("relation"));
1177
    }
1178
    else
1179
    { //let the for loop know that there are no relations to zip
1180
      reldocs = new String[0];
1181
    }
1182

    
1183
    //write the base file to the zip file.
1184
    xmldoc = new DocumentImpl(conn, currentDocid);
1185
    bytestring = (xmldoc.toString()).getBytes();
1186
    zentry = new ZipEntry(currentDocid + ".xml");
1187
    //create a new zip entry and write the file to the stream
1188
    zentry.setSize(bytestring.length);
1189
    zout.putNextEntry(zentry);
1190
    zout.write(bytestring, 0, bytestring.length);
1191
    zout.closeEntry(); //get ready for the next entry. 
1192

    
1193
    //zip up the related documents
1194
    for(int i=0; i<reldocs.length; i++)
1195
    {
1196
      //MetacatURL murl = new MetacatURL(((String)reldocs[i]));
1197
      URL murl = new URL(((String)reldocs[i]));
1198
      Hashtable qparams = util.parseQuery(murl.getQuery());
1199
      if(murl.getProtocol().equals("metacat"))
1200
      {
1201
        //get the document from the database
1202
        //xmldoc = new DocumentImpl(conn, (String)murl.getHashParam("docid"));
1203
        xmldoc = new DocumentImpl(conn, (String)qparams.get("docid"));
1204
        bytestring = (xmldoc.toString()).getBytes();
1205
        zentry = new ZipEntry(qparams.get("docid") + ".xml");
1206
        //create a new zip entry and write the file to the stream
1207
        zentry.setSize(bytestring.length);
1208
        zout.putNextEntry(zentry);
1209
        zout.write(bytestring, 0, bytestring.length);
1210
        zout.closeEntry(); //get ready for the next entry.
1211
      }
1212
      else if(murl.getProtocol().equals("http"))
1213
      {
1214
        //Hashtable murlParams = murl.getHashParams();
1215
        if(qparams.containsKey("httpurl"))
1216
        {//httpurl is the param name for an http url.
1217
          URL urlconn = new URL((String)qparams.get("httpurl"));  
1218
          //create a new url obj.
1219
          BufferedReader htmldoc = new BufferedReader(
1220
                                   new InputStreamReader(urlconn.openStream()));
1221
          //get the data from the web server
1222
          try
1223
          { //zip the document
1224
            String line=null;
1225
            zentry = new ZipEntry((String)qparams.get("filename"));
1226
            //get just the filename from the URL.
1227
            zout.putNextEntry(zentry);
1228
            //make a new entry in the zip file stream
1229
            while((line = htmldoc.readLine()) != null)
1230
            {
1231
              bytestring = (line.toString()).getBytes();
1232
              zout.write(bytestring, 0, bytestring.length);
1233
              //write out the file line by line
1234
            }
1235
            zout.closeEntry(); //close the entry in the file
1236
          }
1237
          catch(Exception e)
1238
          {
1239
            util.debugMessage("error downloading html document"); 
1240
          }
1241
        }
1242
      }
1243
    }
1244
    zout.finish();  //terminate the zip file
1245
    zout.close();   //close the stream.
1246
    util.returnConnection(conn); //return the connection to the pool
1247
  }
1248
  catch(Exception e)
1249
  {
1250
    System.out.println("Error creating zip file: " + e.getMessage()); 
1251
    e.printStackTrace(System.out);
1252
  }
1253
           
1254
   /*
1255
   //////////old code using a shell script/////////////////////////////////
1256
   
1257
      boolean error_flag = false;
1258
      String error_message = "";
1259
      // Get the document indicated
1260
      String[] datadoc = (String[])params.get("datadoc");
1261
      // defaultdatapath = "C:\\Temp\\";    // for testing only!!!
1262
      // executescript = "test.bat";        // for testing only!!!
1263
      
1264
      // set content type and other response header fields first
1265
      response.setContentType("application/octet-stream");
1266
      if (defaultdatapath!=null) {
1267
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) {
1268
          defaultdatapath=defaultdatapath+System.getProperty("file.separator");
1269
        }
1270
        System.out.println("Path= "+defaultdatapath+datadoc[0]);
1271
        if (executescript!=null) {
1272
          String command = null;
1273
          File scriptfile = new File(executescript);
1274
          if (scriptfile.exists()) {
1275
            command=executescript+" "+datadoc[0]; // script includes path
1276
        } else {     // look in defaultdatapath
1277
            // on Win98 one MUST include the .bat extender
1278
            command = defaultdatapath+executescript+" "+datadoc[0];  
1279
        }
1280
      System.out.println(command);
1281
      try {
1282
      Process proc = Runtime.getRuntime().exec(command);
1283
      proc.waitFor();
1284
      }
1285
      catch (Exception eee) {
1286
        System.out.println("Error running process!");
1287
        error_flag = true;
1288
        error_message = "Error running process!";}
1289
      } // end executescript not null if
1290
      File datafile = new File(defaultdatapath+datadoc[0]);
1291
      try {
1292
      FileInputStream fw = new FileInputStream(datafile);
1293
      int x;
1294
      while ((x = fw.read())!=-1) {
1295
        out.write(x); }
1296
        fw.close();
1297
      } catch (Exception e) {
1298
        System.out.println("Error in returning file\n"+e.getMessage());
1299
        error_flag=true;
1300
        error_message = error_message+"\nError in returning file\n"+
1301
                        e.getMessage();
1302
      }
1303
    } // end defaultdatapath not null if
1304
    */
1305
  }
1306
  
1307
  /** 
1308
   * Handle the getdoctypes Action.
1309
   * Read all doctypes from db connection in XML format
1310
   */
1311
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params, 
1312
                                       HttpServletResponse response) {
1313

    
1314
    Connection conn = null;
1315
    
1316
    try {
1317

    
1318
        // get connection from the pool
1319
        conn = util.getConnection();
1320
        DBUtil dbutil = new DBUtil(conn);
1321
        String doctypes = dbutil.readDoctypes();
1322
        out.println(doctypes);
1323

    
1324
    } catch (Exception e) {
1325
      out.println("<?xml version=\"1.0\"?>");
1326
      out.println("<error>");
1327
      out.println(e.getMessage());
1328
      out.println("</error>");
1329
    } finally {
1330
      util.returnConnection(conn);
1331
    }  
1332
    
1333
  }
1334

    
1335
  /** 
1336
   * Handle the getdataguide Action.
1337
   * Read Data Guide for a given doctype from db connection in XML format
1338
   */
1339
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
1340
                                        HttpServletResponse response) {
1341

    
1342
    Connection conn = null;
1343
    String doctype = null;
1344
    String[] doctypeArr = (String[])params.get("doctype");
1345

    
1346
    // get only the first doctype specified in the list of doctypes
1347
    // it could be done for all doctypes in that list
1348
    if (doctypeArr != null) {
1349
        doctype = ((String[])params.get("doctype"))[0]; 
1350
    }
1351

    
1352
    try {
1353

    
1354
        // get connection from the pool
1355
        conn = util.getConnection();
1356
        DBUtil dbutil = new DBUtil(conn);
1357
        String dataguide = dbutil.readDataGuide(doctype);
1358
        out.println(dataguide);
1359

    
1360
    } catch (Exception e) {
1361
      out.println("<?xml version=\"1.0\"?>");
1362
      out.println("<error>");
1363
      out.println(e.getMessage());
1364
      out.println("</error>");
1365
    } finally {
1366
      util.returnConnection(conn);
1367
    }  
1368
    
1369
  }
1370

    
1371
}
(25-25/36)