Project

General

Profile

1 51 jones
/**
2 203 jones
 *  '$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 361 berkley
 *    Authors: Matt Jones, Dan Higgins, Jivka Bojilova, Chad Berkley
7 348 jones
 *    Release: @release@
8 154 jones
 *
9 203 jones
 *   '$Author$'
10
 *     '$Date$'
11
 * '$Revision$'
12 669 jones
 *
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 51 jones
 */
27
28
package edu.ucsb.nceas.metacat;
29
30 46 jones
import java.io.PrintWriter;
31
import java.io.IOException;
32 50 jones
import java.io.Reader;
33
import java.io.StringReader;
34 59 jones
import java.io.BufferedReader;
35 185 jones
import java.io.File;
36
import java.io.FileInputStream;
37 458 berkley
import java.io.FileOutputStream;
38
import java.io.InputStreamReader;
39 453 berkley
import java.io.DataInputStream;
40 46 jones
import java.util.Enumeration;
41
import java.util.Hashtable;
42 341 berkley
import java.util.ResourceBundle;
43 648 berkley
import java.util.Random;
44 82 jones
import java.util.PropertyResourceBundle;
45 50 jones
import java.net.URL;
46
import java.net.MalformedURLException;
47 85 jones
import java.sql.PreparedStatement;
48
import java.sql.ResultSet;
49 50 jones
import java.sql.Connection;
50 55 jones
import java.sql.SQLException;
51 361 berkley
import java.lang.reflect.*;
52 453 berkley
import java.net.*;
53 458 berkley
import java.util.zip.*;
54 46 jones
55
import javax.servlet.ServletConfig;
56
import javax.servlet.ServletContext;
57
import javax.servlet.ServletException;
58 48 jones
import javax.servlet.ServletInputStream;
59 46 jones
import javax.servlet.http.HttpServlet;
60
import javax.servlet.http.HttpServletRequest;
61
import javax.servlet.http.HttpServletResponse;
62 210 bojilova
import javax.servlet.http.HttpSession;
63 47 jones
import javax.servlet.http.HttpUtils;
64 458 berkley
import javax.servlet.ServletOutputStream;
65 46 jones
66 50 jones
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 204 jones
import org.xml.sax.SAXException;
72
73 46 jones
/**
74
 * A metadata catalog server implemented as a Java Servlet
75 154 jones
 *
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 205 jones
 * 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 566 jones
 * action=read -- display an XML document in XML or HTML<br>
85 205 jones
 * doctype -- document type list returned by the query (publicID)<br>
86 154 jones
 * 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 205 jones
 * doctext -- XML text of the document to load into the database<br>
90 598 bojilova
 * 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 183 jones
 * query -- actual query text (to go with 'action=query' or 'action=squery')<br>
93 205 jones
 * valtext -- XML text to be validated<br>
94 688 bojilova
 * 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 699 bojilova
 * action=getdtdschema -- retrieve a DTD or Schema file<br>
98 688 bojilova
 * action=getdataguide -- retrieve a Data Guide<br>
99 205 jones
 * datadoc -- data document name (id)<br>
100
 * <p>
101
 * The particular combination of parameters that are valid for each
102
 * particular action value is quite specific.  This documentation
103
 * will be reorganized to reflect this information.
104 46 jones
 */
