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