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: 2001-02-21 14:29:00 -0800 (Wed, 21 Feb 2001) $'
11
 * '$Revision: 699 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27

    
28
package edu.ucsb.nceas.metacat;
29

    
30
import java.io.PrintWriter;
31
import java.io.IOException;
32
import java.io.Reader;
33
import java.io.StringReader;
34
import java.io.BufferedReader;
35
import java.io.File;
36
import java.io.FileInputStream;
37
import java.io.FileOutputStream;
38
import java.io.InputStreamReader;
39
import java.io.DataInputStream;
40
import java.util.Enumeration;
41
import java.util.Hashtable;
42
import java.util.ResourceBundle; 
43
import java.util.Random;
44
import java.util.PropertyResourceBundle;
45
import java.net.URL;
46
import java.net.MalformedURLException;
47
import java.sql.PreparedStatement;
48
import java.sql.ResultSet;
49
import java.sql.Connection;
50
import java.sql.SQLException;
51
import java.lang.reflect.*;
52
import java.net.*;
53
import java.util.zip.*;
54

    
55
import javax.servlet.ServletConfig;
56
import javax.servlet.ServletContext;
57
import javax.servlet.ServletException;
58
import javax.servlet.ServletInputStream;
59
import javax.servlet.http.HttpServlet;
60
import javax.servlet.http.HttpServletRequest;
61
import javax.servlet.http.HttpServletResponse;
62
import javax.servlet.http.HttpSession;
63
import javax.servlet.http.HttpUtils;
64
import javax.servlet.ServletOutputStream;
65

    
66
import oracle.xml.parser.v2.XSLStylesheet;
67
import oracle.xml.parser.v2.XSLException;
68
import oracle.xml.parser.v2.XMLDocumentFragment;
69
import oracle.xml.parser.v2.XSLProcessor;
70

    
71
import org.xml.sax.SAXException;
72

    
73
/**
74
 * A metadata catalog server implemented as a Java Servlet
75
 *
76
 * <p>Valid parameters are:<br>
77
 * action=query -- query the values of all elements and attributes
78
 *                     and return a result set of nodes<br>
79
 * action=squery -- structured query (see pathquery.dtd)<br>
80
 * action=insert -- insert an XML document into the database store<br>
81
 * action=update -- update an XML document that is in the database store<br>
82
 * action=delete --  delete an XML document from the database store<br>
83
 * action=validate -- vallidate the xml contained in valtext<br>
84
 * action=read -- display an XML document in XML or HTML<br>
85
 * doctype -- document type list returned by the query (publicID)<br>
86
 * qformat=xml -- display resultset from query in XML<br>
87
 * qformat=html -- display resultset from query in HTML<br>
88
 * docid=34 -- display the document with the document ID number 34<br>
89
 * doctext -- XML text of the document to load into the database<br>
90
 * acltext -- XML access text for a document to load into the database<br>
91
 * dtdtext -- XML DTD text for a new DTD to load into Metacat XML Catalog<br>
92
 * query -- actual query text (to go with 'action=query' or 'action=squery')<br>
93
 * valtext -- XML text to be validated<br>
94
 * action=getdatadoc -- retrieve a stored datadocument<br>
95
 * action=getaccesscontrol -- retrieve acl info for Metacat document<br>
96
 * action=getdoctypes -- retrieve all doctypes (publicID)<br>
97
 * action=getdtdschema -- retrieve a DTD or Schema file<br>
98
 * action=getdataguide -- retrieve a Data Guide<br>
99
 * datadoc -- data document name (id)<br>
100
 * <p>
101
 * The particular combination of parameters that are valid for each 
102
 * particular action value is quite specific.  This documentation
103
 * will be reorganized to reflect this information.
104
 */
