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-11-03 09:38:58 -0800 (Fri, 03 Nov 2000) $'
11
 * '$Revision: 510 $'
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 = ((String[])params.get("action"))[0];  
216
    util.debugMessage("Line 213: Action is: " + action);
217

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

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

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

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

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

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

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

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

    
374
  /** 
375
   * Handle the login request. Create a new session object.
376
   * Do user authentication through the session.
377
   */
378
  private void handleLoginAction(PrintWriter out, Hashtable params, 
379
               HttpServletRequest request, HttpServletResponse response) {
380

    
381
    AuthSession sess = null;
382
    String un = ((String[])params.get("username"))[0];
383
    String pw = ((String[])params.get("password"))[0];
384
    String action = ((String[])params.get("action"))[0];
385
    String qformat = ((String[])params.get("qformat"))[0];
386
    
387
    try {
388
      sess = new AuthSession();
389
    } catch (Exception e) {
390
      out.println(e.getMessage());
391
      return;
392
    }
393
    
394
    boolean isValid = sess.authenticate(request, un, pw);
395

    
396
    // format and transform the output
397
    if (qformat.equals("html")) {
398
      Connection conn = null;
399
      try {
400
        conn = util.getConnection();
401
        DBTransform trans = new DBTransform(conn);
402
        response.setContentType("text/html");
403
        trans.transformXMLDocument(sess.getMessage(), "-//NCEAS//login//EN",
404
                                   "-//W3C//HTML//EN", out);
405
        util.returnConnection(conn); 
406
      } catch(Exception e) {
407
        util.returnConnection(conn); 
408
      } 
409
      
410
    // any output is returned  
411
    } else {
412
      response.setContentType("text/xml");
413
      out.println(sess.getMessage()); 
414
    }
415
        
416
/* WITHOUT XSLT transformation
417
    // redirects response to html page
418
    if (qformat.equals("html")) {
419
      // user authentication successful
420
      if (isValid) {
421
        response.sendRedirect(
422
                 response.encodeRedirectUrl(htmlpath + "/metacat.html"));
423
      // unsuccessful user authentication 
424
      } else {
425
        response.sendRedirect(htmlpath + "/login.html");
426
      }
427
    // any output is returned  
428
    } else {
429
      response.setContentType("text/xml");
430
      out.println(sess.getMessage()); 
431
    }
432
*/        
433

    
434
  }    
435

    
436
  /** 
437
   * Handle the logout request. Close the connection.
438
   */
439
  private void handleLogoutAction(PrintWriter out, Hashtable params, 
440
               HttpServletRequest request, HttpServletResponse response) {
441

    
442
    String qformat = ((String[])params.get("qformat"))[0];
443

    
444
    // close the connection
445
    HttpSession sess = request.getSession(false);
446
    if (sess != null) { sess.invalidate();  }    
447

    
448
    // produce output
449
    StringBuffer output = new StringBuffer();
450
    output.append("<?xml version=\"1.0\"?>");
451
    output.append("<logout>");
452
    output.append("User logged out");
453
    output.append("</logout>");
454

    
455
    //format and transform the output
456
    if (qformat.equals("html")) {
457
      Connection conn = null;
458
      try {
459
        conn = util.getConnection();
460
        DBTransform trans = new DBTransform(conn);
461
        response.setContentType("text/html");
462
        trans.transformXMLDocument(output.toString(), "-//NCEAS//login//EN", 
463
                                   "-//W3C//HTML//EN", out);
464
        util.returnConnection(conn); 
465
      } catch(Exception e) {
466
        util.returnConnection(conn); 
467
      } 
468
    // any output is returned  
469
    } else {
470
      response.setContentType("text/xml");
471
      out.println(output.toString()); 
472
    }
473

    
474
/* WITHOUT XSLT transformation
475
    // redirects response to html page
476
    if (qformat.equals("html")) {
477
        response.sendRedirect(htmlpath + "/index.html"); 
478
      } catch(Exception e) {
479
        util.returnConnection(conn); 
480
      } 
481
    // any output is returned  
482
    } else {
483
      response.setContentType("text/xml");
484
      out.println(output.toString()); 
485
    }
486
*/
487
  }