105
public class MetaCatServlet extends HttpServlet {
106
107 370 berkley
  private ServletConfig config = null;
108
  private ServletContext context = null;
109
  private Hashtable connectionPool = new Hashtable();
110
  private String resultStyleURL = null;
111
  private String xmlcatalogfile = null;
112
  private String saxparser = null;
113
  private String defaultdatapath = null;
114
  private String servletpath = null;
115 380 jones
  private PropertyResourceBundle options = null;
116
  private MetaCatUtil util = null;
117
118
  // path to directory where data files
119
  // that can be downloaded will be stored
120 370 berkley
  private String htmlpath = null;
121 380 jones
  // script to get data file and put it
122
  // in defaultdocpath dir
123 370 berkley
  private String executescript  = null;
124 46 jones
125 50 jones
  /**
126
   * Initialize the servlet by creating appropriate database connections
127
   */
128 46 jones
  public void init( ServletConfig config ) throws ServletException {
129
    try {
130
      super.init( config );
131
      this.config = config;
132 332 bojilova
      this.context = config.getServletContext();
133 184 jones
      System.out.println("MetaCatServlet Initialize");
134 82 jones
135 184 jones
      util = new MetaCatUtil();
136
137 83 jones
      // Get the configuration file information
138 184 jones
      resultStyleURL = util.getOption("resultStyleURL");
139
      xmlcatalogfile = util.getOption("xmlcatalogfile");
140
      saxparser = util.getOption("saxparser");
141
      defaultdatapath = util.getOption("defaultdatapath");
142 593 berkley
      executescript = util.getOption("executescript");
143 360 bojilova
      servletpath = util.getOption("servletpath");
144
      htmlpath = util.getOption("htmlpath");
145 598 bojilova
146
//      try {
147
//        // Open a pool of db connections
148
//        connectionPool = util.getConnectionPool();
149
//      } catch (Exception e) {
150
//        System.err.println("Error creating pool of database connections");
151
//        System.err.println(e.getMessage());
152
//      }
153 46 jones
    } catch ( ServletException ex ) {
154
      throw ex;
155
    }
156
  }
157
158 320 bojilova
  /**
159
   * Close all db connections from the pool
160
   */
161
  public void destroy() {
162
163
    if (util != null) {
164
        util.closeConnections();
165
    }
166
  }
167
168 50 jones
  /** Handle "GET" method requests from HTTP clients */
169 46 jones
  public void doGet (HttpServletRequest request, HttpServletResponse response)
170
    throws ServletException, IOException {
171
172 48 jones
    // Process the data and send back the response
173 59 jones
    handleGetOrPost(request, response);
174 48 jones
  }
175
176 50 jones
  /** Handle "POST" method requests from HTTP clients */
177 48 jones
  public void doPost( HttpServletRequest request, HttpServletResponse response)
178
    throws ServletException, IOException {
179
180
    // Process the data and send back the response
181 59 jones
    handleGetOrPost(request, response);
182 48 jones
  }
183
184 49 jones
  /**
185 50 jones
   * Control servlet response depending on the action parameter specified
186 49 jones
   */
187 382 berkley
  private void handleGetOrPost(HttpServletRequest request,
188 59 jones
    HttpServletResponse response)
189 355 berkley
    throws ServletException, IOException
190
 {
191 48 jones
192 309 bojilova
    if ( util == null ) {
193
        util = new MetaCatUtil();
194
    }
195 598 bojilova
    if ( connectionPool.isEmpty() ) {
196 309 bojilova
      try {
197
        // Open a pool of db connections
198
        connectionPool = util.getConnectionPool();
199
      } catch (Exception e) {
200 675 berkley
        System.err.println("Error creating pool of database connections in " +
201
                            " MetaCatServlet.handleGetOrPost");
202 309 bojilova
        System.err.println(e.getMessage());
203
      }
204
    }
205 49 jones
    // Get a handle to the output stream back to the client
206 566 jones
    //PrintWriter pwout = response.getWriter();
207 102 jones
    //response.setContentType("text/html");
208 49 jones
209 59 jones
    String name = null;
210
    String[] value = null;
211 103 jones
    String[] docid = new String[3];
212 59 jones
    Hashtable params = new Hashtable();
213
    Enumeration paramlist = request.getParameterNames();
214
    while (paramlist.hasMoreElements()) {
215
      name = (String)paramlist.nextElement();
216
      value = request.getParameterValues(name);
217 103 jones
218
      // Decode the docid and mouse click information
219
      if (name.endsWith(".y")) {
220
        docid[0] = name.substring(0,name.length()-2);
221
        //out.println("docid => " + docid[0]);
222
        params.put("docid", docid);
223
        name = "ypos";
224
      }
225
      if (name.endsWith(".x")) {
226
        name = "xpos";
227 373 berkley
      }
228 103 jones
229 566 jones
      //pwout.println(name + " => " + value[0]);
230 373 berkley
      params.put(name,value);
231
    }
232 355 berkley
233 509 bojilova
    //if the user clicked on the input images, decode which image
234
    //was clicked then set the action.
235 505 jones
    String action = ((String[])params.get("action"))[0];
236
    util.debugMessage("Line 213: Action is: " + action);
237 509 bojilova
238 505 jones
    //MBJELIMINATE String action = decodeMouseAction(params);
239
    //if(action.equals("error"))
240
    //{
241 509 bojilova
      //util.debugMessage("Line 218: Action is: " + action);
242 505 jones
      //action = ((String[])params.get("action"))[0];
243
    //}
244 355 berkley
245 380 jones
    // This block handles session management for the servlet
246
    // by looking up the current session information for all actions
247 509 bojilova
    // other than "login" and "logout"
248 425 bojilova
    String username = null;
249
    String groupname = null;
250 648 berkley
    String sess_id = null;
251 509 bojilova
252
    // handle login action
253
    if (action.equals("login")) {
254
255 458 berkley
      handleLoginAction(response.getWriter(), params, request, response);
256 509 bojilova
257 210 bojilova
    // handle logout action
258 509 bojilova
    } else if (action.equals("logout")) {
259 361 berkley
260 509 bojilova
      handleLogoutAction(response.getWriter(), params, request, response);
261 361 berkley
262 251 bojilova
    // aware of session expiration on every request
263 343 jones
    } else {
264 509 bojilova
265 332 bojilova
      HttpSession sess = request.getSession(true);
266
      if (sess.isNew()) {
267 251 bojilova
        // session expired or has not been stored b/w user requests
268 441 bojilova
        username = "public";
269 673 bojilova
        sess.setAttribute("username", username);
270 425 bojilova
      } else {
271
        username = (String)sess.getAttribute("username");
272
        groupname = (String)sess.getAttribute("groupname");
273 648 berkley
        try
274
        {
275
          sess_id = (String)sess.getId();
276
        }
277
        catch(IllegalStateException ise)
278
        {
279
          System.out.println("error in handleGetOrPost: this shouldn't " +
280
                             "happen: the session should be valid: " +
281
                             ise.getMessage());
282
        }
283 425 bojilova
      }
284 210 bojilova
    }
285 219 jones
286 380 jones
    // Now that we know the session is valid, we can delegate the request
287
    // to a particular action handler
288 361 berkley
    if(action.equals("query"))
289
    {
290 458 berkley
      handleQuery(response.getWriter(), params, response, username, groupname);
291 373 berkley
    }
292 371 berkley
    else if(action.equals("squery"))
293 361 berkley
    {
294 373 berkley
      if(params.containsKey("query"))
295
      {
296 458 berkley
        handleSQuery(response.getWriter(), params, response, username, groupname);
297 373 berkley
      }
298
      else
299
      {
300 458 berkley
        PrintWriter out = response.getWriter();
301 373 berkley
        out.println("Illegal action squery without \"query\" parameter");
302
      }
303
    }
304 566 jones
    else if (action.equals("read")) {
305 636 berkley
      //PrintWriter out = response.getWriter();
306 87 jones
      try {
307 661 berkley
        handleReadAction(/*out,*/ params, response, username);
308 87 jones
      } catch (ClassNotFoundException e) {
309 675 berkley
        System.out.println("Error in MetacatServlet.handlGetOrPost: " +
310
                            e.getMessage());
311 87 jones
      } catch (SQLException se) {
312 675 berkley
        System.out.println("Error in MetaCatServlet.handleGetOrPost: " +
313
                            se.getMessage());
314 87 jones
      }
315 453 berkley
    }
316 566 jones
/*
317 453 berkley
    else if (action.equals("getrelateddocument")) {
318 458 berkley
      PrintWriter out = response.getWriter();
319 453 berkley
      try {
320
        handleGetRelatedDocumentAction(out, params, response);
321
      } catch (ClassNotFoundException e) {
322
        out.println(e.getMessage());
323
      } catch (SQLException se) {
324
        out.println(se.getMessage());
325
      }
326
    }
327 566 jones
*/
328 453 berkley
    else if (action.equals("insert") || action.equals("update")) {
329 458 berkley
      PrintWriter out = response.getWriter();
330 509 bojilova
      if ( (username != null) &&  !username.equals("public") ) {
331 425 bojilova
        handleInsertOrUpdateAction(out, params, response, username, groupname);
332
      } else {
333
        out.println("Permission denied for " + action);
334
      }
335 203 jones
    } else if (action.equals("delete")) {
336 458 berkley
      PrintWriter out = response.getWriter();
337 509 bojilova
      if ( (username != null) &&  !username.equals("public") ) {
338 425 bojilova
        handleDeleteAction(out, params, response, username, groupname);
339
      } else {
340
        out.println("Permission denied for " + action);
341
      }
342 68 higgins
    } else if (action.equals("validate")) {
343 458 berkley
      PrintWriter out = response.getWriter();
344 437 berkley
      handleValidateAction(out, params, response);
345
    } else if (action.equals("getabstract")) {
346 458 berkley
      PrintWriter out = response.getWriter();
347 437 berkley
      try{
348
        handleViewAbstractAction(out, params, response);
349
      }
350
      catch(Exception e)
351
      {
352 675 berkley
        out.println("error viewing abstract from " +
353
                    "MetacatServlet.handleGetorPost: " + e.getMessage());
354 437 berkley
      }
355 91 higgins
    } else if (action.equals("getdatadoc")) {
356 458 berkley
      response.setContentType("application/zip");
357
      ServletOutputStream out = response.getOutputStream();
358 91 higgins
      handleGetDataDocumentAction(out, params, response);
359 688 bojilova
    } else if (action.equals("getaccesscontrol")) {
360
      PrintWriter out = response.getWriter();
361
      handleGetAccessControlAction(out, params, response, username, groupname);
362 302 bojilova
    } else if (action.equals("getdoctypes")) {
363 458 berkley
      PrintWriter out = response.getWriter();
364 302 bojilova
      handleGetDoctypesAction(out, params, response);
365 648 berkley
    } else if (action.equals("getdataport")) {
366
      PrintWriter out = response.getWriter();
367 649 berkley
      if ( (username != null) &&  !username.equals("public") ) {
368 648 berkley
      handleGetDataPortAction(out, params, response, username, groupname,
369
                              sess_id);
370 649 berkley
      } else {
371
        out.println("You must be authenticated to perform the getdataport " +
372
                    "action!");
373
      }
374 699 bojilova
    } else if (action.equals("getdtdschema")) {
375
      PrintWriter out = response.getWriter();
376
      handleGetDTDSchemaAction(out, params, response);
377 302 bojilova
    } else if (action.equals("getdataguide")) {
378 458 berkley
      PrintWriter out = response.getWriter();
379 302 bojilova
      handleGetDataGuideAction(out, params, response);
380 509 bojilova
    } else if (action.equals("login") || action.equals("logout")) {
381 566 jones
    } else if (action.equals("protocoltest")) {
382
      String testURL = "metacat://dev.nceas.ucsb.edu/NCEAS.897766.9";
383
      try {
384
        testURL = ((String[])params.get("url"))[0];
385
      } catch (Throwable t) {
386
      }
387
      String phandler = System.getProperty("java.protocol.handler.pkgs");
388
      response.setContentType("text/html");
389
      PrintWriter out = response.getWriter();
390
      out.println("<body bgcolor=\"white\">");
391
      out.println("<p>Handler property: <code>" + phandler + "</code></p>");
392
      out.println("<p>Starting test for:<br>");
393
      out.println("    " + testURL + "</p>");
394
      try {
395
        URL u = new URL(testURL);
396
        out.println("<pre>");
397
        out.println("Protocol: " + u.getProtocol());
398
        out.println("    Host: " + u.getHost());
399
        out.println("    Port: " + u.getPort());
400
        out.println("    Path: " + u.getPath());
401
        out.println("     Ref: " + u.getRef());
402
        String pquery = u.getQuery();
403
        out.println("   Query: " + pquery);
404
        out.println("  Params: ");
405
        if (pquery != null) {
406
          Hashtable qparams = util.parseQuery(u.getQuery());
407
          for (Enumeration en = qparams.keys(); en.hasMoreElements(); ) {
408
            String pname = (String)en.nextElement();
409
            String pvalue = (String)qparams.get(pname);
410
            out.println("    " + pname + ": " + pvalue);
411
          }
412
        }
413
        out.println("</pre>");
414
        out.println("</body>");
415
        out.close();
416
      } catch (MalformedURLException mue) {
417 675 berkley
        System.out.println("bad url from MetacatServlet.handleGetOrPost");
418 566 jones
        out.println(mue.getMessage());
419
        mue.printStackTrace(out);
420
        out.close();
421
      }
422 50 jones
    } else {
423 458 berkley
      PrintWriter out = response.getWriter();
424 50 jones
      out.println("Error: action not registered.  Please report this error.");
425 46 jones
    }
426 465 berkley
    util.closeConnections();
427 49 jones
    // Close the stream to the client
428 458 berkley
    //out.close();
429 46 jones
  }
430 355 berkley
431
  /**
432
   * decodes the mouse click information coming from the client.
433
   * This function may be overwritten to provide specific functionality
434
   * for different applications.
435
   * @param params the parameters from the CGI
436
   * @return action the action to be performed or "error" if an error was
437
   * generated
438
   */
439 375 berkley
  protected String decodeMouseAction(Hashtable params)
440 355 berkley
  {
441
    // Determine what type of request the user made
442
    // if the action parameter is set, use it as a default
443
    // but if the ypos param is set, calculate the action needed
444
    String action=null;
445
    long ypos = 0;
446
    try {
447
      ypos = (new Long(((String[])params.get("ypos"))[0]).longValue());
448
      //out.println("<P>YPOS IS " + ypos);
449
      if (ypos <= 13) {
450 566 jones
        action = "read";
451 355 berkley
      } else if (ypos > 13 && ypos <= 27) {
452
        action = "validate";
453
      } else if (ypos > 27) {
454
        action = "transform";
455
      }
456
      return action;
457
    } catch (Exception npe) {
458 380 jones
      //
459
      // MBJ -- NOTE that this should be handled more gracefully with
460
      //        the new exception infrastructure -- this "error" return
461
      //        value is inappropriate
462 355 berkley
      //out.println("<P>Caught exception looking for Y value.");
463
      return "error";
464 382 berkley
    }
465 355 berkley
  }
466 648 berkley
467
  /**
468
   * sends the port number that the data socket is running on.  This is a
469
   * parameter set in the metacat.properties file.
470
   */
471
  private void handleGetDataPortAction(PrintWriter out, Hashtable params,
472
                                       HttpServletResponse response,
473
                                       String username, String groupname,
474
                                       String sess_id)
475
  {
476
    int port;
477
    String filedir = null;
478
    try
479
    {
480
      filedir = util.getOption("datafilepath");
481
482
      Random r = new Random();
483
      port = r.nextInt(65000);  //pick a random port between 0-65000
484
      //System.out.println("random port is: " + port);
485
      while(!DataFileServer.portIsAvailable(port))
486
      {
487
        port = r.nextInt(65000);
488
        //System.out.println("next port used: " + port);
489
      }
490
      DataFileServer dfs = new DataFileServer(port, username, sess_id);
491
      dfs.start();
492
493
      //System.out.println("filedir: " + filedir);
494
      //System.out.println("port: " + port);
495
      response.setContentType("text/xml");
496
      out.println("<?xml version=\"1.0\"?>");
497
      out.println("<port>");
498
      out.print(port);
499
      out.print("</port>");
500
501
    }
502
	  catch (Exception e)
503
    {
504 675 berkley
      System.out.println("error in MetacatServlet.handleGetDataPortAction: " +
505
                          e.getMessage());
506 648 berkley
    }
507
  }
508 49 jones
509 50 jones
  /**
510 509 bojilova
   * Handle the login request. Create a new session object.
511 503 bojilova
   * Do user authentication through the session.
512 210 bojilova
   */
513
  private void handleLoginAction(PrintWriter out, Hashtable params,
514
               HttpServletRequest request, HttpServletResponse response) {
515 251 bojilova
516 503 bojilova
    AuthSession sess = null;
517 228 bojilova
    String un = ((String[])params.get("username"))[0];
518
    String pw = ((String[])params.get("password"))[0];
519 297 bojilova
    String action = ((String[])params.get("action"))[0];
520 509 bojilova
    String qformat = ((String[])params.get("qformat"))[0];
521 332 bojilova
522 297 bojilova
    try {
523 509 bojilova
      sess = new AuthSession();
524 297 bojilova
    } catch (Exception e) {
525 675 berkley
      System.out.println("error in MetacatServlet.handleLoginAction: " +
526
                          e.getMessage());
527 297 bojilova
      out.println(e.getMessage());
528 509 bojilova
      return;
529 297 bojilova
    }
530 411 bojilova
531 509 bojilova
    boolean isValid = sess.authenticate(request, un, pw);
532
533
    // format and transform the output
534
    if (qformat.equals("html")) {
535
      Connection conn = null;
536 503 bojilova
      try {
537 509 bojilova
        conn = util.getConnection();
538
        DBTransform trans = new DBTransform(conn);
539
        response.setContentType("text/html");
540 510 bojilova
        trans.transformXMLDocument(sess.getMessage(), "-//NCEAS//login//EN",
541
                                   "-//W3C//HTML//EN", out);
542 509 bojilova
        util.returnConnection(conn);
543
      } catch(Exception e) {
544
        util.returnConnection(conn);
545
      }
546
547
    // any output is returned
548
    } else {
549
      response.setContentType("text/xml");
550
      out.println(sess.getMessage());
551 503 bojilova
    }
552 510 bojilova
553
/* WITHOUT XSLT transformation
554
    // redirects response to html page
555
    if (qformat.equals("html")) {
556
      // user authentication successful
557
      if (isValid) {
558
        response.sendRedirect(
559
                 response.encodeRedirectUrl(htmlpath + "/metacat.html"));
560
      // unsuccessful user authentication
561
      } else {
562
        response.sendRedirect(htmlpath + "/login.html");
563
      }
564
    // any output is returned
565
    } else {
566
      response.setContentType("text/xml");
567
      out.println(sess.getMessage());
568
    }
569
*/
570 509 bojilova
571 370 berkley
  }
572 509 bojilova
573
  /**
574
   * Handle the logout request. Close the connection.
575
   */
576
  private void handleLogoutAction(PrintWriter out, Hashtable params,
577
               HttpServletRequest request, HttpServletResponse response) {
578
579
    String qformat = ((String[])params.get("qformat"))[0];
580
581
    // close the connection
582
    HttpSession sess = request.getSession(false);
583
    if (sess != null) { sess.invalidate();  }
584
585
    // produce output
586
    StringBuffer output = new StringBuffer();
587
    output.append("<?xml version=\"1.0\"?>");
588 510 bojilova
    output.append("<logout>");
589
    output.append("User logged out");
590
    output.append("</logout>");
591 509 bojilova
592
    //format and transform the output
593
    if (qformat.equals("html")) {
594
      Connection conn = null;
595
      try {
596
        conn = util.getConnection();
597
        DBTransform trans = new DBTransform(conn);
598
        response.setContentType("text/html");
599 510 bojilova
        trans.transformXMLDocument(output.toString(), "-//NCEAS//login//EN",
600
                                   "-//W3C//HTML//EN", out);
601 509 bojilova
        util.returnConnection(conn);
602
      } catch(Exception e) {
603
        util.returnConnection(conn);
604
      }
605
    // any output is returned
606
    } else {
607
      response.setContentType("text/xml");
608
      out.println(output.toString());
609
    }
610
611 510 bojilova
/* WITHOUT XSLT transformation
612
    // redirects response to html page
613
    if (qformat.equals("html")) {
614
        response.sendRedirect(htmlpath + "/index.html");
615
      } catch(Exception e) {
616
        util.returnConnection(conn);
617
      }
618
    // any output is returned
619
    } else {
620
      response.setContentType("text/xml");
621
      out.println(output.toString());
622
    }
623
*/
624 509 bojilova
  }
625
626 370 berkley
627 373 berkley
  /**
628 380 jones
   * Retreive the squery xml, execute it and display it
629
   *
630
   * @param out the output stream to the client
631
   * @param params the Hashtable of parameters that should be included
632
   * in the squery.
633
   * @param response the response object linked to the client
634
   * @param conn the database connection
635
   */
636
  protected void handleSQuery(PrintWriter out, Hashtable params,
637 441 bojilova
                 HttpServletResponse response, String user, String group)
638 373 berkley
  {
639 380 jones
    String xmlquery = ((String[])params.get("query"))[0];
640
    String qformat = ((String[])params.get("qformat"))[0];
641 465 berkley
    String resultdoc = null;
642
    String[] returndoc = null;
643
    if(params.contains("returndoc"))
644
    {
645
      returndoc = (String[])params.get("returndoc");
646
    }
647
648
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
649
    //String resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
650 444 berkley
651 465 berkley
    resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
652
653 380 jones
    //format and transform the results
654
    if(qformat.equals("html")) {
655
      transformResultset(resultdoc, response, out);
656
    } else if(qformat.equals("xml")) {
657
      response.setContentType("text/xml");
658
      out.println(resultdoc);
659
    } else {
660
      out.println("invalid qformat: " + qformat);
661
    }
662 341 berkley
  }
663
664
   /**
665 380 jones
    * Create the xml query, execute it and display the results.
666
    *
667
    * @param out the output stream to the client
668
    * @param params the Hashtable of parameters that should be included
669 370 berkley
    * in the squery.
670 380 jones
    * @param response the response object linked to the client
671 370 berkley
    */
672 375 berkley
  protected void handleQuery(PrintWriter out, Hashtable params,
673 441 bojilova
                 HttpServletResponse response, String user, String group)
674 341 berkley
  {
675 370 berkley
    //create the query and run it
676 465 berkley
    String[] returndoc = null;
677
    if(params.containsKey("returndoc"))
678
    {
679
      returndoc = (String[])params.get("returndoc");
680
    }
681 373 berkley
    String xmlquery = DBQuery.createSQuery(params);
682 465 berkley
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
683
    String qformat = ((String[])params.get("qformat"))[0];
684
    String resultdoc = null;
685
686
    resultdoc = createResultDocument(doclist, transformQuery(params));
687 425 bojilova
688 370 berkley
    //format and transform the results
689 380 jones
    if(qformat.equals("html")) {
690 370 berkley
      transformResultset(resultdoc, response, out);
691 380 jones
    } else if(qformat.equals("xml")) {
692 370 berkley
      response.setContentType("text/xml");
693
      out.println(resultdoc);
694 443 berkley
    } else {
695 370 berkley
      out.println("invalid qformat: " + qformat);
696
    }
697 341 berkley
  }
698
699
  /**
700 384 berkley
   * Removes the <?xml version="x"?> tag from the beginning of xmlquery
701
   * so it can properly be placed in the <query> tag of the resultset.
702
   * This method is overwritable so that other applications can customize
703
   * the structure of what is in the <query> tag.
704
   *
705
   * @param xmlquery is the query to remove the <?xml version="x"?> tag from.
706
   */
707
  protected String transformQuery(Hashtable params)
708
  {
709
    //DBQuery.createSQuery is a re-calling of a previously called
710
    //function but it is necessary
711
    //so that overriding methods have access to the params hashtable
712
    String xmlquery = DBQuery.createSQuery(params);
713
    //the <?xml version="1.0"?> tag is the first 22 characters of the
714
    xmlquery = xmlquery.trim();
715
    int index = xmlquery.indexOf("?>");
716
    return xmlquery.substring(index + 2, xmlquery.length());
717
  }
718
719
  /**
720 443 berkley
   * removes the <?xml version="1.0"?> tag from the beginning.  This takes a
721
   * string as a param instead of a hashtable.
722
   *
723
   * @param xmlquery a string representing a query.
724
   */
725
  protected String transformQuery(String xmlquery)
726
  {
727
    xmlquery = xmlquery.trim();
728
    int index = xmlquery.indexOf("?>");
729
    return xmlquery.substring(index + 2, xmlquery.length());
730
  }
731
732
  /**
733 380 jones
   * Run the query and return a hashtable of results.
734
   *
735
   * @param xmlquery the query to run
736
   */
737 465 berkley
  private Hashtable runQuery(String xmlquery, String user, String group,
738
                             String[] returndoc)
739 341 berkley
  {
740
    Hashtable doclist=null;
741
    Connection conn = null;
742
    try
743
    {
744 441 bojilova
      conn = util.getConnection();
745
      DBQuery queryobj = new DBQuery(conn, saxparser);
746 465 berkley
      doclist = queryobj.findDocuments(new StringReader(xmlquery),user,group,
747
                                       returndoc);
748 441 bojilova
      util.returnConnection(conn);
749
      return doclist;
750 341 berkley
    }
751
    catch (Exception e)
752
    {
753 441 bojilova
      util.returnConnection(conn);
754 675 berkley
      util.debugMessage("Error in MetacatServlet.runQuery: " + e.getMessage());
755 341 berkley
      doclist = null;
756
      return doclist;
757
    }
758
  }
759
760 380 jones
  /**
761 370 berkley
   * Transorms an xml resultset document to html and sends it to the browser
762 380 jones
   *
763 370 berkley
   * @param resultdoc the string representation of the document that needs
764
   * to be transformed.
765
   * @param response the HttpServletResponse object bound to the client.
766
   * @param out the output stream to the client
767 375 berkley
   */
768
  protected void transformResultset(String resultdoc,
769 380 jones
                                    HttpServletResponse response,
770
                                    PrintWriter out)
771 370 berkley
  {
772
    Connection conn = null;
773 380 jones
    try {
774 370 berkley
      conn = util.getConnection();
775
      DBTransform trans = new DBTransform(conn);
776
      response.setContentType("text/html");
777
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN",
778
                                 "-//W3C//HTML//EN", out);
779 382 berkley
      util.returnConnection(conn);
780
    }
781
    catch(Exception e)
782
    {
783 441 bojilova
      util.returnConnection(conn);
784 370 berkley
    }
785
  }