105
public class MetaCatServlet extends HttpServlet {
106

    
107
  private ServletConfig config = null;
108
  private ServletContext context = null;
109
  private Hashtable connectionPool = new Hashtable();
110
  private String resultStyleURL = null;
111
  private String xmlcatalogfile = null;
112
  private String saxparser = null;
113
  private String defaultdatapath = null; 
114
  private String servletpath = null; 
115
  private PropertyResourceBundle options = null;
116
  private MetaCatUtil util = null;
117

    
118
  // path to directory where data files 
119
  // that can be downloaded will be stored
120
  private String htmlpath = null; 
121
  // script to get data file and put it 
122
  // in defaultdocpath dir
123
  private String executescript  = null;  
124

    
125
  /**
126
   * Initialize the servlet by creating appropriate database connections
127
   */
128
  public void init( ServletConfig config ) throws ServletException {
129
    try {
130
      super.init( config );
131
      this.config = config;
132
      this.context = config.getServletContext(); 
133
      System.out.println("MetaCatServlet Initialize");
134

    
135
      util = new MetaCatUtil();
136

    
137
      // Get the configuration file information
138
      resultStyleURL = util.getOption("resultStyleURL");
139
      xmlcatalogfile = util.getOption("xmlcatalogfile");
140
      saxparser = util.getOption("saxparser");
141
      defaultdatapath = util.getOption("defaultdatapath");
142
      executescript = util.getOption("executescript"); 
143
      servletpath = util.getOption("servletpath");
144
      htmlpath = util.getOption("htmlpath");
145

    
146
//      try {
147
//        // Open a pool of db connections
148
//        connectionPool = util.getConnectionPool();
149
//      } catch (Exception e) {
150
//        System.err.println("Error creating pool of database connections");
151
//        System.err.println(e.getMessage());
152
//      }
153
    } catch ( ServletException ex ) {
154
      throw ex;
155
    }
156
  }
157

    
158
  /**
159
   * Close all db connections from the pool
160
   */
161
  public void destroy() {
162
    
163
    if (util != null) {
164
        util.closeConnections();
165
    }
166
  }
167

    
168
  /** Handle "GET" method requests from HTTP clients */
169
  public void doGet (HttpServletRequest request, HttpServletResponse response)
170
    throws ServletException, IOException {
171

    
172
    // Process the data and send back the response
173
    handleGetOrPost(request, response);
174
  }
175

    
176
  /** Handle "POST" method requests from HTTP clients */
177
  public void doPost( HttpServletRequest request, HttpServletResponse response)
178
    throws ServletException, IOException {
179

    
180
    // Process the data and send back the response
181
    handleGetOrPost(request, response);
182
  }
183

    
184
  /**
185
   * Control servlet response depending on the action parameter specified
186
   */
187
  private void handleGetOrPost(HttpServletRequest request, 
188
    HttpServletResponse response) 
189
    throws ServletException, IOException 
190
 {
191

    
192
    if ( util == null ) {
193
        util = new MetaCatUtil(); 
194
    }
195
    if ( connectionPool.isEmpty() ) {
196
      try {
197
        // Open a pool of db connections
198
        connectionPool = util.getConnectionPool();
199
      } catch (Exception e) {
200
        System.err.println("Error creating pool of database connections in " +
201
                            " MetaCatServlet.handleGetOrPost");
202
        System.err.println(e.getMessage());
203
      }
204
    }    
205
    // Get a handle to the output stream back to the client
206
    //PrintWriter pwout = response.getWriter();
207
    //response.setContentType("text/html");
208
  
209
    String name = null;
210
    String[] value = null;
211
    String[] docid = new String[3];
212
    Hashtable params = new Hashtable();
213
    Enumeration paramlist = request.getParameterNames();
214
    while (paramlist.hasMoreElements()) {
215
      name = (String)paramlist.nextElement();
216
      value = request.getParameterValues(name);
217

    
218
      // Decode the docid and mouse click information
219
      if (name.endsWith(".y")) {
220
        docid[0] = name.substring(0,name.length()-2);
221
        //out.println("docid => " + docid[0]);
222
        params.put("docid", docid);
223
        name = "ypos";
224
      }
225
      if (name.endsWith(".x")) {
226
        name = "xpos";
227
      } 
228

    
229
      //pwout.println(name + " => " + value[0]);
230
      params.put(name,value); 
231
    }  
232
    
233
    //if the user clicked on the input images, decode which image
234
    //was clicked then set the action.
235
    String action = ((String[])params.get("action"))[0];  
236
    util.debugMessage("Line 213: Action is: " + action);
237

    
238
    //MBJELIMINATE String action = decodeMouseAction(params);
239
    //if(action.equals("error"))
240
    //{
241
      //util.debugMessage("Line 218: Action is: " + action);
242
      //action = ((String[])params.get("action"))[0];  
243
    //}
244
    
245
    // This block handles session management for the servlet
246
    // by looking up the current session information for all actions
247
    // other than "login" and "logout"
248
    String username = null;
249
    String groupname = null;
250
    String sess_id = null;
251

    
252
    // handle login action
253
    if (action.equals("login")) {
254

    
255
      handleLoginAction(response.getWriter(), params, request, response);
256

    
257
    // handle logout action  
258
    } else if (action.equals("logout")) {
259

    
260
      handleLogoutAction(response.getWriter(), params, request, response);
261

    
262
    // aware of session expiration on every request  
263
    } else {   
264

    
265
      HttpSession sess = request.getSession(true);
266
      if (sess.isNew()) { 
267
        // session expired or has not been stored b/w user requests
268
        username = "public";
269
        sess.setAttribute("username", username);
270
      } else {
271
        username = (String)sess.getAttribute("username");
272
        groupname = (String)sess.getAttribute("groupname");
273
        try
274
        {
275
          sess_id = (String)sess.getId();
276
        }
277
        catch(IllegalStateException ise)
278
        {
279
          System.out.println("error in handleGetOrPost: this shouldn't " +
280
                             "happen: the session should be valid: " + 
281
                             ise.getMessage());
282
        }
283
      }  
284
    }    
285

    
286
    // Now that we know the session is valid, we can delegate the request
287
    // to a particular action handler
288
    if(action.equals("query"))
289
    {
290
      handleQuery(response.getWriter(), params, response, username, groupname); 
291
    } 
292
    else if(action.equals("squery"))
293
    {
294
      if(params.containsKey("query"))
295
      {
296
        handleSQuery(response.getWriter(), params, response, username, groupname); 
297
      }
298
      else
299
      {
300
        PrintWriter out = response.getWriter();
301
        out.println("Illegal action squery without \"query\" parameter");
302
      }
303
    }
304
    else if (action.equals("read")) {
305
      //PrintWriter out = response.getWriter();
306
      try {
307
        handleReadAction(/*out,*/ params, response, username);
308
      } catch (ClassNotFoundException e) {
309
        System.out.println("Error in MetacatServlet.handlGetOrPost: " + 
310
                            e.getMessage());
311
      } catch (SQLException se) {
312
        System.out.println("Error in MetaCatServlet.handleGetOrPost: " + 
313
                            se.getMessage());
314
      }
315
    } 
316
/*
317
    else if (action.equals("getrelateddocument")) {
318
      PrintWriter out = response.getWriter();
319
      try {
320
        handleGetRelatedDocumentAction(out, params, response);
321
      } catch (ClassNotFoundException e) {
322
        out.println(e.getMessage());
323
      } catch (SQLException se) {
324
        out.println(se.getMessage());
325
      }
326
    }
327
*/
328
    else if (action.equals("insert") || action.equals("update")) {
329
      PrintWriter out = response.getWriter();
330
      if ( (username != null) &&  !username.equals("public") ) {
331
        handleInsertOrUpdateAction(out, params, response, username, groupname);
332
      } else {  
333
        out.println("Permission denied for " + action);
334
      }  
335
    } else if (action.equals("delete")) {
336
      PrintWriter out = response.getWriter();
337
      if ( (username != null) &&  !username.equals("public") ) {
338
        handleDeleteAction(out, params, response, username, groupname);
339
      } else {  
340
        out.println("Permission denied for " + action);
341
      }  
342
    } else if (action.equals("validate")) {
343
      PrintWriter out = response.getWriter();
344
      handleValidateAction(out, params, response); 
345
    } else if (action.equals("getabstract")) {
346
      PrintWriter out = response.getWriter();
347
      try{
348
        handleViewAbstractAction(out, params, response);
349
      }
350
      catch(Exception e)
351
      {
352
        out.println("error viewing abstract from " + 
353
                    "MetacatServlet.handleGetorPost: " + e.getMessage());
354
      }
355
    } else if (action.equals("getdatadoc")) {
356
      response.setContentType("application/zip");
357
      ServletOutputStream out = response.getOutputStream();
358
      handleGetDataDocumentAction(out, params, response);  
359
    } else if (action.equals("getaccesscontrol")) {
360
      PrintWriter out = response.getWriter();
361
      handleGetAccessControlAction(out, params, response, username, groupname);
362
    } else if (action.equals("getdoctypes")) {
363
      PrintWriter out = response.getWriter();
364
      handleGetDoctypesAction(out, params, response);  
365
    } else if (action.equals("getdataport")) {
366
      PrintWriter out = response.getWriter();
367
      if ( (username != null) &&  !username.equals("public") ) {
368
      handleGetDataPortAction(out, params, response, username, groupname, 
369
                              sess_id);
370
      } else {
371
        out.println("You must be authenticated to perform the getdataport " +
372
                    "action!");
373
      }
374
    } else if (action.equals("getdtdschema")) {
375
      PrintWriter out = response.getWriter();
376
      handleGetDTDSchemaAction(out, params, response);  
377
    } else if (action.equals("getdataguide")) {
378
      PrintWriter out = response.getWriter();
379
      handleGetDataGuideAction(out, params, response);  
380
    } else if (action.equals("login") || action.equals("logout")) {
381
    } else if (action.equals("protocoltest")) {
382
      String testURL = "metacat://dev.nceas.ucsb.edu/NCEAS.897766.9";
383
      try {
384
        testURL = ((String[])params.get("url"))[0];
385
      } catch (Throwable t) {
386
      }
387
      String phandler = System.getProperty("java.protocol.handler.pkgs");
388
      response.setContentType("text/html");
389
      PrintWriter out = response.getWriter();
390
      out.println("<body bgcolor=\"white\">");
391
      out.println("<p>Handler property: <code>" + phandler + "</code></p>");
392
      out.println("<p>Starting test for:<br>");
393
      out.println("    " + testURL + "</p>");
394
      try {
395
        URL u = new URL(testURL);
396
        out.println("<pre>");
397
        out.println("Protocol: " + u.getProtocol());
398
        out.println("    Host: " + u.getHost());
399
        out.println("    Port: " + u.getPort());
400
        out.println("    Path: " + u.getPath());
401
        out.println("     Ref: " + u.getRef());
402
        String pquery = u.getQuery();
403
        out.println("   Query: " + pquery);
404
        out.println("  Params: ");
405
        if (pquery != null) {
406
          Hashtable qparams = util.parseQuery(u.getQuery());
407
          for (Enumeration en = qparams.keys(); en.hasMoreElements(); ) {
408
            String pname = (String)en.nextElement();
409
            String pvalue = (String)qparams.get(pname);
410
            out.println("    " + pname + ": " + pvalue);
411
          }
412
        }
413
        out.println("</pre>");
414
        out.println("</body>");
415
        out.close();
416
      } catch (MalformedURLException mue) {
417
        System.out.println("bad url from MetacatServlet.handleGetOrPost");
418
        out.println(mue.getMessage());
419
        mue.printStackTrace(out);
420
        out.close();
421
      }
422
    } else {
423
      PrintWriter out = response.getWriter();
424
      out.println("Error: action not registered.  Please report this error.");
425
    }
426
    util.closeConnections();
427
    // Close the stream to the client
428
    //out.close();
429
  }
430
  
431
  /**
432
   * decodes the mouse click information coming from the client.
433
   * This function may be overwritten to provide specific functionality
434
   * for different applications.
435
   * @param params the parameters from the CGI
436
   * @return action the action to be performed or "error" if an error was
437
   * generated
438
   */
439
  protected String decodeMouseAction(Hashtable params)
440
  {
441
    // Determine what type of request the user made
442
    // if the action parameter is set, use it as a default
443
    // but if the ypos param is set, calculate the action needed
444
    String action=null;
445
    long ypos = 0;
446
    try {
447
      ypos = (new Long(((String[])params.get("ypos"))[0]).longValue());
448
      //out.println("<P>YPOS IS " + ypos);
449
      if (ypos <= 13) {
450
        action = "read";
451
      } else if (ypos > 13 && ypos <= 27) {
452
        action = "validate";
453
      } else if (ypos > 27) {
454
        action = "transform";
455
      }
456
      return action;
457
    } catch (Exception npe) {
458
      //
459
      // MBJ -- NOTE that this should be handled more gracefully with
460
      //        the new exception infrastructure -- this "error" return
461
      //        value is inappropriate
462
      //out.println("<P>Caught exception looking for Y value.");
463
      return "error";
464
    }  
465
  }
466
  
467
  /**
468
   * sends the port number that the data socket is running on.  This is a 
469
   * parameter set in the metacat.properties file.
470
   */
471
  private void handleGetDataPortAction(PrintWriter out, Hashtable params, 
472
                                       HttpServletResponse response, 
473
                                       String username, String groupname,
474
                                       String sess_id)
475
  {
476
    int port;
477
    String filedir = null;
478
    try
479
    {
480
      filedir = util.getOption("datafilepath");
481
      
482
      Random r = new Random();
483
      port = r.nextInt(65000);  //pick a random port between 0-65000
484
      //System.out.println("random port is: " + port);
485
      while(!DataFileServer.portIsAvailable(port))
486
      {
487
        port = r.nextInt(65000);
488
        //System.out.println("next port used: " + port);
489
      }
490
      DataFileServer dfs = new DataFileServer(port, username, sess_id);
491
      dfs.start();
492
      
493
      //System.out.println("filedir: " + filedir);
494
      //System.out.println("port: " + port);
495
      response.setContentType("text/xml");
496
      out.println("<?xml version=\"1.0\"?>");
497
      out.println("<port>");
498
      out.print(port);
499
      out.print("</port>");
500
      
501
    }
502
	  catch (Exception e) 
503
    {
504
      System.out.println("error in MetacatServlet.handleGetDataPortAction: " + 
505
                          e.getMessage());
506
    }
507
  }
508

    
509
  /** 
510
   * Handle the login request. Create a new session object.
511
   * Do user authentication through the session.
512
   */
513
  private void handleLoginAction(PrintWriter out, Hashtable params, 
514
               HttpServletRequest request, HttpServletResponse response) {
515

    
516
    AuthSession sess = null;
517
    String un = ((String[])params.get("username"))[0];
518
    String pw = ((String[])params.get("password"))[0];
519
    String action = ((String[])params.get("action"))[0];
520
    String qformat = ((String[])params.get("qformat"))[0];
521
    
522
    try {
523
      sess = new AuthSession();
524
    } catch (Exception e) {
525
      System.out.println("error in MetacatServlet.handleLoginAction: " +
526
                          e.getMessage());
527
      out.println(e.getMessage());
528
      return;
529
    }
530
    
531
    boolean isValid = sess.authenticate(request, un, pw);
532

    
533
    // format and transform the output
534
    if (qformat.equals("html")) {
535
      Connection conn = null;
536
      try {
537
        conn = util.getConnection();
538
        DBTransform trans = new DBTransform(conn);
539
        response.setContentType("text/html");
540
        trans.transformXMLDocument(sess.getMessage(), "-//NCEAS//login//EN",
541
                                   "-//W3C//HTML//EN", out);
542
        util.returnConnection(conn); 
543
      } catch(Exception e) {
544
        util.returnConnection(conn); 
545
      } 
546
      
547
    // any output is returned  
548
    } else {
549
      response.setContentType("text/xml");
550
      out.println(sess.getMessage()); 
551
    }
552
        
553
/* WITHOUT XSLT transformation
554
    // redirects response to html page
555
    if (qformat.equals("html")) {
556
      // user authentication successful
557
      if (isValid) {
558
        response.sendRedirect(
559
                 response.encodeRedirectUrl(htmlpath + "/metacat.html"));
560
      // unsuccessful user authentication 
561
      } else {
562
        response.sendRedirect(htmlpath + "/login.html");
563
      }
564
    // any output is returned  
565
    } else {
566
      response.setContentType("text/xml");
567
      out.println(sess.getMessage()); 
568
    }
569
*/        
570

    
571
  }    
572

    
573
  /** 
574
   * Handle the logout request. Close the connection.
575
   */
576
  private void handleLogoutAction(PrintWriter out, Hashtable params, 
577
               HttpServletRequest request, HttpServletResponse response) {
578

    
579
    String qformat = ((String[])params.get("qformat"))[0];
580

    
581
    // close the connection
582
    HttpSession sess = request.getSession(false);
583
    if (sess != null) { sess.invalidate();  }    
584

    
585
    // produce output
586
    StringBuffer output = new StringBuffer();
587
    output.append("<?xml version=\"1.0\"?>");
588
    output.append("<logout>");
589
    output.append("User logged out");
590
    output.append("</logout>");
591

    
592
    //format and transform the output
593
    if (qformat.equals("html")) {
594
      Connection conn = null;
595
      try {
596
        conn = util.getConnection();
597
        DBTransform trans = new DBTransform(conn);
598
        response.setContentType("text/html");
599
        trans.transformXMLDocument(output.toString(), "-//NCEAS//login//EN", 
600
                                   "-//W3C//HTML//EN", out);
601
        util.returnConnection(conn); 
602
      } catch(Exception e) {
603
        util.returnConnection(conn); 
604
      } 
605
    // any output is returned  
606
    } else {
607
      response.setContentType("text/xml");
608
      out.println(output.toString()); 
609
    }
610

    
611
/* WITHOUT XSLT transformation
612
    // redirects response to html page
613
    if (qformat.equals("html")) {
614
        response.sendRedirect(htmlpath + "/index.html"); 
615
      } catch(Exception e) {
616
        util.returnConnection(conn); 
617
      } 
618
    // any output is returned  
619
    } else {
620
      response.setContentType("text/xml");
621
      out.println(output.toString()); 
622
    }
623
*/
624
  }
625

    
626
  
627
  /**      
628
   * Retreive the squery xml, execute it and display it
629
   *
630
   * @param out the output stream to the client
631
   * @param params the Hashtable of parameters that should be included
632
   * in the squery.
633
   * @param response the response object linked to the client
634
   * @param conn the database connection 
635
   */
636
  protected void handleSQuery(PrintWriter out, Hashtable params, 
637
                 HttpServletResponse response, String user, String group)
638
  { 
639
    String xmlquery = ((String[])params.get("query"))[0];
640
    String qformat = ((String[])params.get("qformat"))[0];
641
    String resultdoc = null;
642
    String[] returndoc = null;
643
    if(params.contains("returndoc"))
644
    {
645
      returndoc = (String[])params.get("returndoc");
646
    }
647
    
648
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
649
    //String resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
650

    
651
    resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
652
    
653
    //format and transform the results                                        
654
    if(qformat.equals("html")) {
655
      transformResultset(resultdoc, response, out);
656
    } else if(qformat.equals("xml")) {
657
      response.setContentType("text/xml");
658
      out.println(resultdoc);
659
    } else {
660
      out.println("invalid qformat: " + qformat); 
661
    }
662
  }
663
  
664
   /**
665
    * Create the xml query, execute it and display the results.
666
    *
667
    * @param out the output stream to the client
668
    * @param params the Hashtable of parameters that should be included
669
    * in the squery.
670
    * @param response the response object linked to the client
671
    */ 
672
  protected void handleQuery(PrintWriter out, Hashtable params, 
673
                 HttpServletResponse response, String user, String group)
674
  {
675
    //create the query and run it
676
    String[] returndoc = null;
677
    if(params.containsKey("returndoc"))
678
    {
679
      returndoc = (String[])params.get("returndoc");
680
    }
681
    String xmlquery = DBQuery.createSQuery(params);
682
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
683
    String qformat = ((String[])params.get("qformat"))[0];
684
    String resultdoc = null;
685
    
686
    resultdoc = createResultDocument(doclist, transformQuery(params));
687

    
688
    //format and transform the results                                        
689
    if(qformat.equals("html")) {
690
      transformResultset(resultdoc, response, out);
691
    } else if(qformat.equals("xml")) {
692
      response.setContentType("text/xml");
693
      out.println(resultdoc);
694
    } else { 
695
      out.println("invalid qformat: " + qformat); 
696
    }
697
  }
698
  
699
  /**
700
   * Removes the <?xml version="x"?> tag from the beginning of xmlquery
701
   * so it can properly be placed in the <query> tag of the resultset.
702
   * This method is overwritable so that other applications can customize
703
   * the structure of what is in the <query> tag.
704
   * 
705
   * @param xmlquery is the query to remove the <?xml version="x"?> tag from.
706
   */
707
  protected String transformQuery(Hashtable params)
708
  {
709
    //DBQuery.createSQuery is a re-calling of a previously called 
710
    //function but it is necessary
711
    //so that overriding methods have access to the params hashtable
712
    String xmlquery = DBQuery.createSQuery(params);
713
    //the <?xml version="1.0"?> tag is the first 22 characters of the
714
    xmlquery = xmlquery.trim();
715
    int index = xmlquery.indexOf("?>");
716
    return xmlquery.substring(index + 2, xmlquery.length());
717
  }
718
  
719
  /**
720
   * removes the <?xml version="1.0"?> tag from the beginning.  This takes a
721
   * string as a param instead of a hashtable.
722
   * 
723
   * @param xmlquery a string representing a query.
724
   */
725
  protected String transformQuery(String xmlquery)
726
  {
727
    xmlquery = xmlquery.trim();
728
    int index = xmlquery.indexOf("?>");
729
    return xmlquery.substring(index + 2, xmlquery.length());
730
  }
731
  
732
  /**
733
   * Run the query and return a hashtable of results.
734
   *
735
   * @param xmlquery the query to run
736
   */
737
  private Hashtable runQuery(String xmlquery, String user, String group, 
738
                             String[] returndoc)
739
  {
740
    Hashtable doclist=null;
741
    Connection conn = null;
742
    try
743
    {
744
      conn = util.getConnection();
745
      DBQuery queryobj = new DBQuery(conn, saxparser);
746
      doclist = queryobj.findDocuments(new StringReader(xmlquery),user,group,
747
                                       returndoc);
748
      util.returnConnection(conn);
749
      return doclist;
750
    } 
751
    catch (Exception e) 
752
    {
753
      util.returnConnection(conn); 
754
      util.debugMessage("Error in MetacatServlet.runQuery: " + e.getMessage());
755
      doclist = null;
756
      return doclist;
757
    }    
758
  }
759
  
760
  /**
761
   * Transorms an xml resultset document to html and sends it to the browser
762
   *
763
   * @param resultdoc the string representation of the document that needs
764
   * to be transformed.
765
   * @param response the HttpServletResponse object bound to the client.
766
   * @param out the output stream to the client
767
   */ 
768
  protected void transformResultset(String resultdoc, 
769
                                    HttpServletResponse response,
770
                                    PrintWriter out)
771
  {
772
    Connection conn = null;
773
    try {
774
      conn = util.getConnection();
775
      DBTransform trans = new DBTransform(conn);
776
      response.setContentType("text/html");
777
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN", 
778
                                 "-//W3C//HTML//EN", out);
779
      util.returnConnection(conn); 
780
    }
781
    catch(Exception e)
782
    {
783
      util.returnConnection(conn); 
784
    } 
785
  }