488

    
489
  
490
  /**      
491
   * Retreive the squery xml, execute it and display it
492
   *
493
   * @param out the output stream to the client
494
   * @param params the Hashtable of parameters that should be included
495
   * in the squery.
496
   * @param response the response object linked to the client
497
   * @param conn the database connection 
498
   */
499
  protected void handleSQuery(PrintWriter out, Hashtable params, 
500
                 HttpServletResponse response, String user, String group)
501
  { 
502
    String xmlquery = ((String[])params.get("query"))[0];
503
    String qformat = ((String[])params.get("qformat"))[0];
504
    String resultdoc = null;
505
    String[] returndoc = null;
506
    if(params.contains("returndoc"))
507
    {
508
      returndoc = (String[])params.get("returndoc");
509
    }
510
    
511
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
512
    //String resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
513

    
514
    resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
515
    
516
    //format and transform the results                                        
517
    if(qformat.equals("html")) {
518
      transformResultset(resultdoc, response, out);
519
    } else if(qformat.equals("xml")) {
520
      response.setContentType("text/xml");
521
      out.println(resultdoc);
522
    } else {
523
      out.println("invalid qformat: " + qformat); 
524
    }
525
  }
526
  
527
   /**
528
    * Create the xml query, execute it and display the results.
529
    *
530
    * @param out the output stream to the client
531
    * @param params the Hashtable of parameters that should be included
532
    * in the squery.
533
    * @param response the response object linked to the client
534
    */ 
535
  protected void handleQuery(PrintWriter out, Hashtable params, 
536
                 HttpServletResponse response, String user, String group)
537
  {
538
    //create the query and run it
539
    String[] returndoc = null;
540
    if(params.containsKey("returndoc"))
541
    {
542
      returndoc = (String[])params.get("returndoc");
543
    }
544
    String xmlquery = DBQuery.createSQuery(params);
545
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
546
    String qformat = ((String[])params.get("qformat"))[0];
547
    String resultdoc = null;
548
    
549
    resultdoc = createResultDocument(doclist, transformQuery(params));
550

    
551
    //format and transform the results                                        
552
    if(qformat.equals("html")) {
553
      transformResultset(resultdoc, response, out);
554
    } else if(qformat.equals("xml")) {
555
      response.setContentType("text/xml");
556
      out.println(resultdoc);
557
    } else { 
558
      out.println("invalid qformat: " + qformat); 
559
    }
560
  }
561
  
562
  /**
563
   * Removes the <?xml version="x"?> tag from the beginning of xmlquery
564
   * so it can properly be placed in the <query> tag of the resultset.
565
   * This method is overwritable so that other applications can customize
566
   * the structure of what is in the <query> tag.
567
   * 
568
   * @param xmlquery is the query to remove the <?xml version="x"?> tag from.
569
   */
570
  protected String transformQuery(Hashtable params)
571
  {
572
    //DBQuery.createSQuery is a re-calling of a previously called 
573
    //function but it is necessary
574
    //so that overriding methods have access to the params hashtable
575
    String xmlquery = DBQuery.createSQuery(params);
576
    //the <?xml version="1.0"?> tag is the first 22 characters of the
577
    xmlquery = xmlquery.trim();
578
    int index = xmlquery.indexOf("?>");
579
    return xmlquery.substring(index + 2, xmlquery.length());
580
  }
581
  
582
  /**
583
   * removes the <?xml version="1.0"?> tag from the beginning.  This takes a
584
   * string as a param instead of a hashtable.
585
   * 
586
   * @param xmlquery a string representing a query.
587
   */
588
  protected String transformQuery(String xmlquery)
589
  {
590
    xmlquery = xmlquery.trim();
591
    int index = xmlquery.indexOf("?>");
592
    return xmlquery.substring(index + 2, xmlquery.length());
593
  }
594
  
595
  /**
596
   * Run the query and return a hashtable of results.
597
   *
598
   * @param xmlquery the query to run
599
   */
600
  private Hashtable runQuery(String xmlquery, String user, String group, 
601
                             String[] returndoc)
