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 51 jones
 */
13
14
package edu.ucsb.nceas.metacat;
15
16 46 jones
import java.io.PrintWriter;
17
import java.io.IOException;
18 50 jones
import java.io.Reader;
19
import java.io.StringReader;
20 59 jones
import java.io.BufferedReader;
21 185 jones
import java.io.File;
22
import java.io.FileInputStream;
23 458 berkley
import java.io.FileOutputStream;
24
import java.io.InputStreamReader;
25 453 berkley
import java.io.DataInputStream;
26 46 jones
import java.util.Enumeration;
27
import java.util.Hashtable;
28 341 berkley
import java.util.ResourceBundle;
29 82 jones
import java.util.PropertyResourceBundle;
30 50 jones
import java.net.URL;
31
import java.net.MalformedURLException;
32 85 jones
import java.sql.PreparedStatement;
33
import java.sql.ResultSet;
34 50 jones
import java.sql.Connection;
35 55 jones
import java.sql.SQLException;
36 361 berkley
import java.lang.reflect.*;
37 453 berkley
import java.net.*;
38 458 berkley
import java.util.zip.*;
39 46 jones
40
import javax.servlet.ServletConfig;
41
import javax.servlet.ServletContext;
42
import javax.servlet.ServletException;
43 48 jones
import javax.servlet.ServletInputStream;
44 46 jones
import javax.servlet.http.HttpServlet;
45
import javax.servlet.http.HttpServletRequest;
46
import javax.servlet.http.HttpServletResponse;
47 210 bojilova
import javax.servlet.http.HttpSession;
48 47 jones
import javax.servlet.http.HttpUtils;
49 458 berkley
import javax.servlet.ServletOutputStream;
50 46 jones
51 50 jones
import oracle.xml.parser.v2.XSLStylesheet;
52
import oracle.xml.parser.v2.XSLException;
53
import oracle.xml.parser.v2.XMLDocumentFragment;
54
import oracle.xml.parser.v2.XSLProcessor;
55
56 204 jones
import org.xml.sax.SAXException;
57
58 46 jones
/**
59
 * A metadata catalog server implemented as a Java Servlet
60 154 jones
 *
61
 * <p>Valid parameters are:<br>
62
 * action=query -- query the values of all elements and attributes
63
 *                     and return a result set of nodes<br>
64 205 jones
 * action=squery -- structured query (see pathquery.dtd)<br>
65
 * action=insert -- insert an XML document into the database store<br>
66
 * action=update -- update an XML document that is in the database store<br>
67
 * action=delete --  delete an XML document from the database store<br>
68
 * action=validate -- vallidate the xml contained in valtext<br>
69
 * action=getdocument -- display an XML document in XML or HTML<br>
70
 * doctype -- document type list returned by the query (publicID)<br>
71 154 jones
 * qformat=xml -- display resultset from query in XML<br>
72
 * qformat=html -- display resultset from query in HTML<br>
73
 * docid=34 -- display the document with the document ID number 34<br>
74 205 jones
 * doctext -- XML text of the document to load into the database<br>
75 183 jones
 * query -- actual query text (to go with 'action=query' or 'action=squery')<br>
76 205 jones
 * valtext -- XML text to be validated<br>
77
 * action=getdatadoc -- retreive a stored datadocument<br>
78 302 bojilova
 * action=getdoctypes -- retreive all doctypes (publicID)<br>
79
 * action=getdataguide -- retreive a Data Guide<br>
80 205 jones
 * datadoc -- data document name (id)<br>
81
 * <p>
82
 * The particular combination of parameters that are valid for each
83
 * particular action value is quite specific.  This documentation
84
 * will be reorganized to reflect this information.
85 46 jones
 */