786
787 355 berkley
  /**
788
   * Transforms a hashtable of documents to an xml or html result.
789 465 berkley
   * If there is a returndoc, then it only displays documents of
790
   * whatever type returndoc represents.  If a result is found in a document
791
   * that is not of type returndoc then this attempts to find a relation
792
   * between this document and one that satifies the returndoc doctype.
793 380 jones
   *
794 355 berkley
   * @param doclist- the hashtable to transform
795
   * @param xmlquery- the query that returned the dolist result
796 465 berkley
   * @param resultdoc- the document type to backtrack to.
797 355 berkley
   */
798 375 berkley
  protected String createResultDocument(Hashtable doclist, String xmlquery)
799 341 berkley
  {
800
    // Create a buffer to hold the xml result
801
    StringBuffer resultset = new StringBuffer();
802
803 382 berkley
    // Print the resulting root nodes
804 341 berkley
    String docid = null;
805
    String document = null;
806
    resultset.append("<?xml version=\"1.0\"?>\n");
807
    resultset.append("<resultset>\n");
808 465 berkley
809 384 berkley
    resultset.append("  <query>" + xmlquery + "</query>");
810 478 berkley
811
    if(doclist != null)
812 341 berkley
    {
813 478 berkley
      Enumeration doclistkeys = doclist.keys();
814
      while (doclistkeys.hasMoreElements())
815
      {
816
        docid = (String)doclistkeys.nextElement();
817
        document = (String)doclist.get(docid);
818
        resultset.append("  <document>" + document + "</document>");
819
      }
820
    }
821
822 341 berkley
    resultset.append("</resultset>");
823 444 berkley
    //System.out.println(resultset.toString());
824 370 berkley
    return resultset.toString();
825 341 berkley
  }