602
  {
603
    Hashtable doclist=null;
604
    Connection conn = null;
605
    try
606
    {
607
      conn = util.getConnection();
608
      DBQuery queryobj = new DBQuery(conn, saxparser);
609
      doclist = queryobj.findDocuments(new StringReader(xmlquery),user,group,
610
                                       returndoc);
611
      util.returnConnection(conn);
612
      return doclist;
613
    } 
614
    catch (Exception e) 
615
    {
616
      util.returnConnection(conn); 
617
      util.debugMessage("Error in runQuery: " + e.getMessage());
618
      doclist = null;
619
      return doclist;
620
    }    
621
  }
622
  
623
  /**
624
   * Transorms an xml resultset document to html and sends it to the browser
625
   *
626
   * @param resultdoc the string representation of the document that needs
627
   * to be transformed.
628
   * @param response the HttpServletResponse object bound to the client.
629
   * @param out the output stream to the client
630
   */ 
631
  protected void transformResultset(String resultdoc, 
632
                                    HttpServletResponse response,
633
                                    PrintWriter out)
634
  {
635
    Connection conn = null;
636
    try {
637
      conn = util.getConnection();
638
      DBTransform trans = new DBTransform(conn);
639
      response.setContentType("text/html");
640
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN", 
641
                                 "-//W3C//HTML//EN", out);
642
      util.returnConnection(conn); 
643
    }
644
    catch(Exception e)
645
    {
646
      util.returnConnection(conn); 
647
    } 
648
  }
649
  
650
  /**
651
   * Transforms a hashtable of documents to an xml or html result.
652
   * If there is a returndoc, then it only displays documents of
653
   * whatever type returndoc represents.  If a result is found in a document
654
   * that is not of type returndoc then this attempts to find a relation 
655
   * between this document and one that satifies the returndoc doctype.
656
   *
657
   * @param doclist- the hashtable to transform
658
   * @param xmlquery- the query that returned the dolist result
659
   * @param resultdoc- the document type to backtrack to.
660
   */
661
  protected String createResultDocument(Hashtable doclist, String xmlquery)
662
  {
663
    // Create a buffer to hold the xml result
664
    StringBuffer resultset = new StringBuffer();
665
 
666
    // Print the resulting root nodes 
667
    String docid = null;
668
    String document = null;
669
    resultset.append("<?xml version=\"1.0\"?>\n");
670
    resultset.append("<resultset>\n");
671
      
672
    resultset.append("  <query>" + xmlquery + "</query>");   
673

    
674
    if(doclist != null)
675
    {
676
      Enumeration doclistkeys = doclist.keys(); 
677
      while (doclistkeys.hasMoreElements()) 
678
      {
679
        docid = (String)doclistkeys.nextElement();
680
        document = (String)doclist.get(docid);
681
        resultset.append("  <document>" + document + "</document>");
682
      }
683
    }
684

    
685
    resultset.append("</resultset>");
686
    //System.out.println(resultset.toString());
687
    return resultset.toString();
688
  }
689
  
690
  /**
691
   * Handle the request to view the abstract of a document.
692
   * The abstractpath CGI parameter gives the xml path to the abstract
693
   * node.  
694
   */
695
  private void handleViewAbstractAction(PrintWriter out, Hashtable params,
696
               HttpServletResponse response) throws IOException, SQLException
697
  {
698
    String abstractpath = null;
699
    String docid = null;
700
    Connection conn = null;
701
    response.setContentType("text/html");
702
    try
703
    {
704
      docid = ((String[])params.get("docid"))[0];
705
      if(params.containsKey("abstractpath"))
706
      {
707
        //the CGI parameter abstractpath holds the path to the abstract
708
        //that should be displayed.
709
        abstractpath = ((String[])params.get("abstractpath"))[0];
710
      }
711
      else
712
      {
713
        out.println("error: no abstractpath parameter"); 
714
      }
715
      conn = util.getConnection();
716
    
717
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid, conn);
718
    
719
      out.println("<html><head><title>Abstract</title></head>");
720
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
721
      for(int i=0; i<abstracts.length; i++)
722
      {
723
        out.println("<p>" + (String)abstracts[i] + "</p>");
724
      }
725
      out.println("</body></html>");
726
    }
727
    catch (IOException ioe)