786
  
787
  /**
788
   * Transforms a hashtable of documents to an xml or html result.
789
   * If there is a returndoc, then it only displays documents of
790
   * whatever type returndoc represents.  If a result is found in a document
791
   * that is not of type returndoc then this attempts to find a relation 
792
   * between this document and one that satifies the returndoc doctype.
793
   *
794
   * @param doclist- the hashtable to transform
795
   * @param xmlquery- the query that returned the dolist result
796
   * @param resultdoc- the document type to backtrack to.
797
   */
798
  protected String createResultDocument(Hashtable doclist, String xmlquery)
799
  {
800
    // Create a buffer to hold the xml result
801
    StringBuffer resultset = new StringBuffer();
802
 
803
    // Print the resulting root nodes 
804
    String docid = null;
805
    String document = null;
806
    resultset.append("<?xml version=\"1.0\"?>\n");
807
    resultset.append("<resultset>\n");
808
      
809
    resultset.append("  <query>" + xmlquery + "</query>");   
810

    
811
    if(doclist != null)
812
    {
813
      Enumeration doclistkeys = doclist.keys(); 
814
      while (doclistkeys.hasMoreElements()) 
815
      {
816
        docid = (String)doclistkeys.nextElement();
817
        document = (String)doclist.get(docid);
818
        resultset.append("  <document>" + document + "</document>");
819
      }
820
    }
821

    
822
    resultset.append("</resultset>");
823
    //System.out.println(resultset.toString());
824
    return resultset.toString();
825
  }
