Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements a metadata catalog as a java Servlet
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Matt Jones, Dan Higgins, Jivka Bojilova, Chad Berkley
7
 *    Release: @release@
8
 *
9
 *   '$Author: berkley $'
10
 *     '$Date: 2000-10-03 14:23:59 -0700 (Tue, 03 Oct 2000) $'
11
 * '$Revision: 486 $'
12
 */
13

    
14
package edu.ucsb.nceas.metacat;
15

    
16
import java.io.PrintWriter;
17
import java.io.IOException;
18
import java.io.Reader;
19
import java.io.StringReader;
20
import java.io.BufferedReader;
21
import java.io.File;
22
import java.io.FileInputStream;
23
import java.io.FileOutputStream;
24
import java.io.InputStreamReader;
25
import java.io.DataInputStream;
26
import java.util.Enumeration;
27
import java.util.Hashtable;
28
import java.util.ResourceBundle; 
29
import java.util.PropertyResourceBundle;
30
import java.net.URL;
31
import java.net.MalformedURLException;
32
import java.sql.PreparedStatement;
33
import java.sql.ResultSet;
34
import java.sql.Connection;
35
import java.sql.SQLException;
36
import java.lang.reflect.*;
37
import java.net.*;
38
import java.util.zip.*;
39

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

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

    
56
import org.xml.sax.SAXException;
57

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

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

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

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

    
116
      util = new MetaCatUtil();
117

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
586
    if(doclist != null)
587
    {
588
      Enumeration doclistkeys = doclist.keys(); 
589
      while (doclistkeys.hasMoreElements()) 
590
      {
591
        docid = (String)doclistkeys.nextElement();
592
        document = (String)doclist.get(docid);
593
        resultset.append("  <document>" + document + "</document>");
594
      }
595
    }
596

    
597
    resultset.append("</resultset>");
598
    //System.out.println(resultset.toString());
599
    return resultset.toString();
600
  }
601
  
602
  /**
603
   * Handle the request to view the abstract of a document.
604
   * The abstractpath CGI parameter gives the xml path to the abstract
605
   * node.  
606
   */
607
  private void handleViewAbstractAction(PrintWriter out, Hashtable params,
608
               HttpServletResponse response) throws IOException, SQLException
609
  {
610
    String abstractpath = null;
611
    String docid = null;
612
    Connection conn = null;
613
    response.setContentType("text/html");
614
    try
615
    {
616
      docid = ((String[])params.get("docid"))[0];
617
      if(params.containsKey("abstractpath"))
618
      {
619
        //the CGI parameter abstractpath holds the path to the abstract
620
        //that should be displayed.
621
        abstractpath = ((String[])params.get("abstractpath"))[0];
622
      }
623
      else
624
      {
625
        out.println("error: no abstractpath parameter"); 
626
      }
627
      conn = util.getConnection();
628
    
629
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid, conn);
630
    
631
      out.println("<html><head><title>Abstract</title></head>");
632
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
633
      for(int i=0; i<abstracts.length; i++)
634
      {
635
        out.println("<p>" + (String)abstracts[i] + "</p>");
636
      }
637
      out.println("</body></html>");
638
    }
639
    catch (IOException ioe)
640
    {
641
       util.debugMessage("error in handlegetabstract: " + ioe.getMessage());
642
    }
643
    catch(SQLException sqle)
644
    {
645
      util.debugMessage("error in handlegetabstract: " + sqle.getMessage()); 
646
    }
647
    catch(Exception e)
648
    {
649
      util.debugMessage("error in handlegetabstract: " + e.getMessage());
650
    }
651
    
652
    util.returnConnection(conn);
653
  }
654

    
655
  /** 
656
   * Handle the database getrelateddocument request and return a XML document, 
657
   * possibly transformed from XML into HTML
658
   */
659
  private void handleGetRelatedDocumentAction(PrintWriter out, Hashtable params, 
660
               HttpServletResponse response) 
661
               throws ClassNotFoundException, IOException, SQLException 