728
    {
729
       util.debugMessage("error in handlegetabstract: " + ioe.getMessage());
730
    }
731
    catch(SQLException sqle)
732
    {
733
      util.debugMessage("error in handlegetabstract: " + sqle.getMessage()); 
734
    }
735
    catch(Exception e)
736
    {
737
      util.debugMessage("error in handlegetabstract: " + e.getMessage());
738
    }
739
    
740
    util.returnConnection(conn);
741
  }
742

    
743
  /** 
744
   * Handle the database getrelateddocument request and return a XML document, 
745
   * possibly transformed from XML into HTML
746
   */
747
  private void handleGetRelatedDocumentAction(PrintWriter out, Hashtable params, 
748
               HttpServletResponse response) 
749
               throws ClassNotFoundException, IOException, SQLException 
750
  {
751
    String docid = null;
752
    Connection conn = null;
753
      
754
    if(params.containsKey("url"))
755
    {//the identifier for the related document is contained in the URL param
756
      try
757
      {
758
        DocumentImpl xmldoc=null;
759
        metacatURL murl = new metacatURL(((String[])params.get("url"))[0]);
760
        if(murl.getURLType().equals("metacat"))
761
        {//get the document from the database if it is the right type of url
762
          Hashtable murlParams = murl.getHashParams();
763
          if(murlParams.containsKey("docid"))
764
          {//the docid should be first
765
            docid = (String)murlParams.get("docid"); //get the docid value
766
            conn = util.getConnection();
767
            xmldoc = new DocumentImpl(conn, docid);
768
            String qformat = ((String[])params.get("qformat"))[0];
769
            if (qformat.equals("xml")) 
770
            { 
771
              // set content type and other response header fields first
772
              response.setContentType("text/xml");
773
              xmldoc.toXml(out);
774
              //out.println(xmldoc);
775
            } 
776
            else if (qformat.equals("html")) 
777
            {
778
              response.setContentType("text/html");
779
              // Look up the document type
780
              String sourcetype = xmldoc.getDoctype();
781
              // Transform the document to the new doctype
782
              DBTransform dbt = new DBTransform(conn);
783
              dbt.transformXMLDocument(xmldoc.toString(), sourcetype, 
784
                                 "-//W3C//HTML//EN", out);
785
            }
786

    
787
            util.returnConnection(conn);
788
          }
789
          else
790
          {
791
            //throw new Exception("handleGetDocument: bad URL");
792
            System.err.println("handleGetDocument: bad URL");
793
          }
794
        }
795
        else if(murl.getURLType().equals("http"))
796
        {//get the document from the internet
797
          Hashtable murlParams = murl.getHashParams();
798
          if(murlParams.containsKey("httpurl"))
799
          {//httpurl is the param name for an http url.
800
            URL urlconn = new URL((String)murlParams.get("httpurl"));  
801
            //create a new url obj.
802
            //DataInputStream htmldoc = new DataInputStream(urlconn.openStream());
803
            BufferedReader htmldoc = new BufferedReader(
804
                                   new InputStreamReader(urlconn.openStream()));
805
            //bind a data stream.
806
            try
807
            { //display the document
808
              String line=null;
809
              while((line = htmldoc.readLine()) != null)
810
              {
811
                out.println(line); 
812
              }
813
            }
814
            catch(Exception e)
815
            {
816
              util.debugMessage("error viewing html document"); 
817
            }
818
          }
819
        }
820
      }
821
      catch (McdbException e) {
822
        response.setContentType("text/xml");
823
        e.toXml(out);
824
      } catch   (Throwable t) {
825
        response.setContentType("text/html");
826
        out.println(t.getMessage());
827
      } finally {
828
        util.returnConnection(conn);
829
      }
830
    }
831
  }   
832
  
833
  /** 
834
   * Handle the database getdocument request and return a XML document, 
835
   * possibly transformed from XML into HTML
836
   */
837
  private void handleGetDocumentAction(PrintWriter out, Hashtable params, 
838
               HttpServletResponse response) 