826
  
827
  /**
828
   * Handle the request to view the abstract of a document.
829
   * The abstractpath CGI parameter gives the xml path to the abstract
830
   * node.  
831
   */
832
  private void handleViewAbstractAction(PrintWriter out, Hashtable params,
833
               HttpServletResponse response) throws IOException, SQLException
834
  {
835
    String abstractpath = null;
836
    String docid = null;
837
    Connection conn = null;
838
    response.setContentType("text/html");
839
    try
840
    {
841
      docid = ((String[])params.get("docid"))[0];
842
      if(params.containsKey("abstractpath"))
843
      {
844
        //the CGI parameter abstractpath holds the path to the abstract
845
        //that should be displayed.
846
        abstractpath = ((String[])params.get("abstractpath"))[0];
847
      }
848
      else
849
      {
850
        out.println("error: no abstractpath parameter"); 
851
      }
852
      conn = util.getConnection();
853
    
854
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid, conn);
855
    
856
      out.println("<html><head><title>Abstract</title></head>");
857
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
858
      for(int i=0; i<abstracts.length; i++)
859
      {
860
        out.println("<p>" + (String)abstracts[i] + "</p>");
861
      }
862
      out.println("</body></html>");
863
    }
864
    catch (IOException ioe)
865
    {
866
       util.debugMessage("error in MetacatServlet.handlegetabstract: " + 
867
                          ioe.getMessage());
868
       System.out.println("IO error in MetacatServlet.handlegetabstract: " + 
869
                          ioe.getMessage());
870
    }
871
    catch(SQLException sqle)