86
public class MetaCatServlet extends HttpServlet {
87
88 370 berkley
  private ServletConfig config = null;
89
  private ServletContext context = null;
90
  private Hashtable connectionPool = new Hashtable();
91
  private String resultStyleURL = null;
92
  private String xmlcatalogfile = null;
93
  private String saxparser = null;
94
  private String defaultdatapath = null;
95
  private String servletpath = null;
96 380 jones
  private PropertyResourceBundle options = null;
97
  private MetaCatUtil util = null;
98
99
  // path to directory where data files
100
  // that can be downloaded will be stored
101 370 berkley
  private String htmlpath = null;
102 380 jones
  // script to get data file and put it
103
  // in defaultdocpath dir
104 370 berkley
  private String executescript  = null;
105 46 jones
106 184 jones
107 50 jones
  /**
108
   * Initialize the servlet by creating appropriate database connections
109
   */
110 46 jones
  public void init( ServletConfig config ) throws ServletException {
111
    try {
112
      super.init( config );
113
      this.config = config;
114 332 bojilova
      this.context = config.getServletContext();
115 184 jones
      System.out.println("MetaCatServlet Initialize");
116 82 jones
117 184 jones
      util = new MetaCatUtil();
118
119 83 jones
      // Get the configuration file information
120 184 jones
      resultStyleURL = util.getOption("resultStyleURL");
121
      xmlcatalogfile = util.getOption("xmlcatalogfile");
122
      saxparser = util.getOption("saxparser");
123
      defaultdatapath = util.getOption("defaultdatapath");
124
      executescript = util.getOption("executescript");
125 360 bojilova
      servletpath = util.getOption("servletpath");
126
      htmlpath = util.getOption("htmlpath");
127 82 jones
128 46 jones
      try {
129 309 bojilova
        // Open a pool of db connections
130
        connectionPool = util.getConnectionPool();
131
      } catch (Exception e) {
132
        System.err.println("Error creating pool of database connections");
133
        System.err.println(e.getMessage());
134
      }
135 46 jones
    } catch ( ServletException ex ) {
136
      throw ex;
137
    }
138
  }
139
140 320 bojilova
  /**
141
   * Close all db connections from the pool
142
   */
143
  public void destroy() {
144
145
    if (util != null) {
146
        util.closeConnections();
147
    }
148
  }
149
150 50 jones
  /** Handle "GET" method requests from HTTP clients */
151 46 jones
  public void doGet (HttpServletRequest request, HttpServletResponse response)
152
    throws ServletException, IOException {
153
154 48 jones
    // Process the data and send back the response
155 59 jones
    handleGetOrPost(request, response);
156 48 jones
  }
157
158 50 jones
  /** Handle "POST" method requests from HTTP clients */
159 48 jones
  public void doPost( HttpServletRequest request, HttpServletResponse response)
160
    throws ServletException, IOException {
161
162
    // Process the data and send back the response
163 59 jones
    handleGetOrPost(request, response);
164 48 jones
  }
165
166 49 jones
  /**
167 50 jones
   * Control servlet response depending on the action parameter specified
168 49 jones
   */
169 382 berkley
  private void handleGetOrPost(HttpServletRequest request,
170 59 jones
    HttpServletResponse response)
171 355 berkley
    throws ServletException, IOException
172
 {
173 48 jones
174 309 bojilova
    if ( util == null ) {
175
        util = new MetaCatUtil();
176
    }
177
    if ( connectionPool == null ) {
178
      try {
179
        // Open a pool of db connections
180
        connectionPool = util.getConnectionPool();
181
      } catch (Exception e) {
182
        System.err.println("Error creating pool of database connections");
183
        System.err.println(e.getMessage());
184
      }
185
    }
186 49 jones
    // Get a handle to the output stream back to the client
187 458 berkley
    //PrintWriter out = response.getWriter();
188 102 jones
    //response.setContentType("text/html");
189 49 jones
190 59 jones
    String name = null;
191
    String[] value = null;
192 103 jones
    String[] docid = new String[3];
193 59 jones
    Hashtable params = new Hashtable();
194
    Enumeration paramlist = request.getParameterNames();
195
    while (paramlist.hasMoreElements()) {
196
      name = (String)paramlist.nextElement();
197
      value = request.getParameterValues(name);
198 103 jones
199
      // Decode the docid and mouse click information
200
      if (name.endsWith(".y")) {
201
        docid[0] = name.substring(0,name.length()-2);
202
        //out.println("docid => " + docid[0]);
203
        params.put("docid", docid);
204
        name = "ypos";
205
      }
206
      if (name.endsWith(".x")) {
207
        name = "xpos";
208 373 berkley
      }
209 103 jones
210 102 jones
      //out.println(name + " => " + value[0]);
211 373 berkley
      params.put(name,value);
212
    }
213 355 berkley
214
    //if the user clicked on the input images, decode which image
215
    //was clicked then set the action.
216
    String action = decodeMouseAction(params);
217
    if(action.equals("error"))
218
    {
219
      action = ((String[])params.get("action"))[0];
220 103 jones
    }
221 355 berkley
222 380 jones
    // This block handles session management for the servlet
223
    // by looking up the current session information for all actions
224
    // other than "Login" and "Logout"
225 210 bojilova
    // handle login action
226 425 bojilova
    String username = null;
227
    String groupname = null;
228 297 bojilova
    if (action.equals("Login") || action.equals("Login Client")) {
229 458 berkley
      handleLoginAction(response.getWriter(), params, request, response);
230 210 bojilova
    // handle logout action
231 345 bojilova
    } else if (action.equals("Logout") || action.equals("Logout Client")) {
232 210 bojilova
      HttpSession sess = request.getSession(false);
233 251 bojilova
      if (sess != null) { sess.invalidate();  }
234 345 bojilova
      if (action.equals("Logout Client")) {
235 458 berkley
        PrintWriter out = response.getWriter();
236 345 bojilova
        out.println("<?xml version=\"1.0\"?>");
237
        out.println("<success>");
238
        out.println("User logout.");
239
        out.println("</success>");
240
        return;
241
      }
242 361 berkley
243 360 bojilova
      response.sendRedirect(htmlpath + "/index.html");
244 361 berkley
245 251 bojilova
    // aware of session expiration on every request
246 343 jones
    } else {
247 332 bojilova
      HttpSession sess = request.getSession(true);
248
      if (sess.isNew()) {
249 251 bojilova
        // session expired or has not been stored b/w user requests
250 328 bojilova
        // redirect to default page for query only access
251 441 bojilova
        //  response.sendRedirect(htmlpath + "/sexpire.html");
252
        username = "public";
253 425 bojilova
      } else {
254
        username = (String)sess.getAttribute("username");
255
        groupname = (String)sess.getAttribute("groupname");
256
      }
257 210 bojilova
    }
258 219 jones
259 380 jones
    // Now that we know the session is valid, we can delegate the request
260
    // to a particular action handler
261 361 berkley
    if(action.equals("query"))
262
    {
263 458 berkley
      handleQuery(response.getWriter(), params, response, username, groupname);
264 373 berkley
    }
265 371 berkley
    else if(action.equals("squery"))
266 361 berkley
    {
267 373 berkley
      if(params.containsKey("query"))
268
      {
269 458 berkley
        handleSQuery(response.getWriter(), params, response, username, groupname);
270 373 berkley
      }
271
      else
272
      {
273 458 berkley
        PrintWriter out = response.getWriter();
274 373 berkley
        out.println("Illegal action squery without \"query\" parameter");
275
      }
276
    }
277 361 berkley
    else if (action.equals("getdocument")) {
278 458 berkley
      PrintWriter out = response.getWriter();
279 87 jones
      try {
280
        handleGetDocumentAction(out, params, response);
281
      } catch (ClassNotFoundException e) {
282 103 jones
        out.println(e.getMessage());
283 87 jones
      } catch (SQLException se) {
284 103 jones
        out.println(se.getMessage());
285 87 jones
      }
286 453 berkley
    }
287
    else if (action.equals("getrelateddocument")) {
288 458 berkley
      PrintWriter out = response.getWriter();
289 453 berkley
      try {
290
        handleGetRelatedDocumentAction(out, params, response);
291
      } catch (ClassNotFoundException e) {
292
        out.println(e.getMessage());
293
      } catch (SQLException se) {
294
        out.println(se.getMessage());
295
      }
296
    }
297
    else if (action.equals("insert") || action.equals("update")) {
298 458 berkley
      PrintWriter out = response.getWriter();
299 425 bojilova
      if ( !username.equals("public") && (username != null) ) {
300
        handleInsertOrUpdateAction(out, params, response, username, groupname);
301
      } else {
302
        out.println("Permission denied for " + action);
303
      }
304 203 jones
    } else if (action.equals("delete")) {
305 458 berkley
      PrintWriter out = response.getWriter();
306 425 bojilova
      if ( !username.equals("public") && (username != null) ) {
307
        handleDeleteAction(out, params, response, username, groupname);
308
      } else {
309
        out.println("Permission denied for " + action);
310
      }
311 68 higgins
    } else if (action.equals("validate")) {
312 458 berkley
      PrintWriter out = response.getWriter();
313 437 berkley
      handleValidateAction(out, params, response);
314
    } else if (action.equals("getabstract")) {
315 458 berkley
      PrintWriter out = response.getWriter();
316 437 berkley
      try{
317
        handleViewAbstractAction(out, params, response);
318
      }
319
      catch(Exception e)
320
      {
321
        out.println("error viewing abstract: " + e.getMessage());
322
      }
323 91 higgins
    } else if (action.equals("getdatadoc")) {
324 458 berkley
      response.setContentType("application/zip");
325
      ServletOutputStream out = response.getOutputStream();
326 91 higgins
      handleGetDataDocumentAction(out, params, response);
327 302 bojilova
    } else if (action.equals("getdoctypes")) {
328 458 berkley
      PrintWriter out = response.getWriter();
329 302 bojilova
      handleGetDoctypesAction(out, params, response);
330
    } else if (action.equals("getdataguide")) {
331 458 berkley
      PrintWriter out = response.getWriter();
332 302 bojilova
      handleGetDataGuideAction(out, params, response);
333 297 bojilova
    } else if (action.equals("Login") || action.equals("Login Client")) {
334 50 jones
    } else {
335 458 berkley
      PrintWriter out = response.getWriter();
336 50 jones
      out.println("Error: action not registered.  Please report this error.");
337 46 jones
    }
338
339 49 jones
    // Close the stream to the client
340 458 berkley
    //out.close();
341 46 jones
  }
342 355 berkley
343
  /**
344
   * decodes the mouse click information coming from the client.
345
   * This function may be overwritten to provide specific functionality
346
   * for different applications.
347
   * @param params the parameters from the CGI
348
   * @return action the action to be performed or "error" if an error was
349
   * generated
350
   */
351 375 berkley
  protected String decodeMouseAction(Hashtable params)
352 355 berkley
  {
353
    // Determine what type of request the user made
354
    // if the action parameter is set, use it as a default
355
    // but if the ypos param is set, calculate the action needed
356
    String action=null;
357
    long ypos = 0;
358
    try {
359
      ypos = (new Long(((String[])params.get("ypos"))[0]).longValue());
360
      //out.println("<P>YPOS IS " + ypos);
361
      if (ypos <= 13) {
362
        action = "getdocument";
363
      } else if (ypos > 13 && ypos <= 27) {
364
        action = "validate";
365
      } else if (ypos > 27) {
366
        action = "transform";
367
      }
368
      return action;
369
    } catch (Exception npe) {
370 380 jones
      //
371
      // MBJ -- NOTE that this should be handled more gracefully with
372
      //        the new exception infrastructure -- this "error" return
373
      //        value is inappropriate
374 355 berkley
      //out.println("<P>Caught exception looking for Y value.");
375
      return "error";
376 382 berkley
    }
377 355 berkley
  }
378 49 jones
379 50 jones
  /**
380 210 bojilova
   * Handle the Login request. Create a new session object.
381
   * Make a user authentication through SRB RMI Connection.
382
   */
383
  private void handleLoginAction(PrintWriter out, Hashtable params,
384
               HttpServletRequest request, HttpServletResponse response) {
385 251 bojilova
386 297 bojilova
    MetaCatSession sess = null;
387 228 bojilova
    String un = ((String[])params.get("username"))[0];
388
    String pw = ((String[])params.get("password"))[0];
389 297 bojilova
    String action = ((String[])params.get("action"))[0];
390 332 bojilova
391 297 bojilova
    try {
392
        sess = new MetaCatSession(request, un, pw);
393
    } catch (Exception e) {
394
      out.println(e.getMessage());
395
    }
396 411 bojilova
397
    String output = null;
398
    output = sess.userLogin(response, un, pw, action, htmlpath);
399
    out.println(output);
400 297 bojilova
401 370 berkley
  }
402
403 373 berkley
  /**
404 380 jones
   * Retreive the squery xml, execute it and display it
405
   *
406
   * @param out the output stream to the client
407
   * @param params the Hashtable of parameters that should be included
408
   * in the squery.
409
   * @param response the response object linked to the client
410
   * @param conn the database connection
411
   */
412
  protected void handleSQuery(PrintWriter out, Hashtable params,
413 441 bojilova
                 HttpServletResponse response, String user, String group)
414 373 berkley
  {
415 380 jones
    String xmlquery = ((String[])params.get("query"))[0];
416
    String qformat = ((String[])params.get("qformat"))[0];
417 441 bojilova
    Hashtable doclist = runQuery(xmlquery, user, group);
418 443 berkley
    String resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
419 444 berkley
420 380 jones
    //format and transform the results
421
    if(qformat.equals("html")) {
422
      transformResultset(resultdoc, response, out);
423
    } else if(qformat.equals("xml")) {
424
      response.setContentType("text/xml");
425
      out.println(resultdoc);
426
    } else {
427
      out.println("invalid qformat: " + qformat);
428
    }
429 341 berkley
  }
430
431
   /**
432 380 jones
    * Create the xml query, execute it and display the results.
433
    *
434
    * @param out the output stream to the client
435
    * @param params the Hashtable of parameters that should be included
436 370 berkley
    * in the squery.
437 380 jones
    * @param response the response object linked to the client
438 370 berkley
    */
439 375 berkley
  protected void handleQuery(PrintWriter out, Hashtable params,
440 441 bojilova
                 HttpServletResponse response, String user, String group)
441 341 berkley
  {
442 370 berkley
    //create the query and run it
443 373 berkley
    String xmlquery = DBQuery.createSQuery(params);
444 441 bojilova
    Hashtable doclist = runQuery(xmlquery, user, group);
445 361 berkley
    String qformat = ((String[])params.get("qformat"))[0];
446 384 berkley
    String resultdoc = createResultDocument(doclist, transformQuery(params));
447 425 bojilova
448 370 berkley
    //format and transform the results
449 380 jones
    if(qformat.equals("html")) {
450 370 berkley
      transformResultset(resultdoc, response, out);
451 380 jones
    } else if(qformat.equals("xml")) {
452 370 berkley
      response.setContentType("text/xml");
453
      out.println(resultdoc);
454 443 berkley
    } else {
455 370 berkley
      out.println("invalid qformat: " + qformat);
456
    }
457 341 berkley
  }
458
459
  /**
460 384 berkley
   * Removes the <?xml version="x"?> tag from the beginning of xmlquery
461
   * so it can properly be placed in the <query> tag of the resultset.
462
   * This method is overwritable so that other applications can customize
463
   * the structure of what is in the <query> tag.
464
   *
465
   * @param xmlquery is the query to remove the <?xml version="x"?> tag from.
466
   */
467
  protected String transformQuery(Hashtable params)
468
  {
469
    //DBQuery.createSQuery is a re-calling of a previously called
470
    //function but it is necessary
471
    //so that overriding methods have access to the params hashtable
472
    String xmlquery = DBQuery.createSQuery(params);
473
    //the <?xml version="1.0"?> tag is the first 22 characters of the
474
    xmlquery = xmlquery.trim();
475
    int index = xmlquery.indexOf("?>");
476
    return xmlquery.substring(index + 2, xmlquery.length());
477
  }
478
479
  /**
480 443 berkley
   * removes the <?xml version="1.0"?> tag from the beginning.  This takes a
481
   * string as a param instead of a hashtable.
482
   *
483
   * @param xmlquery a string representing a query.
484
   */
485
  protected String transformQuery(String xmlquery)
486
  {
487
    xmlquery = xmlquery.trim();
488
    int index = xmlquery.indexOf("?>");
489
    return xmlquery.substring(index + 2, xmlquery.length());
490
  }
491
492
  /**
493 380 jones
   * Run the query and return a hashtable of results.
494
   *
495
   * @param xmlquery the query to run
496
   */
497 441 bojilova
  private Hashtable runQuery(String xmlquery, String user, String group)
498 341 berkley
  {
499
    Hashtable doclist=null;
500
    Connection conn = null;
501
    try
502
    {
503 441 bojilova
      conn = util.getConnection();
504
      DBQuery queryobj = new DBQuery(conn, saxparser);
505
      doclist = queryobj.findDocuments(new StringReader(xmlquery),user,group);
506
      util.returnConnection(conn);
507
      return doclist;
508 341 berkley
    }
509
    catch (Exception e)
510
    {
511 441 bojilova
      util.returnConnection(conn);
512 341 berkley
      util.debugMessage("Error in runQuery: " + e.getMessage());
513
      doclist = null;
514
      return doclist;
515
    }
516
  }
517
518 380 jones
  /**
519 370 berkley
   * Transorms an xml resultset document to html and sends it to the browser
520 380 jones
   *
521 370 berkley
   * @param resultdoc the string representation of the document that needs
522
   * to be transformed.
523
   * @param response the HttpServletResponse object bound to the client.
524
   * @param out the output stream to the client
525 375 berkley
   */
526
  protected void transformResultset(String resultdoc,
527 380 jones
                                    HttpServletResponse response,
528
                                    PrintWriter out)
529 370 berkley
  {
530
    Connection conn = null;
531 380 jones
    try {
532 370 berkley
      conn = util.getConnection();
533
      DBTransform trans = new DBTransform(conn);
534
      response.setContentType("text/html");
535
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN",
536
                                 "-//W3C//HTML//EN", out);
537 382 berkley
      util.returnConnection(conn);
538
    }
539
    catch(Exception e)
540
    {
541 441 bojilova
      util.returnConnection(conn);
542 370 berkley
    }
543
  }