826 437 berkley
827
  /**
828
   * Handle the request to view the abstract of a document.
829 444 berkley
   * The abstractpath CGI parameter gives the xml path to the abstract
830
   * node.
831 437 berkley
   */
832
  private void handleViewAbstractAction(PrintWriter out, Hashtable params,
833
               HttpServletResponse response) throws IOException, SQLException
834
  {
835
    String abstractpath = null;
836
    String docid = null;
837
    Connection conn = null;
838
    response.setContentType("text/html");
839
    try
840
    {
841
      docid = ((String[])params.get("docid"))[0];
842
      if(params.containsKey("abstractpath"))
843
      {
844 444 berkley
        //the CGI parameter abstractpath holds the path to the abstract
845
        //that should be displayed.
846 437 berkley
        abstractpath = ((String[])params.get("abstractpath"))[0];
847
      }
848
      else
849
      {
850
        out.println("error: no abstractpath parameter");
851
      }
852
      conn = util.getConnection();
853
854
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid, conn);
855
856 444 berkley
      out.println("<html><head><title>Abstract</title></head>");
857
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
858 437 berkley
      for(int i=0; i<abstracts.length; i++)
859
      {
860
        out.println("<p>" + (String)abstracts[i] + "</p>");
861
      }
862
      out.println("</body></html>");
863
    }
864
    catch (IOException ioe)
865
    {
866 675 berkley
       util.debugMessage("error in MetacatServlet.handlegetabstract: " +
867
                          ioe.getMessage());
868
       System.out.println("IO error in MetacatServlet.handlegetabstract: " +
869
                          ioe.getMessage());
870 437 berkley
    }
871
    catch(SQLException sqle)