872
    {
873
      util.debugMessage("sql error in MetacatServLet.handlegetabstract: " + 
874
                         sqle.getMessage());
875
      System.out.println("sql error in MetacatServLet.handlegetabstract: " + 
876
                         sqle.getMessage());
877
    }
878
    catch(Exception e)
879
    {
880
      util.debugMessage("error in handlegetabstract: " + e.getMessage());
881
      System.out.println("error in MetacatServlEt.handlegetabstract: " + 
882
                         e.getMessage());
883
    }
884
    
885
    util.returnConnection(conn);
886
  }
887

    
888
  /** 
889
   * Handle the database getrelateddocument request and return a XML document, 
890
   * possibly transformed from XML into HTML
891
   */
892
  private void handleGetRelatedDocumentAction(PrintWriter out, Hashtable params,
893
               HttpServletResponse response, URL murl) 
894
               throws ClassNotFoundException, IOException, SQLException 
895
  {
896
    String docid = null;
897
    Connection conn = null;
898
      
899
    //if(params.containsKey("url"))
900
    //{//the identifier for the related document is contained in the URL param
901
      try
902
      {
903
        DocumentImpl xmldoc=null;
904
        //MetacatURL murl = new MetacatURL(((String[])params.get("url"))[0]);
905
        if(murl.getProtocol().equals("metacat"))
906
        {//get the document from the database if it is the right type of url
907
          //Hashtable murlParams = murl.getHashParams();
908
          Hashtable murlParams = util.parseQuery(murl.getQuery());
909
          if(murlParams.containsKey("docid"))
910
          {//the docid should be first
911
            docid = (String)murlParams.get("docid"); //get the docid value
912
            conn = util.getConnection();
913
            xmldoc = new DocumentImpl(conn, docid);
914
            String qformat = ((String[])params.get("qformat"))[0];
915
            if (qformat.equals("xml")) 
916
            { 
917
              // set content type and other response header fields first
918
              response.setContentType("text/xml");
919
              xmldoc.toXml(out);
920
              //out.println(xmldoc);
921
            } 
922
            else if (qformat.equals("html")) 
923
            {
924
              response.setContentType("text/html");
925
              // Look up the document type
926
              String sourcetype = xmldoc.getDoctype();
927
              // Transform the document to the new doctype
928
              DBTransform dbt = new DBTransform(conn);
929
              dbt.transformXMLDocument(xmldoc.toString(), sourcetype, 
930
                                 "-//W3C//HTML//EN", out);
931
            }
932

    
933
            util.returnConnection(conn);
934
          }
935
          else
936
          {
937
            //throw new Exception("handleGetDocument: bad URL");
938
            System.err.println("handleGetDocument: bad URL");
939
          }
940
        }
941
        else if(murl.getProtocol().equals("http"))
942
        {//get the document from the internet
943
          //Hashtable murlParams = murl.getHashParams();
944
          Hashtable murlParams = util.parseQuery(murl.getQuery());
945
          if(murlParams.containsKey("httpurl"))
946
          {//httpurl is the param name for an http url.
947
            URL urlconn = new URL((String)murlParams.get("httpurl"));  
948
            //create a new url obj.
949
            //DataInputStream htmldoc = new DataInputStream(urlconn.openStream());
950
            BufferedReader htmldoc = new BufferedReader(
951
                                   new InputStreamReader(urlconn.openStream()));
952
            //bind a data stream.
953
            try
954
            { //display the document
955
              String line=null;
956
              while((line = htmldoc.readLine()) != null)
957
              {
958
                out.println(line); 
959
              }
960
            }
961
            catch(Exception e)
962
            {
963
              System.out.println("error viewing html document from " +
964
                            "MetacatServlet.handleGetRelatedDocumentAction: " +
965
                            e.getMessage()); 
966
            }
967
          }
968
        }
969
      }
970
      catch (McdbException e) {
971
        response.setContentType("text/xml");
972
        e.toXml(out);
973
      } catch   (Throwable t) {
974
        response.setContentType("text/html");
975
        out.println(t.getMessage());
976
      } finally {
977
        util.returnConnection(conn);
978
      }
979
    //} // end if
980
  }   
981
  
982
  /** 
983
   * Handle the database read request and return an XML document, 
984
   * possibly transformed from XML into HTML
985
   */
986
  private void handleReadAction(/*PrintWriter out,*/ Hashtable params, 
987
               HttpServletResponse response, String username) 
988
               throws ClassNotFoundException, IOException, SQLException 
989
  {
990
     PrintWriter out;
991
    try {
992
      //MetacatURL murl = new MetacatURL(((String[])params.get("docid"))[0]);
993
      if(params.containsKey(new String("qformat")) && 
994
         ((String[])params.get("qformat"))[0].equals("bin"))
995
      {
996
        handleGetData(params, response, username);
997
      }
998
      else
999
      {
1000
        out = response.getWriter();
1001
        URL murl = new URL(((String[])params.get("docid"))[0]);
1002
        handleGetRelatedDocumentAction(out, params, response, murl);
1003
      }
1004
    } catch (MalformedURLException mue) {
1005
      out = response.getWriter();
1006
      handleGetDocumentAction(out, params, response);
1007
    }
1008
  }
1009
  
1010
  /**
1011
   * Handle the read of a data file.
1012
   */
1013
  private void handleGetData(Hashtable params, 
1014
                             HttpServletResponse response, String username)
1015
  {
1016
    String docid = null;
1017
    try
1018
    {
1019
      URL murl = new URL(((String[])params.get("docid"))[0]);
1020
      Hashtable murlParams = util.parseQuery(murl.getQuery());
1021
      if(murlParams.containsKey("docid"))
1022
      {
1023
        docid = (String)murlParams.get("docid");
1024
      }
1025
    }
1026
    catch(MalformedURLException mue)
1027
    {
1028
      docid = ((String[])params.get("docid"))[0];
1029
    }
1030
    
1031
    File f = null;
1032
    FileInputStream fin = null;
1033
    Connection conn;
1034
    
1035
    try
1036
    {
1037
      StringBuffer sql = new StringBuffer();
1038
      sql.append("select docname from xml_documents where docid like '");
1039
      sql.append(docid).append("'");
1040
      conn = util.openDBConnection();
1041
      
1042
      AccessControlList aclobj = new AccessControlList(conn);
1043
      boolean hasPermission = aclobj.hasPermission("READ",username,docid);
1044
      
1045
      if(!hasPermission)
1046
      {
1047
        response.setContentType("text/html");
1048
        PrintWriter out = response.getWriter();
1049
        out.println("Error: you do not have permission to view this document");
1050
        return;
1051
      }
1052
      response.setContentType("application/octet-stream");
1053
      ServletOutputStream sosout = response.getOutputStream(); 
1054
      PreparedStatement pstmt = conn.prepareStatement(sql.toString());
1055
      pstmt.execute();
1056
      ResultSet rs = pstmt.getResultSet();
1057
      boolean tablehasrows = rs.next();
1058
      while(tablehasrows)
1059
      {
1060
        //get the file stream from the file then send it to the output stream
1061
        String filepath = util.getOption("datafilepath");
1062
        if(!filepath.endsWith("/"))
1063
        {
1064
          filepath += "/";
1065
        }
1066
        f = new File(filepath + rs.getString(1)); 
1067
        fin = new FileInputStream(f);
1068
        
1069
        int b = fin.read();
1070
        while(b != -1)
1071
        {
1072
          sosout.write(b);
1073
          b = fin.read();
1074
        }
1075
        tablehasrows = rs.next();
1076
      }
1077
      
1078
      fin.close();
1079
      pstmt.close();
1080
      conn.close();
1081
    }
1082
    catch(Exception e)
1083
    {
1084
      System.out.println("error in MetacatServlet.handleGetData: " + 
1085
                          e.getMessage());
1086
      e.printStackTrace(System.out);
1087
    }
1088
  }