544
545 355 berkley
  /**
546
   * Transforms a hashtable of documents to an xml or html result.
547 380 jones
   *
548 355 berkley
   * @param doclist- the hashtable to transform
549
   * @param xmlquery- the query that returned the dolist result
550
   */
551 375 berkley
  protected String createResultDocument(Hashtable doclist, String xmlquery)
552 341 berkley
  {
553
    // Create a buffer to hold the xml result
554
    StringBuffer resultset = new StringBuffer();
555
556 382 berkley
    // Print the resulting root nodes
557 341 berkley
    String docid = null;
558
    String document = null;
559
    resultset.append("<?xml version=\"1.0\"?>\n");
560
    resultset.append("<resultset>\n");
561 375 berkley
562 384 berkley
    resultset.append("  <query>" + xmlquery + "</query>");
563 375 berkley
564 341 berkley
    Enumeration doclistkeys = doclist.keys();
565
    while (doclistkeys.hasMoreElements())
566
    {
567
      docid = (String)doclistkeys.nextElement();
568
      document = (String)doclist.get(docid);
569
      resultset.append("  <document>" + document + "</document>");
570 373 berkley
    }
571 341 berkley
    resultset.append("</resultset>");
572 444 berkley
    //System.out.println(resultset.toString());
573 370 berkley
    return resultset.toString();
574 341 berkley
  }
