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-03-05 16:25:52 -0800 (Mon, 05 Mar 2001) $'
11
 * '$Revision: 725 $'
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
 * action=getprincipals -- retrieve a list of principals in XML<br>
100
 * datadoc -- data document name (id)<br>
101
 * <p>
102
 * The particular combination of parameters that are valid for each 
103
 * particular action value is quite specific.  This documentation
104
 * will be reorganized to reflect this information.
105
 */
106
public class MetaCatServlet extends HttpServlet {
107

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

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

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

    
136
      util = new MetaCatUtil();
137

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

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

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

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

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

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

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

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

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

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

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

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

    
254
    // handle login action
255
    if (action.equals("login")) {
256

    
257
      handleLoginAction(response.getWriter(), params, request, response);
258

    
259
    // handle logout action  
260
    } else if (action.equals("logout")) {
261

    
262
      handleLogoutAction(response.getWriter(), params, request, response);
263

    
264
    // aware of session expiration on every request  
265
    } else {   
266

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

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

    
515
  /** 
516
   * Handle the login request. Create a new session object.
517
   * Do user authentication through the session.
518
   */
519
  private void handleLoginAction(PrintWriter out, Hashtable params, 
520
               HttpServletRequest request, HttpServletResponse response) {
521

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

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

    
577
  }    
578

    
579
  /** 
580
   * Handle the logout request. Close the connection.
581
   */
582
  private void handleLogoutAction(PrintWriter out, Hashtable params, 
583
               HttpServletRequest request, HttpServletResponse response) {
584

    
585
    String qformat = ((String[])params.get("qformat"))[0];
586

    
587
    // close the connection
588
    HttpSession sess = request.getSession(false);
589
    if (sess != null) { sess.invalidate();  }    
590

    
591
    // produce output
592
    StringBuffer output = new StringBuffer();
593
    output.append("<?xml version=\"1.0\"?>");
594
    output.append("<logout>");
595
    output.append("User logged out");
596
    output.append("</logout>");
597

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

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

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

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

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

    
817
    if(doclist != null)
818
    {
819
      Enumeration doclistkeys = doclist.keys(); 
820
      while (doclistkeys.hasMoreElements()) 
821
      {
822
        docid = (String)doclistkeys.nextElement();
823
        document = (String)doclist.get(docid);
824
        resultset.append("  <document>" + document + "</document>");
825
      }
826
    }
827

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

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

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

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

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

    
1152
  }
1153

    
1154
  /** 
1155
   * Handle the database putdocument request and write an XML document 
1156
   * to the database connection
1157
   */
1158
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params, 
1159
               HttpServletResponse response, String user, String group) {
1160

    
1161
    Connection conn = null;
1162

    
1163
    try {
1164
      // Get the document indicated
1165
      String[] doctext = (String[])params.get("doctext");
1166

    
1167
      String pub = null;
1168
      if (params.containsKey("public")) {
1169
        pub = ((String[])params.get("public"))[0];
1170
      }
1171

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

    
1190
        String[] action = (String[])params.get("action");
1191
        String[] docid = (String[])params.get("docid");
1192
        String newdocid = null;
1193

    
1194
        String doAction = null;
1195
        if (action[0].equals("insert")) {
1196
          doAction = "INSERT";
1197
        } else if (action[0].equals("update")) {
1198
          doAction = "UPDATE";
1199
        }
1200

    
1201
        try {
1202
          // get a connection from the pool
1203
          conn = util.getConnection();
1204

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

    
1221
        // set content type and other response header fields first
1222
        response.setContentType("text/xml");
1223
        out.println("<?xml version=\"1.0\"?>");
1224
        out.println("<success>");
1225
        out.println("<docid>" + newdocid + "</docid>"); 
1226
        out.println("</success>");
1227

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

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

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

    
1292
    // close the stream
1293
    xmlreader.close();
1294

    
1295
    // check the stack whether it contains the keywords:
1296
    // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1297
    if ( st.size() == 4 ) {
1298
      if ( ((String)st.pop()).equals(">") &&
1299
           ( ((String)st.peek()).equals("PUBLIC") |
1300
             ((String)st.pop()).equals("SYSTEM") ) &&
1301
           ((String)st.pop()).equals("<!DOCTYPE") )  {
1302
        validate = true;
1303
      }
1304
    }
1305

    
1306
System.out.println("Validation is " + validate);
1307
    return validate;
1308
  }
1309

    
1310
  /** 
1311
   * Handle the database delete request and delete an XML document 
1312
   * from the database connection
1313
   */
1314
  private void handleDeleteAction(PrintWriter out, Hashtable params, 
1315
               HttpServletResponse response, String user, String group) {
1316

    
1317
    String[] docid = (String[])params.get("docid");
1318
    Connection conn = null;
1319

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

    
1359
    // Get the document indicated
1360
    String valtext = null;
1361
    
1362
    try {
1363
      valtext = ((String[])params.get("valtext"))[0];
1364
    } catch (Exception nullpe) {
1365

    
1366
      Connection conn = null;
1367
      String docid = null;
1368
      try {
1369
        // Find the document id number
1370
        docid = ((String[])params.get("docid"))[0]; 
1371

    
1372
        // get a connection from the pool
1373
        conn = util.getConnection();
1374

    
1375
        // Get the document indicated from the db
1376
        DocumentImpl xmldoc = new DocumentImpl(conn, docid);
1377
        valtext = xmldoc.toString();
1378

    
1379
      } catch (NullPointerException npe) {
1380
        response.setContentType("text/xml");
1381
        out.println("<error>Error getting document ID: " + docid + "</error>");
1382
        if ( conn != null ) { util.returnConnection(conn); }
1383
        return;
1384
      } catch (Exception e) {
1385
        response.setContentType("text/html");
1386
        out.println(e.getMessage()); 
1387
      } finally {
1388
        util.returnConnection(conn);
1389
      }  
1390
    }
1391

    
1392
    Connection conn = null;
1393
    try {
1394
      // get a connection from the pool
1395
      conn = util.getConnection();
1396
      DBValidate valobj = new DBValidate(saxparser,conn);
1397
      boolean valid = valobj.validateString(valtext);
1398

    
1399
      // set content type and other response header fields first
1400
      response.setContentType("text/xml");
1401
      out.println(valobj.returnErrors());
1402

    
1403
    } catch (NullPointerException npe2) {
1404
      // set content type and other response header fields first
1405
      response.setContentType("text/xml");
1406
      out.println("<error>Error validating document.</error>"); 
1407
    } catch (Exception e) {
1408
      response.setContentType("text/html");
1409
      out.println(e.getMessage()); 
1410
    } finally {
1411
      util.returnConnection(conn);
1412
    }  
1413
  }
1414

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

    
1448
    //write the base file to the zip file.
1449
    xmldoc = new DocumentImpl(conn, currentDocid);
1450
    bytestring = (xmldoc.toString()).getBytes();
1451
    zentry = new ZipEntry(currentDocid + ".xml");
1452
    //create a new zip entry and write the file to the stream
1453
    zentry.setSize(bytestring.length);
1454
    zout.putNextEntry(zentry);
1455
    zout.write(bytestring, 0, bytestring.length);
1456
    zout.closeEntry(); //get ready for the next entry. 
1457

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

    
1583
    Connection conn = null;
1584
    String docid = ((String[])params.get("docid"))[0];
1585
    
1586
    try {
1587

    
1588
        // get connection from the pool
1589
        conn = util.getConnection();
1590
        AccessControlList aclobj = new AccessControlList(conn);
1591
        String acltext = aclobj.getACL(docid, username, groupname);
1592
        out.println(acltext);
1593

    
1594
    } catch (Exception e) {
1595
      out.println("<?xml version=\"1.0\"?>");
1596
      out.println("<error>");
1597
      out.println(e.getMessage());
1598
      out.println("</error>");
1599
    } finally {
1600
      util.returnConnection(conn);
1601
    }  
1602
    
1603
  }
1604

    
1605
  /** 
1606
   * Handle "getdoctypes" action.
1607
   * Read all doctypes from db connection in XML format
1608
   */
1609
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params, 
1610
                                       HttpServletResponse response) {
1611

    
1612
    Connection conn = null;
1613
    
1614
    try {
1615

    
1616
        // get connection from the pool
1617
        conn = util.getConnection();
1618
        DBUtil dbutil = new DBUtil(conn);
1619
        String doctypes = dbutil.readDoctypes();
1620
        out.println(doctypes);
1621

    
1622
    } catch (Exception e) {
1623
      out.println("<?xml version=\"1.0\"?>");
1624
      out.println("<error>");
1625
      out.println(e.getMessage());
1626
      out.println("</error>");
1627
    } finally {
1628
      util.returnConnection(conn);
1629
    }  
1630
    
1631
  }
1632

    
1633
  /** 
1634
   * Handle the "getdtdschema" action.
1635
   * Read DTD or Schema file for a given doctype from Metacat catalog system
1636
   */
1637
  private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
1638
                                        HttpServletResponse response) {
1639

    
1640
    Connection conn = null;
1641
    String doctype = null;
1642
    String[] doctypeArr = (String[])params.get("doctype");
1643

    
1644
    // get only the first doctype specified in the list of doctypes
1645
    // it could be done for all doctypes in that list
1646
    if (doctypeArr != null) {
1647
        doctype = ((String[])params.get("doctype"))[0]; 
1648
    }
1649

    
1650
    try {
1651

    
1652
        // get connection from the pool
1653
        conn = util.getConnection();
1654
        DBUtil dbutil = new DBUtil(conn);
1655
        String dtdschema = dbutil.readDTDSchema(doctype);
1656
        out.println(dtdschema);
1657

    
1658
    } catch (Exception e) {
1659
      out.println("<?xml version=\"1.0\"?>");
1660
      out.println("<error>");
1661
      out.println(e.getMessage());
1662
      out.println("</error>");
1663
    } finally {
1664
      util.returnConnection(conn);
1665
    }  
1666
    
1667
  }