1089

    
1090
  /** 
1091
   * Handle the database read request and return an XML document, 
1092
   * possibly transformed from XML into HTML
1093
   */
1094
  private void handleGetDocumentAction(PrintWriter out, Hashtable params, 
1095
               HttpServletResponse response) 
1096
               throws ClassNotFoundException, IOException, SQLException {
1097
    String docidstr = null;
1098
    String docid = null;
1099
    String doc = null;
1100
    Connection conn = null;
1101
    
1102
    try {
1103
      // Find the document id number
1104
      docidstr = ((String[])params.get("docid"))[0]; 
1105
      docid = docidstr;
1106
      
1107
      conn = util.getConnection();
1108
      DocumentImpl xmldoc = new DocumentImpl(conn, docid);
1109
      // Get the document indicated from the db
1110
      //doc = docreader.readXMLDocument(docid);
1111

    
1112
      // Return the document in XML or HTML format
1113
      String qformat=null;
1114
      if(params.containsKey("qformat"))
1115
      {
1116
        qformat = ((String[])params.get("qformat"))[0];
1117
      }
1118
      else
1119
      {
1120
        qformat = "html";        
1121
      }
1122
      if (qformat.equals("xml")) { 
1123
        // set content type and other response header fields first
1124
        response.setContentType("text/xml");
1125
        xmldoc.toXml(out);
1126
        //out.println(xmldoc);
1127
      } else if (qformat.equals("html")) {
1128
        response.setContentType("text/html");
1129
        // Look up the document type
1130
        String sourcetype = xmldoc.getDoctype();
1131
        // Transform the document to the new doctype
1132
        DBTransform dbt = new DBTransform(conn);
1133
        dbt.transformXMLDocument(xmldoc.toString(), sourcetype, 
1134
                                 "-//W3C//HTML//EN", out);
1135
      }
1136
    } catch (McdbException e) {
1137
      response.setContentType("text/xml");
1138
      e.toXml(out);
1139
    } catch (Throwable t) {
1140
      response.setContentType("text/html");
1141
      out.println(t.getMessage());
1142
    } finally {
1143
      util.returnConnection(conn);
1144
    }    
1145

    
1146
  }
1147

    
1148
  /** 
1149
   * Handle the database putdocument request and write an XML document 
1150
   * to the database connection
1151
   */
1152
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params, 
1153
               HttpServletResponse response, String user, String group) {
1154

    
1155
    Connection conn = null;
1156

    
1157
    try {
1158
      // Get the document indicated
1159
      String[] doctext = (String[])params.get("doctext");
1160

    
1161
      String pub = null;
1162
      if (params.containsKey("public")) {
1163
        pub = ((String[])params.get("public"))[0];
1164
      }
1165

    
1166
      StringReader dtd = null;
1167
      if (params.containsKey("dtdtext")) {
1168
        String[] dtdtext = (String[])params.get("dtdtext");
1169
        try {
1170
          if ( !dtdtext[0].equals("") ) {
1171
            dtd = new StringReader(dtdtext[0]);
1172
          }
1173
        } catch (NullPointerException npe) {}
1174
      }
1175
      
1176
      StringReader xml = null;
1177
      boolean validate = false;
1178
      try {
1179
        // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ... > 
1180
        // in order to decide whether to use validation parser
1181
        validate = validateXML(doctext[0]);
1182
        xml = new StringReader(doctext[0]);
1183

    
1184
        String[] action = (String[])params.get("action");
1185
        String[] docid = (String[])params.get("docid");
1186
        String newdocid = null;
1187

    
1188
        String doAction = null;
1189
        if (action[0].equals("insert")) {
1190
          doAction = "INSERT";
1191
        } else if (action[0].equals("update")) {
1192
          doAction = "UPDATE";
1193
        }
1194

    
1195
        try {
1196
          // get a connection from the pool
1197
          conn = util.getConnection();
1198

    
1199
          // write the document to the database
1200
          try {
1201
            String accNumber = docid[0];
1202
            if (accNumber.equals("")) {
1203
              accNumber = null;
1204
            }
1205
            newdocid = DocumentImpl.write(conn, xml, pub, dtd, doAction,
1206
                                          accNumber, user, group, validate);
1207
          } catch (NullPointerException npe) {
1208
            newdocid = DocumentImpl.write(conn, xml, pub, dtd, doAction,
1209
                                          null, user, group, validate);
1210
          }
1211
        } finally {
1212
          util.returnConnection(conn);
1213
        }    
1214

    
1215
        // set content type and other response header fields first
1216
        response.setContentType("text/xml");
1217
        out.println("<?xml version=\"1.0\"?>");
1218
        out.println("<success>");
1219
        out.println("<docid>" + newdocid + "</docid>"); 
1220
        out.println("</success>");
1221

    
1222
      } catch (NullPointerException npe) {
1223
        response.setContentType("text/xml");
1224
        out.println("<?xml version=\"1.0\"?>");
1225
        out.println("<error>");
1226
        out.println(npe.getMessage()); 
1227
        out.println("</error>");
1228
      }
1229
    } catch (Exception e) {
1230
      response.setContentType("text/xml");
1231
      out.println("<?xml version=\"1.0\"?>");
1232
      out.println("<error>");
1233
      out.println(e.getMessage()); 
1234
      if (e instanceof SAXException) {
1235
        Exception e2 = ((SAXException)e).getException();
1236
        out.println("<error>");
1237
        out.println(e2.getMessage()); 
1238
        out.println("</error>");
1239
      }
1240
      //e.printStackTrace(out);
1241
      out.println("</error>");
1242
    }
1243
  }
1244

    
1245
  /** 
1246
   * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... > 
1247
   * in order to decide whether to use validation parser
1248
   */