575 437 berkley
576
  /**
577
   * Handle the request to view the abstract of a document.
578 444 berkley
   * The abstractpath CGI parameter gives the xml path to the abstract
579
   * node.
580 437 berkley
   */
581
  private void handleViewAbstractAction(PrintWriter out, Hashtable params,
582
               HttpServletResponse response) throws IOException, SQLException
583
  {
584
    String abstractpath = null;
585
    String docid = null;
586
    Connection conn = null;
587
    response.setContentType("text/html");
588
    try
589
    {
590
      docid = ((String[])params.get("docid"))[0];
591
      if(params.containsKey("abstractpath"))
592
      {
593 444 berkley
        //the CGI parameter abstractpath holds the path to the abstract
594
        //that should be displayed.
595 437 berkley
        abstractpath = ((String[])params.get("abstractpath"))[0];
596
      }
597
      else
598
      {
599
        out.println("error: no abstractpath parameter");
600
      }
601
      conn = util.getConnection();
602
603
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid, conn);
604
605 444 berkley
      out.println("<html><head><title>Abstract</title></head>");
606
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
607 437 berkley
      for(int i=0; i<abstracts.length; i++)
608
      {
609
        out.println("<p>" + (String)abstracts[i] + "</p>");
610
      }
611
      out.println("</body></html>");
612
    }