839
               throws ClassNotFoundException, IOException, SQLException {
840
    String docidstr = null;
841
    String docid = null;
842
    String doc = null;
843
    Connection conn = null;
844
    
845
    try {
846
      // Find the document id number
847
      docidstr = ((String[])params.get("docid"))[0]; 
848
      docid = docidstr;
849
      conn = util.getConnection();
850
      DocumentImpl xmldoc = new DocumentImpl(conn, docid);
851
      // Get the document indicated from the db
852
      //doc = docreader.readXMLDocument(docid);
853

    
854
      // Return the document in XML or HTML format
855
      String qformat=null;
856
      if(params.containsKey("qformat"))
857
      {
858
        qformat = ((String[])params.get("qformat"))[0];
859
      }
860
      else
861
      {
862
        qformat = "html";        
863
      }
864
      if (qformat.equals("xml")) { 
865
        // set content type and other response header fields first
866
        response.setContentType("text/xml");
867
        xmldoc.toXml(out);
868
        //out.println(xmldoc);
869
      } else if (qformat.equals("html")) {
870
        response.setContentType("text/html");
871
        // Look up the document type
872
        String sourcetype = xmldoc.getDoctype();
873
        // Transform the document to the new doctype
874
        DBTransform dbt = new DBTransform(conn);
875
        dbt.transformXMLDocument(xmldoc.toString(), sourcetype, 
876
                                 "-//W3C//HTML//EN", out);
877
      }
878
    } catch (McdbException e) {
879
      response.setContentType("text/xml");
880
      e.toXml(out);
881
    } catch (Throwable t) {
882
      response.setContentType("text/html");
883
      out.println(t.getMessage());
884
    } finally {
885
      util.returnConnection(conn);
886
    }    
887

    
888
  }
889

    
890
  /** 
891
   * Handle the database putdocument request and write an XML document 
892
   * to the database connection
893
   */
894
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params, 
895
               HttpServletResponse response, String user, String group) {
896

    
897
    Connection conn = null;
898

    
899
    try {
900
      // Get the document indicated
901
      String[] doctext = (String[])params.get("doctext");
902
      StringReader xml = null;
903
      try {
904
        xml = new StringReader(doctext[0]);
905

    
906
        String[] action = (String[])params.get("action");
907
        String[] docid = (String[])params.get("docid");
908
        String newdocid = null;
909

    
910
        String doAction = null;
911
        if (action[0].equals("insert")) {
912
          doAction = "INSERT";
913
        } else if (action[0].equals("update")) {
914
          doAction = "UPDATE";
915
        }
916

    
917
        try {
918
            // get a connection from the pool
919
            conn = util.getConnection();
920

    
921
            // write the document to the database
922
            try {
923
                String accNumber = docid[0];
924
                if (accNumber.equals("")) {
925
                    accNumber = null;
926
                }
927
                newdocid = DocumentImpl.write(conn, xml, doAction, accNumber, 
928
                                              user, group);
929
                
930
            } catch (NullPointerException npe) {
931
              newdocid = DocumentImpl.write(conn,xml,doAction,null,user,group);
932
            }
933
//        } catch (Exception e) {
934
//          response.setContentType("text/html");
935
//          out.println(e.getMessage());
936
        } finally {
937
          util.returnConnection(conn);
938
        }    
939

    
940
        // set content type and other response header fields first
941
        response.setContentType("text/xml");
942
        out.println("<?xml version=\"1.0\"?>");
943
        out.println("<success>");
944
        out.println("<docid>" + newdocid + "</docid>"); 
945
        out.println("</success>");
946

    
947
      } catch (NullPointerException npe) {
948
        response.setContentType("text/xml");
949
        out.println("<?xml version=\"1.0\"?>");
950
        out.println("<error>");
951
        out.println(npe.getMessage()); 
952
        out.println("</error>");
953
      }
954
    } catch (Exception e) {
955
      response.setContentType("text/xml");
956
      out.println("<?xml version=\"1.0\"?>");
957
      out.println("<error>");
958
      out.println(e.getMessage()); 
959
      if (e instanceof SAXException) {
960
        Exception e2 = ((SAXException)e).getException();
961
        out.println("<error>");
962
        out.println(e2.getMessage()); 
963
        out.println("</error>");
964
      }
965
      //e.printStackTrace(out);
966
      out.println("</error>");
967
    }
968
  }