872
    {
873 675 berkley
      util.debugMessage("sql error in MetacatServLet.handlegetabstract: " +
874
                         sqle.getMessage());
875
      System.out.println("sql error in MetacatServLet.handlegetabstract: " +
876
                         sqle.getMessage());
877 437 berkley
    }
878
    catch(Exception e)
879
    {
880 444 berkley
      util.debugMessage("error in handlegetabstract: " + e.getMessage());
881 675 berkley
      System.out.println("error in MetacatServlEt.handlegetabstract: " +
882
                         e.getMessage());
883 437 berkley
    }
884
885
    util.returnConnection(conn);
886
  }
887 181 jones
888 50 jones
  /**
889 453 berkley
   * Handle the database getrelateddocument request and return a XML document,
890
   * possibly transformed from XML into HTML
891
   */
892 566 jones
  private void handleGetRelatedDocumentAction(PrintWriter out, Hashtable params,
893
               HttpServletResponse response, URL murl)
894 453 berkley
               throws ClassNotFoundException, IOException, SQLException
895
  {
896
    String docid = null;
897
    Connection conn = null;
898
899 566 jones
    //if(params.containsKey("url"))
900
    //{//the identifier for the related document is contained in the URL param
901 453 berkley
      try
902
      {
903
        DocumentImpl xmldoc=null;
904 566 jones
        //MetacatURL murl = new MetacatURL(((String[])params.get("url"))[0]);
905
        if(murl.getProtocol().equals("metacat"))
906 453 berkley
        {//get the document from the database if it is the right type of url
907 566 jones
          //Hashtable murlParams = murl.getHashParams();
908
          Hashtable murlParams = util.parseQuery(murl.getQuery());
909 473 berkley
          if(murlParams.containsKey("docid"))
910 453 berkley
          {//the docid should be first
911 473 berkley
            docid = (String)murlParams.get("docid"); //get the docid value
912 453 berkley
            conn = util.getConnection();
913
            xmldoc = new DocumentImpl(conn, docid);
914 485 berkley
            String qformat = ((String[])params.get("qformat"))[0];
915
            if (qformat.equals("xml"))
916
            {
917
              // set content type and other response header fields first
918
              response.setContentType("text/xml");
919
              xmldoc.toXml(out);
920
              //out.println(xmldoc);
921
            }
922
            else if (qformat.equals("html"))
923
            {
924
              response.setContentType("text/html");
925
              // Look up the document type
926
              String sourcetype = xmldoc.getDoctype();
927
              // Transform the document to the new doctype
928
              DBTransform dbt = new DBTransform(conn);
929
              dbt.transformXMLDocument(xmldoc.toString(), sourcetype,
930
                                 "-//W3C//HTML//EN", out);
931
            }
932
933 473 berkley
            util.returnConnection(conn);
934 453 berkley
          }
935
          else
936
          {
937
            //throw new Exception("handleGetDocument: bad URL");
938
            System.err.println("handleGetDocument: bad URL");
939
          }
940
        }
941 566 jones
        else if(murl.getProtocol().equals("http"))
942 453 berkley
        {//get the document from the internet
943 566 jones
          //Hashtable murlParams = murl.getHashParams();
944
          Hashtable murlParams = util.parseQuery(murl.getQuery());
945 473 berkley
          if(murlParams.containsKey("httpurl"))
946 453 berkley
          {//httpurl is the param name for an http url.
947 473 berkley
            URL urlconn = new URL((String)murlParams.get("httpurl"));
948
            //create a new url obj.
949 458 berkley
            //DataInputStream htmldoc = new DataInputStream(urlconn.openStream());
950
            BufferedReader htmldoc = new BufferedReader(
951
                                   new InputStreamReader(urlconn.openStream()));
952 453 berkley
            //bind a data stream.
953
            try
954
            { //display the document
955
              String line=null;
956
              while((line = htmldoc.readLine()) != null)
957
              {
958
                out.println(line);
959
              }
960
            }
961
            catch(Exception e)
962
            {
963 675 berkley
              System.out.println("error viewing html document from " +
964
                            "MetacatServlet.handleGetRelatedDocumentAction: " +
965
                            e.getMessage());
966 453 berkley
            }
967
          }
968
        }
969
      }
970
      catch (McdbException e) {
971
        response.setContentType("text/xml");
972
        e.toXml(out);
973
      } catch   (Throwable t) {
974
        response.setContentType("text/html");
975
        out.println(t.getMessage());
976
      } finally {
977
        util.returnConnection(conn);
978
      }
979 566 jones
    //} // end if
980 453 berkley
  }
981
982
  /**
983 566 jones
   * Handle the database read request and return an XML document,
984 50 jones
   * possibly transformed from XML into HTML
985
   */
986 636 berkley
  private void handleReadAction(/*PrintWriter out,*/ Hashtable params,
987 661 berkley
               HttpServletResponse response, String username)
988 566 jones
               throws ClassNotFoundException, IOException, SQLException
989
  {
990 636 berkley
     PrintWriter out;
991 566 jones
    try {
992
      //MetacatURL murl = new MetacatURL(((String[])params.get("docid"))[0]);
993 636 berkley
      if(params.containsKey(new String("qformat")) &&
994
         ((String[])params.get("qformat"))[0].equals("bin"))
995
      {
996 661 berkley
        handleGetData(params, response, username);
997 636 berkley
      }
998
      else
999
      {
1000
        out = response.getWriter();
1001
        URL murl = new URL(((String[])params.get("docid"))[0]);
1002
        handleGetRelatedDocumentAction(out, params, response, murl);
1003
      }
1004 566 jones
    } catch (MalformedURLException mue) {
1005 636 berkley
      out = response.getWriter();
1006 566 jones
      handleGetDocumentAction(out, params, response);
1007
    }
1008
  }
1009 636 berkley
1010
  /**
1011
   * Handle the read of a data file.
1012
   */
1013
  private void handleGetData(Hashtable params,
1014 661 berkley
                             HttpServletResponse response, String username)
1015 636 berkley
  {
1016
    String docid = null;
1017
    try
1018
    {
1019
      URL murl = new URL(((String[])params.get("docid"))[0]);
1020
      Hashtable murlParams = util.parseQuery(murl.getQuery());
1021
      if(murlParams.containsKey("docid"))
1022
      {
1023 641 berkley
        docid = (String)murlParams.get("docid");
1024 636 berkley
      }
1025
    }
1026
    catch(MalformedURLException mue)
1027
    {
1028
      docid = ((String[])params.get("docid"))[0];
1029
    }
1030
1031
    File f = null;
1032
    FileInputStream fin = null;
1033
    Connection conn;
1034
1035
    try
1036
    {
1037
      StringBuffer sql = new StringBuffer();
1038
      sql.append("select docname from xml_documents where docid like '");
1039
      sql.append(docid).append("'");
1040
      conn = util.openDBConnection();
1041 661 berkley
1042
      AccessControlList aclobj = new AccessControlList(conn);
1043
      boolean hasPermission = aclobj.hasPermission("READ",username,docid);
1044
1045
      if(!hasPermission)
1046
      {
1047
        response.setContentType("text/html");
1048
        PrintWriter out = response.getWriter();
1049
        out.println("Error: you do not have permission to view this document");
1050
        return;
1051
      }
1052
      response.setContentType("application/octet-stream");
1053
      ServletOutputStream sosout = response.getOutputStream();
1054 636 berkley
      PreparedStatement pstmt = conn.prepareStatement(sql.toString());
1055
      pstmt.execute();
1056
      ResultSet rs = pstmt.getResultSet();
1057
      boolean tablehasrows = rs.next();
1058
      while(tablehasrows)
1059
      {
1060
        //get the file stream from the file then send it to the output stream
1061
        String filepath = util.getOption("datafilepath");
1062
        if(!filepath.endsWith("/"))
1063
        {
1064
          filepath += "/";
1065
        }
1066
        f = new File(filepath + rs.getString(1));
1067
        fin = new FileInputStream(f);
1068 661 berkley
1069 636 berkley
        int b = fin.read();
1070
        while(b != -1)
1071
        {
1072
          sosout.write(b);
1073
          b = fin.read();
1074
        }
1075
        tablehasrows = rs.next();
1076
      }
1077
1078
      fin.close();
1079 667 berkley
      pstmt.close();
1080 636 berkley
      conn.close();
1081
    }
1082
    catch(Exception e)
1083
    {
1084 675 berkley
      System.out.println("error in MetacatServlet.handleGetData: " +
1085
                          e.getMessage());
1086 636 berkley
      e.printStackTrace(System.out);
1087
    }
1088
  }