1249
  private static boolean validateXML(String xmltext) throws IOException {
1250
    
1251
    StringReader xmlreader = new StringReader(xmltext);
1252
    StringBuffer cbuff = new StringBuffer();
1253
    java.util.Stack st = new java.util.Stack();
1254
    boolean validate = false;
1255
    int c;
1256
    int inx;
1257
    
1258
    // read from the stream until find the keywords
1259
    while ( (st.empty() || st.size()<4) && ((c = xmlreader.read()) != -1) ) {
1260
      cbuff.append((char)c);
1261

    
1262
      // "<!DOCTYPE" keyword is found; put it in the stack
1263
      if ( (inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1 ) {
1264
        cbuff = new StringBuffer();
1265
        st.push("<!DOCTYPE");
1266
      }
1267
      // "PUBLIC" keyword is found; put it in the stack
1268
      if ( (inx = cbuff.toString().indexOf("PUBLIC")) != -1 ) {
1269
        cbuff = new StringBuffer();
1270
        st.push("PUBLIC");
1271
      }
1272
      // "SYSTEM" keyword is found; put it in the stack
1273
      if ( (inx = cbuff.toString().indexOf("SYSTEM")) != -1 ) {
1274
        cbuff = new StringBuffer();
1275
        st.push("SYSTEM");
1276
      }
1277
      // ">" character is found; put it in the stack
1278
      // ">" is found twice: fisrt from <?xml ...?> 
1279
      // and second from <!DOCTYPE ... >
1280
      if ( (inx = cbuff.toString().indexOf(">")) != -1 ) {
1281
        cbuff = new StringBuffer();
1282
        st.push(">");
1283
      }
1284
    }
1285

    
1286
    // close the stream
1287
    xmlreader.close();
1288

    
1289
    // check the stack whether it contains the keywords:
1290
    // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1291
    if ( st.size() == 4 ) {
1292
      if ( ((String)st.pop()).equals(">") &&
1293
           ( ((String)st.peek()).equals("PUBLIC") |
1294
             ((String)st.pop()).equals("SYSTEM") ) &&
1295
           ((String)st.pop()).equals("<!DOCTYPE") )  {
1296
        validate = true;
1297
      }
1298
    }
1299

    
1300
System.out.println("Validation is " + validate);
1301
    return validate;
1302
  }
1303

    
1304
  /** 
1305
   * Handle the database delete request and delete an XML document 
1306
   * from the database connection
1307
   */
1308
  private void handleDeleteAction(PrintWriter out, Hashtable params, 
1309
               HttpServletResponse response, String user, String group) {
1310

    
1311
    String[] docid = (String[])params.get("docid");
1312
    Connection conn = null;
1313

    
1314
    // delete the document from the database
1315
    try {
1316
      // get a connection from the pool
1317
      conn = util.getConnection();
1318
                                      // NOTE -- NEED TO TEST HERE
1319
                                      // FOR EXISTENCE OF DOCID PARAM
1320
                                      // BEFORE ACCESSING ARRAY
1321
      try { 
1322
        DocumentImpl.delete(conn, docid[0], user, group);
1323
        response.setContentType("text/xml");
1324
        out.println("<?xml version=\"1.0\"?>");
1325
        out.println("<success>");
1326
        out.println("Document deleted."); 
1327
        out.println("</success>");
1328
      } catch (AccessionNumberException ane) {
1329
        response.setContentType("text/xml");
1330
        out.println("<?xml version=\"1.0\"?>");
1331
        out.println("<error>");
1332
        out.println("Error deleting document!!!");
1333
        out.println(ane.getMessage()); 
1334
        out.println("</error>");
1335
      }
1336
    } catch (Exception e) {
1337
      response.setContentType("text/xml");
1338
      out.println("<?xml version=\"1.0\"?>");
1339
      out.println("<error>");
1340
      out.println(e.getMessage()); 
1341
      out.println("</error>");
1342
    } finally {
1343
      util.returnConnection(conn);
1344
    }  
1345
  }
1346
  
1347
  /** 
1348
   * Handle the validation request and return the results to the requestor
1349
   */
1350
  private void handleValidateAction(PrintWriter out, Hashtable params, 
1351
               HttpServletResponse response) {
1352

    
1353
    // Get the document indicated
1354
    String valtext = null;
1355
    
1356
    try {
1357
      valtext = ((String[])params.get("valtext"))[0];
1358
    } catch (Exception nullpe) {
1359

    
1360
      Connection conn = null;
1361
      String docid = null;
1362
      try {
1363
        // Find the document id number
1364
        docid = ((String[])params.get("docid"))[0]; 
1365

    
1366
        // get a connection from the pool
1367
        conn = util.getConnection();
1368

    
1369
        // Get the document indicated from the db
1370
        DocumentImpl xmldoc = new DocumentImpl(conn, docid);
1371
        valtext = xmldoc.toString();
1372

    
1373
      } catch (NullPointerException npe) {
1374
        response.setContentType("text/xml");
1375
        out.println("<error>Error getting document ID: " + docid + "</error>");
1376
        if ( conn != null ) { util.returnConnection(conn); }
1377
        return;
1378
      } catch (Exception e) {
1379
        response.setContentType("text/html");
1380
        out.println(e.getMessage()); 
1381
      } finally {
1382
        util.returnConnection(conn);
1383
      }  
1384
    }
1385

    
1386
    Connection conn = null;
1387
    try {
1388
      // get a connection from the pool
1389
      conn = util.getConnection();
1390
      DBValidate valobj = new DBValidate(saxparser,conn);
1391
      boolean valid = valobj.validateString(valtext);
1392

    
1393
      // set content type and other response header fields first
1394
      response.setContentType("text/xml");
1395
      out.println(valobj.returnErrors());
1396

    
1397
    } catch (NullPointerException npe2) {
1398
      // set content type and other response header fields first
1399
      response.setContentType("text/xml");
1400
      out.println("<error>Error validating document.</error>"); 
1401
    } catch (Exception e) {
1402
      response.setContentType("text/html");
1403
      out.println(e.getMessage()); 
1404
    } finally {
1405
      util.returnConnection(conn);
1406
    }  
1407
  }
1408

    
1409
  /** 
1410
   * Handle the document request and return the results to the requestor
1411
   * If a docid is passed in through the params then that document
1412
   * will be retrieved form the DB and put in the zip file.
1413
   * In addition if 1 or more relations parameters are passed, those file
1414
   * will be zipped as well.  Currently this is only implemented for 
1415
   * metacat:// and http:// files.  Support should be added for srb:// files
1416
   * as well.
1417
   */
1418
  private void handleGetDataDocumentAction(ServletOutputStream out, 
1419
               Hashtable params, 
1420
               HttpServletResponse response) {
1421
  //find the related files, get them from their source and zip them into 
1422
  //a zip file.
1423
  try
1424
  {
1425
    Connection conn = util.getConnection();
1426
    String currentDocid = ((String[])params.get("docid"))[0];
1427
    ZipOutputStream zout = new ZipOutputStream(out);
1428
    byte[] bytestring = null;
1429
    ZipEntry zentry = null;
1430
    DocumentImpl xmldoc = null;
1431
    String[] reldocs = null;
1432
    
1433
    if(params.containsKey("relation"))
1434
    { //get the relations from the parameters.
1435
      reldocs = ((String[])params.get("relation"));
1436
    }
1437
    else
1438
    { //let the for loop know that there are no relations to zip
1439
      reldocs = new String[0];
1440
    }
1441

    
1442
    //write the base file to the zip file.
1443
    xmldoc = new DocumentImpl(conn, currentDocid);
1444
    bytestring = (xmldoc.toString()).getBytes();
1445
    zentry = new ZipEntry(currentDocid + ".xml");
1446
    //create a new zip entry and write the file to the stream
1447
    zentry.setSize(bytestring.length);
1448
    zout.putNextEntry(zentry);
1449
    zout.write(bytestring, 0, bytestring.length);
1450
    zout.closeEntry(); //get ready for the next entry. 
1451

    
1452
    //zip up the related documents
1453
    for(int i=0; i<reldocs.length; i++)
1454
    {
1455
      //MetacatURL murl = new MetacatURL(((String)reldocs[i]));
1456
      URL murl = new URL(((String)reldocs[i]));
1457
      Hashtable qparams = util.parseQuery(murl.getQuery());
1458
      if(murl.getProtocol().equals("metacat"))
1459
      {
1460
        //get the document from the database
1461
        //xmldoc = new DocumentImpl(conn, (String)murl.getHashParam("docid"));
1462
        xmldoc = new DocumentImpl(conn, (String)qparams.get("docid"));
1463
        bytestring = (xmldoc.toString()).getBytes();
1464
        zentry = new ZipEntry(qparams.get("docid") + ".xml");
1465
        //create a new zip entry and write the file to the stream
1466
        zentry.setSize(bytestring.length);
1467
        zout.putNextEntry(zentry);
1468
        zout.write(bytestring, 0, bytestring.length);
1469
        zout.closeEntry(); //get ready for the next entry.
1470
      }
1471
      else if(murl.getProtocol().equals("http"))
1472
      {
1473
        //Hashtable murlParams = murl.getHashParams();
1474
        if(qparams.containsKey("httpurl"))
1475
        {//httpurl is the param name for an http url.
1476
          URL urlconn = new URL((String)qparams.get("httpurl"));  
1477
          //create a new url obj.
1478
          BufferedReader htmldoc = new BufferedReader(
1479
                                   new InputStreamReader(urlconn.openStream()));
1480
          //get the data from the web server
1481
          try
1482
          { //zip the document
1483
            String line=null;
1484
            zentry = new ZipEntry((String)qparams.get("filename"));
1485
            //get just the filename from the URL.
1486
            zout.putNextEntry(zentry);
1487
            //make a new entry in the zip file stream
1488
            while((line = htmldoc.readLine()) != null)
1489
            {
1490
              bytestring = (line.toString()).getBytes();
1491
              zout.write(bytestring, 0, bytestring.length);
1492
              //write out the file line by line
1493
            }
1494
            zout.closeEntry(); //close the entry in the file
1495
          }
1496
          catch(Exception e)
1497
          {
1498
            System.out.println("error downloading html document "+ 
1499
                               "in metacatServlet.handleGetDataDocumentAction"); 
1500
          }
1501
        }
1502
      }
1503
    }
1504
    zout.finish();  //terminate the zip file
1505
    zout.close();   //close the stream.
1506
    util.returnConnection(conn); //return the connection to the pool
1507
  }
1508
  catch(Exception e)
1509
  {
1510
    System.out.println("Error creating zip file from " +
1511
                       "MetacatServlet.handleGetDataDocumentAction: " + 
1512
                        e.getMessage()); 
1513
    e.printStackTrace(System.out);
1514
  }
1515
           
1516
   /*
1517
   //////////old code using a shell script/////////////////////////////////
1518
   
1519
      boolean error_flag = false;
1520
      String error_message = "";
1521
      // Get the document indicated
1522
      String[] datadoc = (String[])params.get("datadoc");
1523
      // defaultdatapath = "C:\\Temp\\";    // for testing only!!!
1524
      // executescript = "test.bat";        // for testing only!!!
1525
      
1526
      // set content type and other response header fields first
1527
      response.setContentType("application/octet-stream");
1528
      if (defaultdatapath!=null) {
1529
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) {
1530
          defaultdatapath=defaultdatapath+System.getProperty("file.separator");
1531
        }
1532
        System.out.println("Path= "+defaultdatapath+datadoc[0]);
1533
        if (executescript!=null) {
1534
          String command = null;
1535
          File scriptfile = new File(executescript);
1536
          if (scriptfile.exists()) {
1537
            command=executescript+" "+datadoc[0]; // script includes path
1538
        } else {     // look in defaultdatapath
1539
            // on Win98 one MUST include the .bat extender
1540
            command = defaultdatapath+executescript+" "+datadoc[0];  
1541
        }
1542
      System.out.println(command);
1543
      try {
1544
      Process proc = Runtime.getRuntime().exec(command);
1545
      proc.waitFor();
1546
      }
1547
      catch (Exception eee) {
1548
        System.out.println("Error running process!");
1549
        error_flag = true;
1550
        error_message = "Error running process!";}
1551
      } // end executescript not null if
1552
      File datafile = new File(defaultdatapath+datadoc[0]);
1553
      try {
1554
      FileInputStream fw = new FileInputStream(datafile);
1555
      int x;
1556
      while ((x = fw.read())!=-1) {
1557
        out.write(x); }
1558
        fw.close();
1559
      } catch (Exception e) {
1560
        System.out.println("Error in returning file\n"+e.getMessage());
1561
        error_flag=true;
1562
        error_message = error_message+"\nError in returning file\n"+
1563
                        e.getMessage();
1564
      }
1565
    } // end defaultdatapath not null if
1566
    */
1567
  }
1568
  
1569
  /** 
1570
   * Handle "getaccesscontrol" action.
1571
   * Read Access Control List from db connection in XML format
1572
   */
1573
  private void handleGetAccessControlAction(PrintWriter out, Hashtable params, 
1574
                                       HttpServletResponse response, 
1575
                                       String username, String groupname) {
1576

    
1577
    Connection conn = null;
1578
    String docid = ((String[])params.get("docid"))[0];
1579
    
1580
    try {
1581

    
1582
        // get connection from the pool
1583
        conn = util.getConnection();
1584
        AccessControlList aclobj = new AccessControlList(conn);
1585
        String acltext = aclobj.getACL(docid, username, groupname);
1586
        out.println(acltext);
1587

    
1588
    } catch (Exception e) {
1589
      out.println("<?xml version=\"1.0\"?>");
1590
      out.println("<error>");
1591
      out.println(e.getMessage());
1592
      out.println("</error>");
1593
    } finally {
1594
      util.returnConnection(conn);
1595
    }  
1596
    
1597
  }
1598

    
1599
  /** 
1600
   * Handle "getdoctypes" action.
1601
   * Read all doctypes from db connection in XML format
1602
   */
1603
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params, 
1604
                                       HttpServletResponse response) {
1605

    
1606
    Connection conn = null;
1607
    
1608
    try {
1609

    
1610
        // get connection from the pool
1611
        conn = util.getConnection();
1612
        DBUtil dbutil = new DBUtil(conn);
1613
        String doctypes = dbutil.readDoctypes();
1614
        out.println(doctypes);
1615

    
1616
    } catch (Exception e) {
1617
      out.println("<?xml version=\"1.0\"?>");
1618
      out.println("<error>");
1619
      out.println(e.getMessage());
1620
      out.println("</error>");
1621
    } finally {
1622
      util.returnConnection(conn);
1623
    }  
1624
    
1625
  }