662
  {
663
    String docid = null;
664
    Connection conn = null;
665
      
666
    if(params.containsKey("url"))
667
    {//the identifier for the related document is contained in the URL param
668
      try
669
      {
670
        DocumentImpl xmldoc=null;
671
        metacatURL murl = new metacatURL(((String[])params.get("url"))[0]);
672
        if(murl.getURLType().equals("metacat"))
673
        {//get the document from the database if it is the right type of url
674
          Hashtable murlParams = murl.getHashParams();
675
          if(murlParams.containsKey("docid"))
676
          {//the docid should be first
677
            docid = (String)murlParams.get("docid"); //get the docid value
678
            conn = util.getConnection();
679
            xmldoc = new DocumentImpl(conn, docid);
680
            String qformat = ((String[])params.get("qformat"))[0];
681
            if (qformat.equals("xml")) 
682
            { 
683
              // set content type and other response header fields first
684
              response.setContentType("text/xml");
685
              xmldoc.toXml(out);
686
              //out.println(xmldoc);
687
            } 
688
            else if (qformat.equals("html")) 
689
            {
690
              response.setContentType("text/html");
691
              // Look up the document type
692
              String sourcetype = xmldoc.getDoctype();
693
              // Transform the document to the new doctype
694
              DBTransform dbt = new DBTransform(conn);
695
              dbt.transformXMLDocument(xmldoc.toString(), sourcetype, 
696
                                 "-//W3C//HTML//EN", out);
697
            }
698

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

    
766
      // Return the document in XML or HTML format
767
      String qformat=null;
768
      if(params.containsKey("qformat"))
769
      {
770
        qformat = ((String[])params.get("qformat"))[0];
771
      }
772
      else
773
      {
774
        qformat = "html";        
775
      }
776
      if (qformat.equals("xml")) { 
777
        // set content type and other response header fields first
778
        response.setContentType("text/xml");
779
        xmldoc.toXml(out);
780
        //out.println(xmldoc);
781
      } else if (qformat.equals("html")) {
782
        response.setContentType("text/html");
783
        // Look up the document type
784
        String sourcetype = xmldoc.getDoctype();
785
        // Transform the document to the new doctype
786
        DBTransform dbt = new DBTransform(conn);
787
        dbt.transformXMLDocument(xmldoc.toString(), sourcetype, 
788
                                 "-//W3C//HTML//EN", out);
789
      }
790
    } catch (McdbException e) {
791
      response.setContentType("text/xml");
792
      e.toXml(out);
793
    } catch (Throwable t) {
794
      response.setContentType("text/html");
795
      out.println(t.getMessage());
796
    } finally {
797
      util.returnConnection(conn);
798
    }    
799

    
800
  }
801

    
802
  /** 
803
   * Handle the database putdocument request and write an XML document 
804
   * to the database connection
805
   */
806
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params, 
807
               HttpServletResponse response, String user, String group) {
808

    
809
    Connection conn = null;
810

    
811
    try {
812
      // Get the document indicated
813
      String[] doctext = (String[])params.get("doctext");
814
      StringReader xml = null;
815
      try {
816
        xml = new StringReader(doctext[0]);
817

    
818
        String[] action = (String[])params.get("action");
819
        String[] docid = (String[])params.get("docid");
820
        String newdocid = null;
821

    
822
        String doAction = null;
823
        if (action[0].equals("insert")) {
824
          doAction = "INSERT";
825
        } else if (action[0].equals("update")) {
826
          doAction = "UPDATE";
827
        }
828

    
829
        try {
830
            // get a connection from the pool
831
            conn = util.getConnection();
832

    
833
            // write the document to the database
834
            try {
835
                String accNumber = docid[0];
836
                if (accNumber.equals("")) {
837
                    accNumber = null;
838
                }
839
                newdocid = DocumentImpl.write(conn, xml, doAction, accNumber, 
840
                                              user, group);
841
                
842
            } catch (NullPointerException npe) {
843
              newdocid = DocumentImpl.write(conn,xml,doAction,null,user,group);
844
            }
845
//        } catch (Exception e) {
846
//          response.setContentType("text/html");
847
//          out.println(e.getMessage());
848
        } finally {
849
          util.returnConnection(conn);
850
        }    
851

    
852
        // set content type and other response header fields first
853
        response.setContentType("text/xml");
854
        out.println("<?xml version=\"1.0\"?>");
855
        out.println("<success>");
856
        out.println("<docid>" + newdocid + "</docid>"); 
857
        out.println("</success>");
858

    
859
      } catch (NullPointerException npe) {
860
        response.setContentType("text/xml");
861
        out.println("<?xml version=\"1.0\"?>");
862
        out.println("<error>");
863
        out.println(npe.getMessage()); 
864
        out.println("</error>");
865
      }
866
    } catch (Exception e) {
867
      response.setContentType("text/xml");
868
      out.println("<?xml version=\"1.0\"?>");
869
      out.println("<error>");
870
      out.println(e.getMessage()); 
871
      if (e instanceof SAXException) {
872
        Exception e2 = ((SAXException)e).getException();
873
        out.println("<error>");
874
        out.println(e2.getMessage()); 
875
        out.println("</error>");
876
      }
877
      //e.printStackTrace(out);
878
      out.println("</error>");
879
    }
880
  }
881

    
882
  /** 
883
   * Handle the database delete request and delete an XML document 
884
   * from the database connection
885
   */
886
  private void handleDeleteAction(PrintWriter out, Hashtable params, 
887
               HttpServletResponse response, String user, String group) {
888

    
889
    String[] docid = (String[])params.get("docid");
890
    Connection conn = null;
891

    
892
    // delete the document from the database
893
    try {
894
      // get a connection from the pool
895
      conn = util.getConnection();
896
                                      // NOTE -- NEED TO TEST HERE
897
                                      // FOR EXISTENCE OF DOCID PARAM
898
                                      // BEFORE ACCESSING ARRAY
899
      try { 
900
        DocumentImpl.delete(conn, docid[0], user, group);
901
        response.setContentType("text/xml");
902
        out.println("<?xml version=\"1.0\"?>");
903
        out.println("<success>");
904
        out.println("Document deleted."); 
905
        out.println("</success>");
906
      } catch (AccessionNumberException ane) {
907
        response.setContentType("text/xml");
908
        out.println("<?xml version=\"1.0\"?>");
909
        out.println("<error>");
910
        out.println("Error deleting document!!!");
911
        out.println(ane.getMessage()); 
912
        out.println("</error>");
913
      }
914
    } catch (Exception e) {
915
      response.setContentType("text/xml");
916
      out.println("<?xml version=\"1.0\"?>");
917
      out.println("<error>");
918
      out.println(e.getMessage()); 
919
      out.println("</error>");
920
    } finally {
921
      util.returnConnection(conn);
922
    }  
923
  }
924
  
925
  /** 
926
   * Handle the validation request and return the results to the requestor
927
   */
928
  private void handleValidateAction(PrintWriter out, Hashtable params, 
929
               HttpServletResponse response) {
930

    
931
    // Get the document indicated
932
    String valtext = null;
933
    
934
    try {
935
      valtext = ((String[])params.get("valtext"))[0];
936
    } catch (Exception nullpe) {
937

    
938
      Connection conn = null;
939
      String docid = null;
940
      try {
941
        // Find the document id number
942
        docid = ((String[])params.get("docid"))[0]; 
943

    
944
        // get a connection from the pool
945
        conn = util.getConnection();
946

    
947
        // Get the document indicated from the db
948
        DocumentImpl xmldoc = new DocumentImpl(conn, docid);
949
        valtext = xmldoc.toString();
950

    
951
      } catch (NullPointerException npe) {
952
        response.setContentType("text/xml");
953
        out.println("<error>Error getting document ID: " + docid + "</error>");
954
        if ( conn != null ) { util.returnConnection(conn); }
955
        return;
956
      } catch (Exception e) {
957
        response.setContentType("text/html");
958
        out.println(e.getMessage()); 
959
      } finally {
960
        util.returnConnection(conn);
961
      }  
962
    }
963

    
964
    Connection conn = null;
965
    try {
966
      // get a connection from the pool
967
      conn = util.getConnection();
968
      DBValidate valobj = new DBValidate(saxparser,conn);
969
      boolean valid = valobj.validateString(valtext);
970

    
971
      // set content type and other response header fields first
972
      response.setContentType("text/xml");
973
      out.println(valobj.returnErrors());
974

    
975
    } catch (NullPointerException npe2) {
976
      // set content type and other response header fields first
977
      response.setContentType("text/xml");
978
      out.println("<error>Error validating document.</error>"); 
979
    } catch (Exception e) {
980
      response.setContentType("text/html");
981
      out.println(e.getMessage()); 
982
    } finally {
983
      util.returnConnection(conn);
984
    }  
985
  }
986

    
987
  /** 
988
   * Handle the document request and return the results to the requestor
989
   * If a docid is passed in through the params then that document
990
   * will be retrieved form the DB and put in the zip file.
991
   * In addition if 1 or more relations parameters are passed, those file
992
   * will be zipped as well.  Currently this is only implemented for 
993
   * metacat:// and http:// files.  Support should be added for srb:// files
994
   * as well.
995
   */
996
  private void handleGetDataDocumentAction(ServletOutputStream out, 
997
               Hashtable params, 
998
               HttpServletResponse response) {
999
  //find the related files, get them from their source and zip them into 
1000
  //a zip file.
1001
  try
1002
  {
1003
    Connection conn = util.getConnection();
1004
    String currentDocid = ((String[])params.get("docid"))[0];
1005
    ZipOutputStream zout = new ZipOutputStream(out);
1006
    byte[] bytestring = null;
1007
    ZipEntry zentry = null;
1008
    DocumentImpl xmldoc = null;
1009
    String[] reldocs = null;
1010
    
1011
    if(params.containsKey("relation"))
1012
    { //get the relations from the parameters.
1013
      reldocs = ((String[])params.get("relation"));
1014
    }
1015
    else
1016
    { //let the for loop know that there are no relations to zip
1017
      reldocs = new String[0];
1018
    }
1019

    
1020
    //write the base file to the zip file.
1021
    xmldoc = new DocumentImpl(conn, currentDocid);
1022
    bytestring = (xmldoc.toString()).getBytes();
1023
    zentry = new ZipEntry(currentDocid + ".xml");
1024
    //create a new zip entry and write the file to the stream
1025
    zentry.setSize(bytestring.length);
1026
    zout.putNextEntry(zentry);
1027
    zout.write(bytestring, 0, bytestring.length);
1028
    zout.closeEntry(); //get ready for the next entry. 
1029

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

    
1148
    Connection conn = null;
1149
    
1150
    try {
1151

    
1152
        // get connection from the pool
1153
        conn = util.getConnection();
1154
        DBUtil dbutil = new DBUtil(conn);
1155
        String doctypes = dbutil.readDoctypes();
1156
        out.println(doctypes);
1157

    
1158
    } catch (Exception e) {
1159
      out.println("<?xml version=\"1.0\"?>");
1160
      out.println("<error>");
1161
      out.println(e.getMessage());
1162
      out.println("</error>");
1163
    } finally {
1164
      util.returnConnection(conn);
1165
    }  
1166
    
1167
  }
1168

    
1169
  /** 
1170
   * Handle the getdataguide Action.
1171
   * Read Data Guide for a given doctype from db connection in XML format
1172
   */
1173
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
1174
                                        HttpServletResponse response) {
1175

    
1176
    Connection conn = null;
1177
    String doctype = null;
1178
    String[] doctypeArr = (String[])params.get("doctype");
1179

    
1180
    // get only the first doctype specified in the list of doctypes
1181
    // it could be done for all doctypes in that list
1182
    if (doctypeArr != null) {
1183
        doctype = ((String[])params.get("doctype"))[0]; 
1184
    }
1185

    
1186
    try {
1187

    
1188
        // get connection from the pool
1189
        conn = util.getConnection();
1190
        DBUtil dbutil = new DBUtil(conn);
1191
        String dataguide = dbutil.readDataGuide(doctype);
1192
        out.println(dataguide);
1193

    
1194
    } catch (Exception e) {
1195
      out.println("<?xml version=\"1.0\"?>");
1196
      out.println("<error>");
1197
      out.println(e.getMessage());
1198
      out.println("</error>");
1199
    } finally {
1200
      util.returnConnection(conn);
1201
    }  
1202
    
1203
  }
1204

    
1205
}
(19-19/29)