1089 566 jones
1090
  /**
1091
   * Handle the database read request and return an XML document,
1092
   * possibly transformed from XML into HTML
1093
   */
1094 382 berkley
  private void handleGetDocumentAction(PrintWriter out, Hashtable params,
1095 87 jones
               HttpServletResponse response)
1096
               throws ClassNotFoundException, IOException, SQLException {
1097 102 jones
    String docidstr = null;
1098 162 bojilova
    String docid = null;
1099 102 jones
    String doc = null;
1100 309 bojilova
    Connection conn = null;
1101
1102 102 jones
    try {
1103 87 jones
      // Find the document id number
1104 102 jones
      docidstr = ((String[])params.get("docid"))[0];
1105 162 bojilova
      docid = docidstr;
1106 625 berkley
1107 309 bojilova
      conn = util.getConnection();
1108 393 jones
      DocumentImpl xmldoc = new DocumentImpl(conn, docid);
1109
      // Get the document indicated from the db
1110
      //doc = docreader.readXMLDocument(docid);
1111 85 jones
1112 87 jones
      // Return the document in XML or HTML format
1113 437 berkley
      String qformat=null;
1114
      if(params.containsKey("qformat"))
1115
      {
1116
        qformat = ((String[])params.get("qformat"))[0];
1117
      }
1118
      else
1119
      {
1120
        qformat = "html";
1121
      }
1122
      if (qformat.equals("xml")) {
1123 85 jones
        // set content type and other response header fields first
1124
        response.setContentType("text/xml");
1125 431 jones
        xmldoc.toXml(out);
1126
        //out.println(xmldoc);
1127 85 jones
      } else if (qformat.equals("html")) {
1128 437 berkley
        response.setContentType("text/html");
1129 87 jones
        // Look up the document type
1130 393 jones
        String sourcetype = xmldoc.getDoctype();
1131 87 jones
        // Transform the document to the new doctype
1132 393 jones
        DBTransform dbt = new DBTransform(conn);
1133
        dbt.transformXMLDocument(xmldoc.toString(), sourcetype,
1134
                                 "-//W3C//HTML//EN", out);
1135 85 jones
      }
1136 343 jones
    } catch (McdbException e) {
1137
      response.setContentType("text/xml");
1138
      e.toXml(out);
1139
    } catch (Throwable t) {
1140 309 bojilova
      response.setContentType("text/html");
1141 343 jones
      out.println(t.getMessage());
1142 309 bojilova
    } finally {
1143 320 bojilova
      util.returnConnection(conn);
1144 309 bojilova
    }
1145
1146 49 jones
  }
1147 55 jones
1148
  /**
1149
   * Handle the database putdocument request and write an XML document
1150
   * to the database connection
1151
   */
1152 382 berkley
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params,
1153 425 bojilova
               HttpServletResponse response, String user, String group) {
1154 59 jones
1155 309 bojilova
    Connection conn = null;
1156
1157 204 jones
    try {
1158
      // Get the document indicated
1159
      String[] doctext = (String[])params.get("doctext");
1160 557 bojilova
1161 680 bojilova
      String pub = null;
1162
      if (params.containsKey("public")) {
1163
        pub = ((String[])params.get("public"))[0];
1164 557 bojilova
      }
1165 680 bojilova
1166 598 bojilova
      StringReader dtd = null;
1167 680 bojilova
      if (params.containsKey("dtdtext")) {
1168 598 bojilova
        String[] dtdtext = (String[])params.get("dtdtext");
1169
        try {
1170 619 bojilova
          if ( !dtdtext[0].equals("") ) {
1171
            dtd = new StringReader(dtdtext[0]);
1172
          }
1173 598 bojilova
        } catch (NullPointerException npe) {}
1174
      }
1175 557 bojilova
1176 204 jones
      StringReader xml = null;
1177 695 bojilova
      boolean validate = false;
1178 204 jones
      try {
1179 695 bojilova
        // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ... >
1180
        // in order to decide whether to use validation parser
1181
        validate = validateXML(doctext[0]);
1182 204 jones
        xml = new StringReader(doctext[0]);
1183 59 jones
1184 204 jones
        String[] action = (String[])params.get("action");
1185
        String[] docid = (String[])params.get("docid");
1186
        String newdocid = null;
1187 203 jones
1188 204 jones
        String doAction = null;
1189
        if (action[0].equals("insert")) {
1190
          doAction = "INSERT";
1191
        } else if (action[0].equals("update")) {
1192
          doAction = "UPDATE";
1193
        }
1194 203 jones
1195 204 jones
        try {
1196 680 bojilova
          // get a connection from the pool
1197
          conn = util.getConnection();
1198 408 jones
1199 680 bojilova
          // write the document to the database
1200
          try {
1201
            String accNumber = docid[0];
1202
            if (accNumber.equals("")) {
1203
              accNumber = null;
1204 309 bojilova
            }
1205 680 bojilova
            newdocid = DocumentImpl.write(conn, xml, pub, dtd, doAction,
1206 695 bojilova
                                          accNumber, user, group, validate);
1207 680 bojilova
          } catch (NullPointerException npe) {
1208
            newdocid = DocumentImpl.write(conn, xml, pub, dtd, doAction,
1209 695 bojilova
                                          null, user, group, validate);
1210 680 bojilova
          }
1211 309 bojilova
        } finally {
1212 320 bojilova
          util.returnConnection(conn);
1213 309 bojilova
        }
1214
1215 204 jones
        // set content type and other response header fields first
1216
        response.setContentType("text/xml");
1217
        out.println("<?xml version=\"1.0\"?>");
1218
        out.println("<success>");
1219
        out.println("<docid>" + newdocid + "</docid>");
1220
        out.println("</success>");
1221
1222 203 jones
      } catch (NullPointerException npe) {
1223 204 jones
        response.setContentType("text/xml");
1224
        out.println("<?xml version=\"1.0\"?>");
1225
        out.println("<error>");
1226
        out.println(npe.getMessage());
1227
        out.println("</error>");
1228 55 jones
      }
1229 204 jones
    } catch (Exception e) {
1230
      response.setContentType("text/xml");
1231
      out.println("<?xml version=\"1.0\"?>");
1232
      out.println("<error>");
1233
      out.println(e.getMessage());
1234
      if (e instanceof SAXException) {
1235
        Exception e2 = ((SAXException)e).getException();
1236
        out.println("<error>");
1237
        out.println(e2.getMessage());
1238
        out.println("</error>");
1239
      }
1240
      //e.printStackTrace(out);
1241
      out.println("</error>");
1242 203 jones
    }
1243 55 jones
  }
1244 203 jones
1245
  /**
1246 695 bojilova
   * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... >
1247
   * in order to decide whether to use validation parser
1248
   */