969

    
970
  /** 
971
   * Handle the database delete request and delete an XML document 
972
   * from the database connection
973
   */
974
  private void handleDeleteAction(PrintWriter out, Hashtable params, 
975
               HttpServletResponse response, String user, String group) {
976

    
977
    String[] docid = (String[])params.get("docid");
978
    Connection conn = null;
979

    
980
    // delete the document from the database
981
    try {
982
      // get a connection from the pool
983
      conn = util.getConnection();
984
                                      // NOTE -- NEED TO TEST HERE
985
                                      // FOR EXISTENCE OF DOCID PARAM
986
                                      // BEFORE ACCESSING ARRAY
987
      try { 
988
        DocumentImpl.delete(conn, docid[0], user, group);
989
        response.setContentType("text/xml");
990
        out.println("<?xml version=\"1.0\"?>");
991
        out.println("<success>");
992
        out.println("Document deleted."); 
993
        out.println("</success>");
994
      } catch (AccessionNumberException ane) {
995
        response.setContentType("text/xml");
996
        out.println("<?xml version=\"1.0\"?>");
997
        out.println("<error>");
998
        out.println("Error deleting document!!!");
999
        out.println(ane.getMessage()); 
1000
        out.println("</error>");
1001
      }
1002
    } catch (Exception e) {
1003
      response.setContentType("text/xml");
1004
      out.println("<?xml version=\"1.0\"?>");
1005
      out.println("<error>");
1006
      out.println(e.getMessage()); 
1007
      out.println("</error>");
1008
    } finally {
1009
      util.returnConnection(conn);
1010
    }  
1011
  }
1012
  
1013
  /** 
1014
   * Handle the validation request and return the results to the requestor
1015
   */
1016
  private void handleValidateAction(PrintWriter out, Hashtable params, 
1017
               HttpServletResponse response) {
1018

    
1019
    // Get the document indicated
1020
    String valtext = null;
1021
    
1022
    try {
1023
      valtext = ((String[])params.get("valtext"))[0];
1024
    } catch (Exception nullpe) {
1025

    
1026
      Connection conn = null;
1027
      String docid = null;
1028
      try {
1029
        // Find the document id number
1030
        docid = ((String[])params.get("docid"))[0]; 
1031

    
1032
        // get a connection from the pool
1033
        conn = util.getConnection();
1034

    
1035
        // Get the document indicated from the db
1036
        DocumentImpl xmldoc = new DocumentImpl(conn, docid);
1037
        valtext = xmldoc.toString();
1038

    
1039
      } catch (NullPointerException npe) {
1040
        response.setContentType("text/xml");
1041
        out.println("<error>Error getting document ID: " + docid + "</error>");
1042
        if ( conn != null ) { util.returnConnection(conn); }
1043
        return;
1044
      } catch (Exception e) {
1045
        response.setContentType("text/html");
1046
        out.println(e.getMessage()); 
1047
      } finally {
1048
        util.returnConnection(conn);
1049
      }  
1050
    }
1051

    
1052
    Connection conn = null;
1053
    try {
1054
      // get a connection from the pool
1055
      conn = util.getConnection();
1056
      DBValidate valobj = new DBValidate(saxparser,conn);
1057
      boolean valid = valobj.validateString(valtext);
1058

    
1059
      // set content type and other response header fields first
1060
      response.setContentType("text/xml");
1061
      out.println(valobj.returnErrors());
1062

    
1063
    } catch (NullPointerException npe2) {
1064
      // set content type and other response header fields first
1065
      response.setContentType("text/xml");
1066
      out.println("<error>Error validating document.</error>"); 
1067
    } catch (Exception e) {
1068
      response.setContentType("text/html");
1069
      out.println(e.getMessage()); 
1070
    } finally {
1071
      util.returnConnection(conn);
1072
    }  
1073
  }
1074

    
1075
  /** 
1076
   * Handle the document request and return the results to the requestor
1077
   * If a docid is passed in through the params then that document
1078
   * will be retrieved form the DB and put in the zip file.
1079
   * In addition if 1 or more relations parameters are passed, those file
1080
   * will be zipped as well.  Currently this is only implemented for 
1081
   * metacat:// and http:// files.  Support should be added for srb:// files
1082
   * as well.
1083
   */
