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-06 13:51:17 -0800 (Tue, 06 Feb 2001) $'
11
 * '$Revision: 695 $'
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=getdataguide -- retrieve a Data Guide<br>
98
 * datadoc -- data document name (id)<br>
99
 * <p>
100
 * The particular combination of parameters that are valid for each 
101
 * particular action value is quite specific.  This documentation
102
 * will be reorganized to reflect this information.
103
 */
104
public class MetaCatServlet extends HttpServlet {
105

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

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

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

    
134
      util = new MetaCatUtil();
135

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
567
  }    
568

    
569
  /** 
570
   * Handle the logout request. Close the connection.
571
   */
572
  private void handleLogoutAction(PrintWriter out, Hashtable params, 
573
               HttpServletRequest request, HttpServletResponse response) {
574

    
575
    String qformat = ((String[])params.get("qformat"))[0];
576

    
577
    // close the connection
578
    HttpSession sess = request.getSession(false);
579
    if (sess != null) { sess.invalidate();  }    
580

    
581
    // produce output
582
    StringBuffer output = new StringBuffer();
583
    output.append("<?xml version=\"1.0\"?>");
584
    output.append("<logout>");
585
    output.append("User logged out");
586
    output.append("</logout>");
587

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

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

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

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

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

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

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

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

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

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

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

    
1142
  }
1143

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

    
1151
    Connection conn = null;
1152

    
1153
    try {
1154
      // Get the document indicated
1155
      String[] doctext = (String[])params.get("doctext");
1156

    
1157
      String pub = null;
1158
      if (params.containsKey("public")) {
1159
        pub = ((String[])params.get("public"))[0];
1160
      }
1161

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

    
1180
        String[] action = (String[])params.get("action");
1181
        String[] docid = (String[])params.get("docid");
1182
        String newdocid = null;
1183

    
1184
        String doAction = null;
1185
        if (action[0].equals("insert")) {
1186
          doAction = "INSERT";
1187
        } else if (action[0].equals("update")) {
1188
          doAction = "UPDATE";
1189
        }
1190

    
1191
        try {
1192
          // get a connection from the pool
1193
          conn = util.getConnection();
1194

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

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

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

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

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

    
1282
    // close the stream
1283
    xmlreader.close();
1284

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

    
1296
System.out.println("Validation is " + validate);
1297
    return validate;
1298
  }
1299

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

    
1307
    String[] docid = (String[])params.get("docid");
1308
    Connection conn = null;
1309

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

    
1349
    // Get the document indicated
1350
    String valtext = null;
1351
    
1352
    try {
1353
      valtext = ((String[])params.get("valtext"))[0];
1354
    } catch (Exception nullpe) {
1355

    
1356
      Connection conn = null;
1357
      String docid = null;
1358
      try {
1359
        // Find the document id number
1360
        docid = ((String[])params.get("docid"))[0]; 
1361

    
1362
        // get a connection from the pool
1363
        conn = util.getConnection();
1364

    
1365
        // Get the document indicated from the db
1366
        DocumentImpl xmldoc = new DocumentImpl(conn, docid);
1367
        valtext = xmldoc.toString();
1368

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

    
1382
    Connection conn = null;
1383
    try {
1384
      // get a connection from the pool
1385
      conn = util.getConnection();
1386
      DBValidate valobj = new DBValidate(saxparser,conn);
1387
      boolean valid = valobj.validateString(valtext);
1388

    
1389
      // set content type and other response header fields first
1390
      response.setContentType("text/xml");
1391
      out.println(valobj.returnErrors());
1392

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

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

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

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

    
1573
    Connection conn = null;
1574
    String docid = ((String[])params.get("docid"))[0];
1575
    
1576
    try {
1577

    
1578
        // get connection from the pool
1579
        conn = util.getConnection();
1580
        AccessControlList aclobj = new AccessControlList(conn);
1581
        String acltext = aclobj.getACL(docid, username, groupname);
1582
        out.println(acltext);
1583

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

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

    
1602
    Connection conn = null;
1603
    
1604
    try {
1605

    
1606
        // get connection from the pool
1607
        conn = util.getConnection();
1608
        DBUtil dbutil = new DBUtil(conn);
1609
        String doctypes = dbutil.readDoctypes();
1610
        out.println(doctypes);
1611

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

    
1623
  /** 
1624
   * Handle the "getdataguide" action.
1625
   * Read Data Guide for a given doctype from db connection in XML format
1626
   */
1627
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
1628
                                        HttpServletResponse response) {
1629

    
1630
    Connection conn = null;
1631
    String doctype = null;
1632
    String[] doctypeArr = (String[])params.get("doctype");
1633

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

    
1640
    try {
1641

    
1642
        // get connection from the pool
1643
        conn = util.getConnection();
1644
        DBUtil dbutil = new DBUtil(conn);
1645
        String dataguide = dbutil.readDataGuide(doctype);
1646
        out.println(dataguide);
1647

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

    
1659
}
(32-32/43)