1249
  private static boolean validateXML(String xmltext) throws IOException {
1250
1251
    StringReader xmlreader = new StringReader(xmltext);
1252
    StringBuffer cbuff = new StringBuffer();
1253
    java.util.Stack st = new java.util.Stack();
1254
    boolean validate = false;
1255
    int c;
1256
    int inx;
1257
1258
    // read from the stream until find the keywords
1259
    while ( (st.empty() || st.size()<4) && ((c = xmlreader.read()) != -1) ) {
1260
      cbuff.append((char)c);
1261
1262
      // "<!DOCTYPE" keyword is found; put it in the stack
1263
      if ( (inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1 ) {
1264
        cbuff = new StringBuffer();
1265
        st.push("<!DOCTYPE");
1266
      }
1267
      // "PUBLIC" keyword is found; put it in the stack
1268
      if ( (inx = cbuff.toString().indexOf("PUBLIC")) != -1 ) {
1269
        cbuff = new StringBuffer();
1270
        st.push("PUBLIC");
1271
      }
1272
      // "SYSTEM" keyword is found; put it in the stack
1273
      if ( (inx = cbuff.toString().indexOf("SYSTEM")) != -1 ) {
1274
        cbuff = new StringBuffer();
1275
        st.push("SYSTEM");
1276
      }
1277
      // ">" character is found; put it in the stack
1278
      // ">" is found twice: fisrt from <?xml ...?>
1279
      // and second from <!DOCTYPE ... >
1280
      if ( (inx = cbuff.toString().indexOf(">")) != -1 ) {
1281
        cbuff = new StringBuffer();
1282
        st.push(">");
1283
      }
1284
    }
1285
1286
    // close the stream
1287
    xmlreader.close();
1288
1289
    // check the stack whether it contains the keywords:
1290
    // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1291
    if ( st.size() == 4 ) {
1292
      if ( ((String)st.pop()).equals(">") &&
1293
           ( ((String)st.peek()).equals("PUBLIC") |
1294
             ((String)st.pop()).equals("SYSTEM") ) &&
1295
           ((String)st.pop()).equals("<!DOCTYPE") )  {
1296
        validate = true;
1297
      }
1298
    }
1299
1300
System.out.println("Validation is " + validate);
1301
    return validate;
1302
  }
1303
1304
  /**
1305 203 jones
   * Handle the database delete request and delete an XML document
1306
   * from the database connection
1307
   */
1308
  private void handleDeleteAction(PrintWriter out, Hashtable params,
1309 425 bojilova
               HttpServletResponse response, String user, String group) {
1310 203 jones
1311
    String[] docid = (String[])params.get("docid");
1312 309 bojilova
    Connection conn = null;
1313 203 jones
1314
    // delete the document from the database
1315
    try {
1316 309 bojilova
      // get a connection from the pool
1317
      conn = util.getConnection();
1318 203 jones
                                      // NOTE -- NEED TO TEST HERE
1319 408 jones
                                      // FOR EXISTENCE OF DOCID PARAM
1320 203 jones
                                      // BEFORE ACCESSING ARRAY
1321 375 berkley
      try {
1322 425 bojilova
        DocumentImpl.delete(conn, docid[0], user, group);
1323 204 jones
        response.setContentType("text/xml");
1324
        out.println("<?xml version=\"1.0\"?>");
1325
        out.println("<success>");
1326 203 jones
        out.println("Document deleted.");
1327 204 jones
        out.println("</success>");
1328 203 jones
      } catch (AccessionNumberException ane) {
1329 204 jones
        response.setContentType("text/xml");
1330
        out.println("<?xml version=\"1.0\"?>");
1331
        out.println("<error>");
1332
        out.println("Error deleting document!!!");
1333 203 jones
        out.println(ane.getMessage());
1334 204 jones
        out.println("</error>");
1335 203 jones
      }
1336 204 jones
    } catch (Exception e) {
1337
      response.setContentType("text/xml");
1338
      out.println("<?xml version=\"1.0\"?>");
1339
      out.println("<error>");
1340
      out.println(e.getMessage());
1341
      out.println("</error>");
1342 309 bojilova
    } finally {
1343 320 bojilova
      util.returnConnection(conn);
1344 309 bojilova
    }
1345 203 jones
  }
1346 68 higgins
1347
  /**
1348 380 jones
   * Handle the validation request and return the results to the requestor
1349 68 higgins
   */
1350 185 jones
  private void handleValidateAction(PrintWriter out, Hashtable params,
1351
               HttpServletResponse response) {
1352 68 higgins
1353 103 jones
    // Get the document indicated
1354
    String valtext = null;
1355 309 bojilova
1356 103 jones
    try {
1357
      valtext = ((String[])params.get("valtext"))[0];
1358
    } catch (Exception nullpe) {
1359 68 higgins
1360 309 bojilova
      Connection conn = null;
1361 162 bojilova
      String docid = null;
1362 103 jones
      try {
1363
        // Find the document id number
1364 185 jones
        docid = ((String[])params.get("docid"))[0];
1365 309 bojilova
1366
        // get a connection from the pool
1367
        conn = util.getConnection();
1368 393 jones
1369 309 bojilova
        // Get the document indicated from the db
1370 393 jones
        DocumentImpl xmldoc = new DocumentImpl(conn, docid);
1371
        valtext = xmldoc.toString();
1372 185 jones
1373 103 jones
      } catch (NullPointerException npe) {
1374 253 jones
        response.setContentType("text/xml");
1375
        out.println("<error>Error getting document ID: " + docid + "</error>");
1376 320 bojilova
        if ( conn != null ) { util.returnConnection(conn); }
1377 380 jones
        return;
1378 309 bojilova
      } catch (Exception e) {
1379
        response.setContentType("text/html");
1380
        out.println(e.getMessage());
1381
      } finally {
1382 320 bojilova
        util.returnConnection(conn);
1383 309 bojilova
      }
1384 103 jones
    }
1385 68 higgins
1386 309 bojilova
    Connection conn = null;
1387 103 jones
    try {
1388 309 bojilova
      // get a connection from the pool
1389
      conn = util.getConnection();
1390 253 jones
      DBValidate valobj = new DBValidate(saxparser,conn);
1391 185 jones
      boolean valid = valobj.validateString(valtext);
1392 68 higgins
1393
      // set content type and other response header fields first
1394 253 jones
      response.setContentType("text/xml");
1395
      out.println(valobj.returnErrors());
1396
1397 103 jones
    } catch (NullPointerException npe2) {
1398
      // set content type and other response header fields first
1399 253 jones
      response.setContentType("text/xml");
1400
      out.println("<error>Error validating document.</error>");
1401 309 bojilova
    } catch (Exception e) {
1402
      response.setContentType("text/html");
1403
      out.println(e.getMessage());
1404
    } finally {
1405 320 bojilova
      util.returnConnection(conn);
1406 309 bojilova
    }
1407 103 jones
  }
1408 87 jones
1409
  /**
1410 380 jones
   * Handle the document request and return the results to the requestor
1411 458 berkley
   * If a docid is passed in through the params then that document
1412
   * will be retrieved form the DB and put in the zip file.
1413
   * In addition if 1 or more relations parameters are passed, those file
1414
   * will be zipped as well.  Currently this is only implemented for
1415
   * metacat:// and http:// files.  Support should be added for srb:// files
1416
   * as well.
1417 91 higgins
   */
1418 458 berkley
  private void handleGetDataDocumentAction(ServletOutputStream out,
1419
               Hashtable params,
1420 185 jones
               HttpServletResponse response) {
1421 458 berkley
  //find the related files, get them from their source and zip them into
1422
  //a zip file.
1423
  try
1424
  {
1425
    Connection conn = util.getConnection();
1426
    String currentDocid = ((String[])params.get("docid"))[0];
1427
    ZipOutputStream zout = new ZipOutputStream(out);
1428
    byte[] bytestring = null;
1429
    ZipEntry zentry = null;
1430
    DocumentImpl xmldoc = null;
1431
    String[] reldocs = null;
1432
1433
    if(params.containsKey("relation"))
1434
    { //get the relations from the parameters.
1435
      reldocs = ((String[])params.get("relation"));
1436
    }
1437
    else
1438
    { //let the for loop know that there are no relations to zip
1439
      reldocs = new String[0];
1440
    }
1441
1442
    //write the base file to the zip file.
1443
    xmldoc = new DocumentImpl(conn, currentDocid);
1444
    bytestring = (xmldoc.toString()).getBytes();
1445
    zentry = new ZipEntry(currentDocid + ".xml");
1446
    //create a new zip entry and write the file to the stream
1447
    zentry.setSize(bytestring.length);
1448
    zout.putNextEntry(zentry);
1449
    zout.write(bytestring, 0, bytestring.length);
1450
    zout.closeEntry(); //get ready for the next entry.
1451
1452
    //zip up the related documents
1453
    for(int i=0; i<reldocs.length; i++)
1454
    {
1455 566 jones
      //MetacatURL murl = new MetacatURL(((String)reldocs[i]));
1456
      URL murl = new URL(((String)reldocs[i]));
1457
      Hashtable qparams = util.parseQuery(murl.getQuery());
1458
      if(murl.getProtocol().equals("metacat"))
1459 458 berkley
      {
1460
        //get the document from the database
1461 566 jones
        //xmldoc = new DocumentImpl(conn, (String)murl.getHashParam("docid"));
1462
        xmldoc = new DocumentImpl(conn, (String)qparams.get("docid"));
1463 458 berkley
        bytestring = (xmldoc.toString()).getBytes();
1464 566 jones
        zentry = new ZipEntry(qparams.get("docid") + ".xml");
1465 458 berkley
        //create a new zip entry and write the file to the stream
1466
        zentry.setSize(bytestring.length);
1467
        zout.putNextEntry(zentry);
1468
        zout.write(bytestring, 0, bytestring.length);
1469
        zout.closeEntry(); //get ready for the next entry.
1470
      }
1471 566 jones
      else if(murl.getProtocol().equals("http"))
1472 458 berkley
      {
1473 566 jones
        //Hashtable murlParams = murl.getHashParams();
1474
        if(qparams.containsKey("httpurl"))
1475 458 berkley
        {//httpurl is the param name for an http url.
1476 566 jones
          URL urlconn = new URL((String)qparams.get("httpurl"));
1477 473 berkley
          //create a new url obj.
1478 458 berkley
          BufferedReader htmldoc = new BufferedReader(
1479
                                   new InputStreamReader(urlconn.openStream()));
1480
          //get the data from the web server
1481
          try
1482
          { //zip the document
1483
            String line=null;
1484 566 jones
            zentry = new ZipEntry((String)qparams.get("filename"));
1485 458 berkley
            //get just the filename from the URL.
1486
            zout.putNextEntry(zentry);
1487
            //make a new entry in the zip file stream
1488
            while((line = htmldoc.readLine()) != null)
1489
            {
1490
              bytestring = (line.toString()).getBytes();
1491
              zout.write(bytestring, 0, bytestring.length);
1492
              //write out the file line by line
1493
            }
1494
            zout.closeEntry(); //close the entry in the file
1495
          }
1496
          catch(Exception e)
1497
          {
1498 675 berkley
            System.out.println("error downloading html document "+
1499
                               "in metacatServlet.handleGetDataDocumentAction");
1500 458 berkley
          }
1501
        }
1502
      }
1503
    }
1504
    zout.finish();  //terminate the zip file
1505
    zout.close();   //close the stream.
1506
    util.returnConnection(conn); //return the connection to the pool
1507
  }
1508
  catch(Exception e)
1509
  {
1510 675 berkley
    System.out.println("Error creating zip file from " +
1511
                       "MetacatServlet.handleGetDataDocumentAction: " +
1512
                        e.getMessage());
1513 458 berkley
    e.printStackTrace(System.out);
1514
  }
1515
1516
   /*
1517
   //////////old code using a shell script/////////////////////////////////
1518
1519 91 higgins
      boolean error_flag = false;
1520
      String error_message = "";
1521
      // Get the document indicated
1522
      String[] datadoc = (String[])params.get("datadoc");
1523 185 jones
      // defaultdatapath = "C:\\Temp\\";    // for testing only!!!
1524
      // executescript = "test.bat";        // for testing only!!!
1525 91 higgins
1526
      // set content type and other response header fields first
1527
      response.setContentType("application/octet-stream");
1528 185 jones
      if (defaultdatapath!=null) {
1529
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) {
1530
          defaultdatapath=defaultdatapath+System.getProperty("file.separator");
1531 91 higgins
        }
1532 185 jones
        System.out.println("Path= "+defaultdatapath+datadoc[0]);
1533
        if (executescript!=null) {
1534
          String command = null;
1535
          File scriptfile = new File(executescript);
1536
          if (scriptfile.exists()) {
1537
            command=executescript+" "+datadoc[0]; // script includes path
1538
        } else {     // look in defaultdatapath
1539
            // on Win98 one MUST include the .bat extender
1540
            command = defaultdatapath+executescript+" "+datadoc[0];
1541
        }
1542 91 higgins
      System.out.println(command);
1543
      try {
1544
      Process proc = Runtime.getRuntime().exec(command);
1545
      proc.waitFor();
1546
      }
1547
      catch (Exception eee) {
1548
        System.out.println("Error running process!");
1549
        error_flag = true;
1550
        error_message = "Error running process!";}
1551
      } // end executescript not null if
1552
      File datafile = new File(defaultdatapath+datadoc[0]);
1553
      try {
1554
      FileInputStream fw = new FileInputStream(datafile);
1555
      int x;
1556 185 jones
      while ((x = fw.read())!=-1) {
1557 91 higgins
        out.write(x); }
1558 185 jones
        fw.close();
1559
      } catch (Exception e) {
1560 91 higgins
        System.out.println("Error in returning file\n"+e.getMessage());
1561
        error_flag=true;
1562 185 jones
        error_message = error_message+"\nError in returning file\n"+
1563
                        e.getMessage();
1564
      }
1565
    } // end defaultdatapath not null if
1566 458 berkley
    */
1567 91 higgins
  }
1568 302 bojilova
1569
  /**
1570 688 bojilova
   * Handle "getaccesscontrol" action.
1571
   * Read Access Control List from db connection in XML format
1572
   */
1573
  private void handleGetAccessControlAction(PrintWriter out, Hashtable params,
1574
                                       HttpServletResponse response,
1575
                                       String username, String groupname) {
1576
1577
    Connection conn = null;
1578
    String docid = ((String[])params.get("docid"))[0];
1579
1580
    try {
1581
1582
        // get connection from the pool
1583
        conn = util.getConnection();
1584
        AccessControlList aclobj = new AccessControlList(conn);
1585
        String acltext = aclobj.getACL(docid, username, groupname);
1586
        out.println(acltext);
1587
1588
    } catch (Exception e) {
1589
      out.println("<?xml version=\"1.0\"?>");
1590
      out.println("<error>");
1591
      out.println(e.getMessage());
1592
      out.println("</error>");
1593
    } finally {
1594
      util.returnConnection(conn);
1595
    }
1596
1597
  }
1598
1599
  /**
1600
   * Handle "getdoctypes" action.
1601 302 bojilova
   * Read all doctypes from db connection in XML format
1602
   */
1603
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
1604
                                       HttpServletResponse response) {
1605
1606 309 bojilova
    Connection conn = null;
1607
1608 302 bojilova
    try {
1609
1610 309 bojilova
        // get connection from the pool
1611
        conn = util.getConnection();
1612
        DBUtil dbutil = new DBUtil(conn);
1613 302 bojilova
        String doctypes = dbutil.readDoctypes();
1614
        out.println(doctypes);
1615
1616
    } catch (Exception e) {
1617
      out.println("<?xml version=\"1.0\"?>");
1618
      out.println("<error>");
1619
      out.println(e.getMessage());
1620
      out.println("</error>");
1621 309 bojilova
    } finally {
1622 320 bojilova
      util.returnConnection(conn);
1623 309 bojilova
    }
1624 302 bojilova
1625
  }