1626

    
1627
  /** 
1628
   * Handle the "getdtdschema" action.
1629
   * Read DTD or Schema file for a given doctype from Metacat catalog system
1630
   */
1631
  private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
1632
                                        HttpServletResponse response) {
1633

    
1634
    Connection conn = null;
1635
    String doctype = null;
1636
    String[] doctypeArr = (String[])params.get("doctype");
1637

    
1638
    // get only the first doctype specified in the list of doctypes
1639
    // it could be done for all doctypes in that list
1640
    if (doctypeArr != null) {
1641
        doctype = ((String[])params.get("doctype"))[0]; 
1642
    }
1643

    
1644
    try {
1645

    
1646
        // get connection from the pool
1647
        conn = util.getConnection();
1648
        DBUtil dbutil = new DBUtil(conn);
1649
        String dtdschema = dbutil.readDTDSchema(doctype);
1650
        out.println(dtdschema);
1651

    
1652
    } catch (Exception e) {
1653
      out.println("<?xml version=\"1.0\"?>");
1654
      out.println("<error>");
1655
      out.println(e.getMessage());
1656
      out.println("</error>");
1657
    } finally {
1658
      util.returnConnection(conn);
1659
    }  
1660
    
1661
  }
1662

    
1663
  /** 
1664
   * Handle the "getdataguide" action.
1665
   * Read Data Guide for a given doctype from db connection in XML format
1666
   */
1667
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
1668
                                        HttpServletResponse response) {
1669

    
1670
    Connection conn = null;
1671
    String doctype = null;
1672
    String[] doctypeArr = (String[])params.get("doctype");
1673

    
1674
    // get only the first doctype specified in the list of doctypes
1675
    // it could be done for all doctypes in that list
1676
    if (doctypeArr != null) {
1677
        doctype = ((String[])params.get("doctype"))[0]; 
1678
    }
1679

    
1680
    try {
1681

    
1682
        // get connection from the pool
1683
        conn = util.getConnection();
1684
        DBUtil dbutil = new DBUtil(conn);
1685
        String dataguide = dbutil.readDataGuide(doctype);
1686
        out.println(dataguide);
1687

    
1688
    } catch (Exception e) {
1689
      out.println("<?xml version=\"1.0\"?>");
1690
      out.println("<error>");
1691
      out.println(e.getMessage());
1692
      out.println("</error>");
1693
    } finally {
1694
      util.returnConnection(conn);
1695
    }  
1696
    
1697
  }
1698

    
1699
}
(32-32/43)