1084
  private void handleGetDataDocumentAction(ServletOutputStream out, 
1085
               Hashtable params, 
1086
               HttpServletResponse response) {
1087
  //find the related files, get them from their source and zip them into 
1088
  //a zip file.
1089
  try
1090
  {
1091
    Connection conn = util.getConnection();
1092
    String currentDocid = ((String[])params.get("docid"))[0];
1093
    ZipOutputStream zout = new ZipOutputStream(out);
1094
    byte[] bytestring = null;
1095
    ZipEntry zentry = null;
1096
    DocumentImpl xmldoc = null;
1097
    String[] reldocs = null;
1098
    
1099
    if(params.containsKey("relation"))
1100
    { //get the relations from the parameters.
1101
      reldocs = ((String[])params.get("relation"));
1102
    }
1103
    else
1104
    { //let the for loop know that there are no relations to zip
1105
      reldocs = new String[0];
1106
    }
1107

    
1108
    //write the base file to the zip file.
1109
    xmldoc = new DocumentImpl(conn, currentDocid);
1110
    bytestring = (xmldoc.toString()).getBytes();
1111
    zentry = new ZipEntry(currentDocid + ".xml");
1112
    //create a new zip entry and write the file to the stream
1113
    zentry.setSize(bytestring.length);
1114
    zout.putNextEntry(zentry);
1115
    zout.write(bytestring, 0, bytestring.length);
1116
    zout.closeEntry(); //get ready for the next entry. 
1117

    
1118
    //zip up the related documents
1119
    for(int i=0; i<reldocs.length; i++)
1120
    {
1121
      metacatURL murl = new metacatURL(((String)reldocs[i]));
1122
      if(murl.getURLType().equals("metacat"))
1123
      {
1124
        //get the document from the database
1125
        xmldoc = new DocumentImpl(conn, (String)murl.getHashParam("docid"));
1126
        bytestring = (xmldoc.toString()).getBytes();
1127
        zentry = new ZipEntry(murl.getHashParam("docid") + ".xml");
1128
        //create a new zip entry and write the file to the stream
1129
        zentry.setSize(bytestring.length);
1130
        zout.putNextEntry(zentry);
1131
        zout.write(bytestring, 0, bytestring.length);
1132
        zout.closeEntry(); //get ready for the next entry.
1133
      }
1134
      else if(murl.getURLType().equals("http"))
1135
      {
1136
        Hashtable murlParams = murl.getHashParams();
1137
        if(murlParams.containsKey("httpurl"))
1138
        {//httpurl is the param name for an http url.
1139
          URL urlconn = new URL((String)murlParams.get("httpurl"));  
1140
          //create a new url obj.
1141
          BufferedReader htmldoc = new BufferedReader(
1142
                                   new InputStreamReader(urlconn.openStream()));
1143
          //get the data from the web server
1144
          try
1145
          { //zip the document
1146
            String line=null;
1147
            zentry = new ZipEntry((String)murlParams.get("filename"));
1148
            //get just the filename from the URL.
1149
            zout.putNextEntry(zentry);
1150
            //make a new entry in the zip file stream
1151
            while((line = htmldoc.readLine()) != null)
1152
            {
1153
              bytestring = (line.toString()).getBytes();
1154
              zout.write(bytestring, 0, bytestring.length);
1155
              //write out the file line by line
1156
            }
1157
            zout.closeEntry(); //close the entry in the file
1158
          }
1159
          catch(Exception e)
1160
          {
1161
            util.debugMessage("error downloading html document"); 
1162
          }
1163
        }
1164
      }
1165
    }
1166
    zout.finish();  //terminate the zip file
1167
    zout.close();   //close the stream.
1168
    util.returnConnection(conn); //return the connection to the pool
1169
  }
1170
  catch(Exception e)
1171
  {
1172
    System.out.println("Error creating zip file: " + e.getMessage()); 
1173
    e.printStackTrace(System.out);
1174
  }
1175
           
1176
   /*
1177
   //////////old code using a shell script/////////////////////////////////
1178
   
1179
      boolean error_flag = false;
1180
      String error_message = "";
1181
      // Get the document indicated
1182
      String[] datadoc = (String[])params.get("datadoc");
1183
      // defaultdatapath = "C:\\Temp\\";    // for testing only!!!
1184
      // executescript = "test.bat";        // for testing only!!!
1185
      
1186
      // set content type and other response header fields first
1187
      response.setContentType("application/octet-stream");
1188
      if (defaultdatapath!=null) {
1189
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) {
1190
          defaultdatapath=defaultdatapath+System.getProperty("file.separator");
1191
        }
1192
        System.out.println("Path= "+defaultdatapath+datadoc[0]);
1193
        if (executescript!=null) {
1194
          String command = null;
1195
          File scriptfile = new File(executescript);
1196
          if (scriptfile.exists()) {
1197
            command=executescript+" "+datadoc[0]; // script includes path
1198
        } else {     // look in defaultdatapath
1199
            // on Win98 one MUST include the .bat extender
1200
            command = defaultdatapath+executescript+" "+datadoc[0];  
1201
        }
1202
      System.out.println(command);
1203
      try {
1204
      Process proc = Runtime.getRuntime().exec(command);
1205
      proc.waitFor();
1206
      }
1207
      catch (Exception eee) {
1208
        System.out.println("Error running process!");
1209
        error_flag = true;
1210
        error_message = "Error running process!";}
1211
      } // end executescript not null if
1212
      File datafile = new File(defaultdatapath+datadoc[0]);
1213
      try {
1214
      FileInputStream fw = new FileInputStream(datafile);
1215
      int x;
1216
      while ((x = fw.read())!=-1) {
1217
        out.write(x); }
1218
        fw.close();
1219
      } catch (Exception e) {
1220
        System.out.println("Error in returning file\n"+e.getMessage());
1221
        error_flag=true;
1222
        error_message = error_message+"\nError in returning file\n"+
1223
                        e.getMessage();
1224
      }
1225
    } // end defaultdatapath not null if
1226
    */
1227
  }