1626
1627
  /**
1628 699 bojilova
   * Handle the "getdtdschema" action.
1629
   * Read DTD or Schema file for a given doctype from Metacat catalog system
1630
   */
1631
  private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
1632
                                        HttpServletResponse response) {
1633
1634
    Connection conn = null;
1635
    String doctype = null;
1636
    String[] doctypeArr = (String[])params.get("doctype");
1637
1638
    // get only the first doctype specified in the list of doctypes
1639
    // it could be done for all doctypes in that list
1640
    if (doctypeArr != null) {
1641
        doctype = ((String[])params.get("doctype"))[0];
1642
    }
1643
1644
    try {
1645
1646
        // get connection from the pool
1647
        conn = util.getConnection();
1648
        DBUtil dbutil = new DBUtil(conn);
1649
        String dtdschema = dbutil.readDTDSchema(doctype);
1650
        out.println(dtdschema);
1651
1652
    } catch (Exception e) {
1653
      out.println("<?xml version=\"1.0\"?>");
1654
      out.println("<error>");
1655
      out.println(e.getMessage());
1656
      out.println("</error>");
1657
    } finally {
1658
      util.returnConnection(conn);
1659
    }
1660
1661
  }
1662
1663
  /**
1664 688 bojilova
   * Handle the "getdataguide" action.
1665 302 bojilova
   * Read Data Guide for a given doctype from db connection in XML format
1666
   */
1667
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params,
1668
                                        HttpServletResponse response) {
1669
1670 309 bojilova
    Connection conn = null;
1671 316 bojilova
    String doctype = null;
1672
    String[] doctypeArr = (String[])params.get("doctype");
1673 309 bojilova
1674 316 bojilova
    // get only the first doctype specified in the list of doctypes
1675
    // it could be done for all doctypes in that list
1676
    if (doctypeArr != null) {
1677
        doctype = ((String[])params.get("doctype"))[0];
1678
    }
1679
1680 302 bojilova
    try {
1681
1682 309 bojilova
        // get connection from the pool
1683
        conn = util.getConnection();
1684
        DBUtil dbutil = new DBUtil(conn);
1685 316 bojilova
        String dataguide = dbutil.readDataGuide(doctype);
1686 302 bojilova
        out.println(dataguide);
1687
1688
    } catch (Exception e) {
1689
      out.println("<?xml version=\"1.0\"?>");
1690
      out.println("<error>");
1691
      out.println(e.getMessage());
1692
      out.println("</error>");
1693 309 bojilova
    } finally {
1694 320 bojilova
      util.returnConnection(conn);
1695 309 bojilova
    }
1696 302 bojilova
1697
  }
1698
1699 46 jones
}