613
    catch (IOException ioe)
614
    {
615 444 berkley
       util.debugMessage("error in handlegetabstract: " + ioe.getMessage());
616 437 berkley
    }
617
    catch(SQLException sqle)
618
    {
619 444 berkley
      util.debugMessage("error in handlegetabstract: " + sqle.getMessage());
620 437 berkley
    }
621
    catch(Exception e)
622
    {
623 444 berkley
      util.debugMessage("error in handlegetabstract: " + e.getMessage());
624 437 berkley
    }
625
626
    util.returnConnection(conn);
627
  }
628 181 jones
629 50 jones
  /**
630 453 berkley
   * Handle the database getrelateddocument request and return a XML document,
631
   * possibly transformed from XML into HTML
632
   */
633
  private void handleGetRelatedDocumentAction(PrintWriter out, Hashtable params,
634
               HttpServletResponse response)
635
               throws ClassNotFoundException, IOException, SQLException
636
  {
637
    String docid = null;
638
    Connection conn = null;
639
640
    if(params.containsKey("url"))
641
    {//the identifier for the related document is contained in the URL param
642
      try
643
      {
644
        DocumentImpl xmldoc=null;
645
        metacatURL murl = new metacatURL(((String[])params.get("url"))[0]);
646
        if(murl.getURLType().equals("metacat"))
647
        {//get the document from the database if it is the right type of url
648
          String[] murlParams = murl.getParam(0);
649
          if(murlParams[0].equals("docid"))
650
          {//the docid should be first
651
            murl.printParams();
652
            docid = murlParams[1]; //get the docid value
653
            conn = util.getConnection();
654
            xmldoc = new DocumentImpl(conn, docid);
655
656
            //**************************************************
657
            //the style sheet handling code needs to be put here.
658
            out.println(xmldoc.toString());
659
            //**************************************************
660
          }
661
          else
662
          {
663
            //throw new Exception("handleGetDocument: bad URL");
664
            System.err.println("handleGetDocument: bad URL");
665
          }
666
        }
667
        else if(murl.getURLType().equals("http"))
668
        {//get the document from the internet
669
          String[] murlParams = murl.getParam(0);
670
          if(murlParams[0].equals("httpurl"))
671
          {//httpurl is the param name for an http url.
672
            URL urlconn = new URL(murlParams[1]);  //create a new url obj.
673 458 berkley
            //DataInputStream htmldoc = new DataInputStream(urlconn.openStream());
674
            BufferedReader htmldoc = new BufferedReader(
675
                                   new InputStreamReader(urlconn.openStream()));
676 453 berkley
            //bind a data stream.
677
            try
678
            { //display the document
679
              String line=null;
680
              while((line = htmldoc.readLine()) != null)
681
              {
682
                out.println(line);
683
              }
684
            }
685
            catch(Exception e)
686
            {
687
              util.debugMessage("error viewing html document");
688
            }
689
          }
690
        }
691
      }
692
      catch (McdbException e) {
693
        response.setContentType("text/xml");
694
        e.toXml(out);
695
      } catch   (Throwable t) {
696
        response.setContentType("text/html");
697
        out.println(t.getMessage());
698
      } finally {
699
        util.returnConnection(conn);
700
      }
701
    }
702
  }
703
704
  /**
705 50 jones
   * Handle the database getdocument request and return a XML document,
706
   * possibly transformed from XML into HTML
707
   */
708 382 berkley
  private void handleGetDocumentAction(PrintWriter out, Hashtable params,
709 87 jones
               HttpServletResponse response)