1668

    
1669
  /** 
1670
   * Handle the "getdataguide" action.
1671
   * Read Data Guide for a given doctype from db connection in XML format
1672
   */
1673
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
1674
                                        HttpServletResponse response) {
1675

    
1676
    Connection conn = null;
1677
    String doctype = null;
1678
    String[] doctypeArr = (String[])params.get("doctype");
1679

    
1680
    // get only the first doctype specified in the list of doctypes
1681
    // it could be done for all doctypes in that list
1682
    if (doctypeArr != null) {
1683
        doctype = ((String[])params.get("doctype"))[0]; 
1684
    }
1685

    
1686
    try {
1687

    
1688
        // get connection from the pool
1689
        conn = util.getConnection();
1690
        DBUtil dbutil = new DBUtil(conn);
1691
        String dataguide = dbutil.readDataGuide(doctype);
1692
        out.println(dataguide);
1693

    
1694
    } catch (Exception e) {
1695
      out.println("<?xml version=\"1.0\"?>");
1696
      out.println("<error>");
1697
      out.println(e.getMessage());
1698
      out.println("</error>");
1699
    } finally {
1700
      util.returnConnection(conn);
1701
    }  
1702
    
1703
  }
1704

    
1705
  /** 
1706
   * Handle the "getprincipals" action.
1707
   * Read all principals from authentication scheme in XML format
1708
   */
1709
  private void handleGetPrincipalsAction(PrintWriter out, String user,
1710
                                         String password) {
1711

    
1712
    Connection conn = null;
1713

    
1714
    try {
1715

    
1716
        // get connection from the pool
1717
        AuthSession auth = new AuthSession();
1718
        String principals = auth.getPrincipals(user, password);
1719
        out.println(principals);
1720

    
1721
    } catch (Exception e) {
1722
      out.println("<?xml version=\"1.0\"?>");
1723
      out.println("<error>");
1724
      out.println(e.getMessage());
1725
      out.println("</error>");
1726
    } finally {
1727
      util.returnConnection(conn);
1728
    }  
1729
    
1730
  }
1731

    
1732
}
(32-32/43)