1228
  
1229
  /** 
1230
   * Handle the getdoctypes Action.
1231
   * Read all doctypes from db connection in XML format
1232
   */
1233
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params, 
1234
                                       HttpServletResponse response) {
1235

    
1236
    Connection conn = null;
1237
    
1238
    try {
1239

    
1240
        // get connection from the pool
1241
        conn = util.getConnection();
1242
        DBUtil dbutil = new DBUtil(conn);
1243
        String doctypes = dbutil.readDoctypes();
1244
        out.println(doctypes);
1245

    
1246
    } catch (Exception e) {
1247
      out.println("<?xml version=\"1.0\"?>");
1248
      out.println("<error>");
1249
      out.println(e.getMessage());
1250
      out.println("</error>");
1251
    } finally {
1252
      util.returnConnection(conn);
1253
    }  
1254
    
1255
  }
1256

    
1257
  /** 
1258
   * Handle the getdataguide Action.
1259
   * Read Data Guide for a given doctype from db connection in XML format
1260
   */
1261
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
1262
                                        HttpServletResponse response) {
1263

    
1264
    Connection conn = null;
1265
    String doctype = null;
1266
    String[] doctypeArr = (String[])params.get("doctype");
1267

    
1268
    // get only the first doctype specified in the list of doctypes
1269
    // it could be done for all doctypes in that list
1270
    if (doctypeArr != null) {
1271
        doctype = ((String[])params.get("doctype"))[0]; 
1272
    }
1273

    
1274
    try {
1275

    
1276
        // get connection from the pool
1277
        conn = util.getConnection();
1278
        DBUtil dbutil = new DBUtil(conn);
1279
        String dataguide = dbutil.readDataGuide(doctype);
1280
        out.println(dataguide);
1281

    
1282
    } catch (Exception e) {
1283
      out.println("<?xml version=\"1.0\"?>");
1284
      out.println("<error>");
1285
      out.println(e.getMessage());
1286
      out.println("</error>");
1287
    } finally {
1288
      util.returnConnection(conn);
1289
    }  
1290
    
1291
  }
1292

    
1293
}
(23-23/33)