710
               throws ClassNotFoundException, IOException, SQLException {
711 102 jones
    String docidstr = null;
712 162 bojilova
    String docid = null;
713 102 jones
    String doc = null;
714 309 bojilova
    Connection conn = null;
715
716 102 jones
    try {
717 87 jones
      // Find the document id number
718 102 jones
      docidstr = ((String[])params.get("docid"))[0];
719 162 bojilova
      docid = docidstr;
720 309 bojilova
      conn = util.getConnection();
721 393 jones
      DocumentImpl xmldoc = new DocumentImpl(conn, docid);
722
      // Get the document indicated from the db
723
      //doc = docreader.readXMLDocument(docid);
724 85 jones
725 87 jones
      // Return the document in XML or HTML format
726 437 berkley
      String qformat=null;
727
      if(params.containsKey("qformat"))
728
      {
729
        qformat = ((String[])params.get("qformat"))[0];
730
      }
731
      else
732
      {
733
        qformat = "html";
734
      }
735
      if (qformat.equals("xml")) {
736 85 jones
        // set content type and other response header fields first
737
        response.setContentType("text/xml");
738 431 jones
        xmldoc.toXml(out);
739
        //out.println(xmldoc);
740 85 jones
      } else if (qformat.equals("html")) {
741 437 berkley
        response.setContentType("text/html");
742 87 jones
        // Look up the document type
743 393 jones
        String sourcetype = xmldoc.getDoctype();
744 87 jones
        // Transform the document to the new doctype
745 393 jones
        DBTransform dbt = new DBTransform(conn);
746
        dbt.transformXMLDocument(xmldoc.toString(), sourcetype,
747
                                 "-//W3C//HTML//EN", out);
748 85 jones
      }
749 343 jones
    } catch (McdbException e) {
750
      response.setContentType("text/xml");
751
      e.toXml(out);
752
    } catch (Throwable t) {
753 309 bojilova
      response.setContentType("text/html");
754 343 jones
      out.println(t.getMessage());
755 309 bojilova
    } finally {
756 320 bojilova
      util.returnConnection(conn);
757 309 bojilova
    }
758
759 49 jones
  }
760 55 jones
761
  /**
762
   * Handle the database putdocument request and write an XML document
763
   * to the database connection
764
   */
765 382 berkley
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params,
766 425 bojilova
               HttpServletResponse response, String user, String group) {
767 59 jones
768 309 bojilova
    Connection conn = null;
769
770 204 jones
    try {
771
      // Get the document indicated
772
      String[] doctext = (String[])params.get("doctext");
773
      StringReader xml = null;
774
      try {
775
        xml = new StringReader(doctext[0]);
776 59 jones
777 204 jones
        String[] action = (String[])params.get("action");
778
        String[] docid = (String[])params.get("docid");
779
        String newdocid = null;
780 203 jones
781 204 jones
        String doAction = null;
782
        if (action[0].equals("insert")) {
783
          doAction = "INSERT";
784
        } else if (action[0].equals("update")) {
785
          doAction = "UPDATE";
786
        }
787 203 jones
788 204 jones
        try {
789 309 bojilova
            // get a connection from the pool
790
            conn = util.getConnection();
791 408 jones
792 309 bojilova
            // write the document to the database
793
            try {
794
                String accNumber = docid[0];
795
                if (accNumber.equals("")) {
796
                    accNumber = null;
797
                }
798 425 bojilova
                newdocid = DocumentImpl.write(conn, xml, doAction, accNumber,
799
                                                                  user, group);
800 309 bojilova
            } catch (NullPointerException npe) {
801 425 bojilova
              newdocid = DocumentImpl.write(conn,xml,doAction,null,user,group);
802 309 bojilova
            }
803
        } catch (Exception e) {
804
          response.setContentType("text/html");
805
          out.println(e.getMessage());
806
        } finally {
807 320 bojilova
          util.returnConnection(conn);
808 309 bojilova
        }
809
810 204 jones
        // set content type and other response header fields first
811
        response.setContentType("text/xml");
812
        out.println("<?xml version=\"1.0\"?>");
813
        out.println("<success>");
814
        out.println("<docid>" + newdocid + "</docid>");
815
        out.println("</success>");
816
817 203 jones
      } catch (NullPointerException npe) {
818 204 jones
        response.setContentType("text/xml");
819
        out.println("<?xml version=\"1.0\"?>");
820
        out.println("<error>");
821
        out.println(npe.getMessage());
822
        out.println("</error>");
823 55 jones
      }
824 204 jones
    } catch (Exception e) {
825
      response.setContentType("text/xml");
826
      out.println("<?xml version=\"1.0\"?>");
827
      out.println("<error>");
828
      out.println(e.getMessage());
829
      if (e instanceof SAXException) {
830
        Exception e2 = ((SAXException)e).getException();
831
        out.println("<error>");
832
        out.println(e2.getMessage());
833
        out.println("</error>");
834
      }
835
      //e.printStackTrace(out);
836
      out.println("</error>");
837 203 jones
    }
838 55 jones
  }
839 203 jones
840
  /**
841
   * Handle the database delete request and delete an XML document
842
   * from the database connection
843
   */
844
  private void handleDeleteAction(PrintWriter out, Hashtable params,
845 425 bojilova
               HttpServletResponse response, String user, String group) {
846 203 jones
847
    String[] docid = (String[])params.get("docid");
848 309 bojilova
    Connection conn = null;
849 203 jones
850
    // delete the document from the database
851
    try {
852 309 bojilova
      // get a connection from the pool
853
      conn = util.getConnection();
854 203 jones
                                      // NOTE -- NEED TO TEST HERE
855 408 jones
                                      // FOR EXISTENCE OF DOCID PARAM
856 203 jones
                                      // BEFORE ACCESSING ARRAY
857 375 berkley
      try {
858 425 bojilova
        DocumentImpl.delete(conn, docid[0], user, group);
859 204 jones
        response.setContentType("text/xml");
860
        out.println("<?xml version=\"1.0\"?>");
861
        out.println("<success>");
862 203 jones
        out.println("Document deleted.");
863 204 jones
        out.println("</success>");
864 203 jones
      } catch (AccessionNumberException ane) {
865 204 jones
        response.setContentType("text/xml");
866
        out.println("<?xml version=\"1.0\"?>");
867
        out.println("<error>");
868
        out.println("Error deleting document!!!");
869 203 jones
        out.println(ane.getMessage());
870 204 jones
        out.println("</error>");
871 203 jones
      }
872 204 jones
    } catch (Exception e) {
873
      response.setContentType("text/xml");
874
      out.println("<?xml version=\"1.0\"?>");
875
      out.println("<error>");
876
      out.println(e.getMessage());
877
      out.println("</error>");
878 309 bojilova
    } finally {
879 320 bojilova
      util.returnConnection(conn);
880 309 bojilova
    }
881 203 jones
  }
882 68 higgins
883
  /**
884 380 jones
   * Handle the validation request and return the results to the requestor
885 68 higgins
   */
886 185 jones
  private void handleValidateAction(PrintWriter out, Hashtable params,
887
               HttpServletResponse response) {
888 68 higgins
889 103 jones
    // Get the document indicated
890
    String valtext = null;
891 309 bojilova
892 103 jones
    try {
893
      valtext = ((String[])params.get("valtext"))[0];
894
    } catch (Exception nullpe) {
895 68 higgins
896 309 bojilova
      Connection conn = null;
897 162 bojilova
      String docid = null;
898 103 jones
      try {
899
        // Find the document id number
900 185 jones
        docid = ((String[])params.get("docid"))[0];
901 309 bojilova
902
        // get a connection from the pool
903
        conn = util.getConnection();
904 393 jones
905 309 bojilova
        // Get the document indicated from the db
906 393 jones
        DocumentImpl xmldoc = new DocumentImpl(conn, docid);
907
        valtext = xmldoc.toString();
908 185 jones
909 103 jones
      } catch (NullPointerException npe) {
910 253 jones
        response.setContentType("text/xml");
911
        out.println("<error>Error getting document ID: " + docid + "</error>");
912 320 bojilova
        if ( conn != null ) { util.returnConnection(conn); }
913 380 jones
        return;
914 309 bojilova
      } catch (Exception e) {
915
        response.setContentType("text/html");
916
        out.println(e.getMessage());
917
      } finally {
918 320 bojilova
        util.returnConnection(conn);
919 309 bojilova
      }
920 103 jones
    }
921 68 higgins
922 309 bojilova
    Connection conn = null;
923 103 jones
    try {
924 309 bojilova
      // get a connection from the pool
925
      conn = util.getConnection();
926 253 jones
      DBValidate valobj = new DBValidate(saxparser,conn);
927 185 jones
      boolean valid = valobj.validateString(valtext);
928 68 higgins
929
      // set content type and other response header fields first
930 253 jones
      response.setContentType("text/xml");
931
      out.println(valobj.returnErrors());
932
933 103 jones
    } catch (NullPointerException npe2) {
934
      // set content type and other response header fields first
935 253 jones
      response.setContentType("text/xml");
936
      out.println("<error>Error validating document.</error>");
937 309 bojilova
    } catch (Exception e) {
938
      response.setContentType("text/html");
939
      out.println(e.getMessage());
940
    } finally {
941 320 bojilova
      util.returnConnection(conn);
942 309 bojilova
    }
943 103 jones
  }
944 87 jones
945
  /**
946 380 jones
   * Handle the document request and return the results to the requestor
947 458 berkley
   * If a docid is passed in through the params then that document
948
   * will be retrieved form the DB and put in the zip file.
949
   * In addition if 1 or more relations parameters are passed, those file
950
   * will be zipped as well.  Currently this is only implemented for
951
   * metacat:// and http:// files.  Support should be added for srb:// files
952
   * as well.
953 91 higgins
   */
954 458 berkley
  private void handleGetDataDocumentAction(ServletOutputStream out,
955
               Hashtable params,
956 185 jones
               HttpServletResponse response) {
957 458 berkley
  //find the related files, get them from their source and zip them into
958
  //a zip file.
959
  try
960
  {
961
    Connection conn = util.getConnection();
962
    String currentDocid = ((String[])params.get("docid"))[0];
963
    ZipOutputStream zout = new ZipOutputStream(out);
964
    byte[] bytestring = null;
965
    ZipEntry zentry = null;
966
    DocumentImpl xmldoc = null;
967
    String[] reldocs = null;
968
969
    if(params.containsKey("relation"))
970
    { //get the relations from the parameters.
971
      reldocs = ((String[])params.get("relation"));
972
    }
973
    else
974
    { //let the for loop know that there are no relations to zip
975
      reldocs = new String[0];
976
    }
977
978
    //write the base file to the zip file.
979
    xmldoc = new DocumentImpl(conn, currentDocid);
980
    bytestring = (xmldoc.toString()).getBytes();
981
    zentry = new ZipEntry(currentDocid + ".xml");
982
    //create a new zip entry and write the file to the stream
983
    zentry.setSize(bytestring.length);
984
    zout.putNextEntry(zentry);
985
    zout.write(bytestring, 0, bytestring.length);
986
    zout.closeEntry(); //get ready for the next entry.
987
988
    //zip up the related documents
989
    for(int i=0; i<reldocs.length; i++)
990
    {
991
      metacatURL murl = new metacatURL(((String)reldocs[i]));
992
      if(murl.getURLType().equals("metacat"))
993
      {
994
        //get the document from the database
995
        xmldoc = new DocumentImpl(conn, (murl.getParam(0))[1]);
996
        bytestring = (xmldoc.toString()).getBytes();
997
        zentry = new ZipEntry((murl.getParam(0))[1] + ".xml");
998
        //create a new zip entry and write the file to the stream
999
        zentry.setSize(bytestring.length);
1000
        zout.putNextEntry(zentry);
1001
        zout.write(bytestring, 0, bytestring.length);
1002
        zout.closeEntry(); //get ready for the next entry.
1003
      }
1004
      else if(murl.getURLType().equals("http"))
1005
      {
1006
        String[] murlParams = murl.getParam(0);
1007
        if(murlParams[0].equals("httpurl"))
1008
        {//httpurl is the param name for an http url.
1009
          URL urlconn = new URL(murlParams[1]);  //create a new url obj.
1010
          BufferedReader htmldoc = new BufferedReader(
1011
                                   new InputStreamReader(urlconn.openStream()));
1012
          //get the data from the web server
1013
          try
1014
          { //zip the document
1015
            String line=null;
1016
            zentry = new ZipEntry((murl.getParam(1))[1]);
1017
            //get just the filename from the URL.
1018
            zout.putNextEntry(zentry);
1019
            //make a new entry in the zip file stream
1020
            while((line = htmldoc.readLine()) != null)
1021
            {
1022
              bytestring = (line.toString()).getBytes();
1023
              zout.write(bytestring, 0, bytestring.length);
1024
              //write out the file line by line
1025
            }
1026
            zout.closeEntry(); //close the entry in the file
1027
          }
1028
          catch(Exception e)
1029
          {
1030
            util.debugMessage("error downloading html document");
1031
          }
1032
        }
1033
      }
1034
    }
1035
    zout.finish();  //terminate the zip file
1036
    zout.close();   //close the stream.
1037
    util.returnConnection(conn); //return the connection to the pool
1038
  }
1039
  catch(Exception e)
1040
  {
1041
    System.out.println("Error creating zip file: " + e.getMessage());
1042
    e.printStackTrace(System.out);
1043
  }
1044
1045
   /*
1046
   //////////old code using a shell script/////////////////////////////////
1047
1048 91 higgins
      boolean error_flag = false;
1049
      String error_message = "";
1050
      // Get the document indicated
1051
      String[] datadoc = (String[])params.get("datadoc");
1052 185 jones
      // defaultdatapath = "C:\\Temp\\";    // for testing only!!!
1053
      // executescript = "test.bat";        // for testing only!!!
1054 91 higgins
1055
      // set content type and other response header fields first
1056
      response.setContentType("application/octet-stream");
1057 185 jones
      if (defaultdatapath!=null) {
1058
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) {
1059
          defaultdatapath=defaultdatapath+System.getProperty("file.separator");
1060 91 higgins
        }
1061 185 jones
        System.out.println("Path= "+defaultdatapath+datadoc[0]);
1062
        if (executescript!=null) {
1063
          String command = null;
1064
          File scriptfile = new File(executescript);
1065
          if (scriptfile.exists()) {
1066
            command=executescript+" "+datadoc[0]; // script includes path
1067
        } else {     // look in defaultdatapath
1068
            // on Win98 one MUST include the .bat extender
1069
            command = defaultdatapath+executescript+" "+datadoc[0];
1070
        }
1071 91 higgins
      System.out.println(command);
1072
      try {
1073
      Process proc = Runtime.getRuntime().exec(command);
1074
      proc.waitFor();
1075
      }
1076
      catch (Exception eee) {
1077
        System.out.println("Error running process!");
1078
        error_flag = true;
1079
        error_message = "Error running process!";}
1080
      } // end executescript not null if
1081
      File datafile = new File(defaultdatapath+datadoc[0]);
1082
      try {
1083
      FileInputStream fw = new FileInputStream(datafile);
1084
      int x;
1085 185 jones
      while ((x = fw.read())!=-1) {
1086 91 higgins
        out.write(x); }
1087 185 jones
        fw.close();
1088
      } catch (Exception e) {
1089 91 higgins
        System.out.println("Error in returning file\n"+e.getMessage());
1090
        error_flag=true;
1091 185 jones
        error_message = error_message+"\nError in returning file\n"+
1092
                        e.getMessage();
1093
      }
1094
    } // end defaultdatapath not null if
1095 458 berkley
    */
1096 91 higgins
  }
1097 302 bojilova
1098
  /**
1099
   * Handle the getdoctypes Action.
1100
   * Read all doctypes from db connection in XML format
1101
   */
1102
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
1103
                                       HttpServletResponse response) {
1104
1105 309 bojilova
    Connection conn = null;
1106
1107 302 bojilova
    try {
1108
1109 309 bojilova
        // get connection from the pool
1110
        conn = util.getConnection();
1111
        DBUtil dbutil = new DBUtil(conn);
1112 302 bojilova
        String doctypes = dbutil.readDoctypes();
1113
        out.println(doctypes);
1114
1115
    } catch (Exception e) {
1116
      out.println("<?xml version=\"1.0\"?>");
1117
      out.println("<error>");
1118
      out.println(e.getMessage());
1119
      out.println("</error>");
1120 309 bojilova
    } finally {
1121 320 bojilova
      util.returnConnection(conn);
1122 309 bojilova
    }
1123 302 bojilova
1124
  }
1125
1126
  /**
1127
   * Handle the getdataguide Action.
1128
   * Read Data Guide for a given doctype from db connection in XML format
1129
   */
1130
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params,
1131
                                        HttpServletResponse response) {
1132
1133 309 bojilova
    Connection conn = null;
1134 316 bojilova
    String doctype = null;
1135
    String[] doctypeArr = (String[])params.get("doctype");
1136 309 bojilova
1137 316 bojilova
    // get only the first doctype specified in the list of doctypes
1138
    // it could be done for all doctypes in that list
1139
    if (doctypeArr != null) {
1140
        doctype = ((String[])params.get("doctype"))[0];
1141
    }
1142
1143 302 bojilova
    try {
1144
1145 309 bojilova
        // get connection from the pool
1146
        conn = util.getConnection();
1147
        DBUtil dbutil = new DBUtil(conn);
1148 316 bojilova
        String dataguide = dbutil.readDataGuide(doctype);
1149 302 bojilova
        out.println(dataguide);
1150
1151
    } catch (Exception e) {
1152
      out.println("<?xml version=\"1.0\"?>");
1153
      out.println("<error>");
1154
      out.println(e.getMessage());
1155
      out.println("</error>");
1156 309 bojilova
    } finally {
1157 320 bojilova
      util.returnConnection(conn);
1158 309 bojilova
    }
1159 302 bojilova
1160
  }
1161
1162 46 jones
}