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 798 jones
import com.oreilly.servlet.multipart.FilePart;
31
import com.oreilly.servlet.multipart.MultipartParser;
32
import com.oreilly.servlet.multipart.ParamPart;
33
import com.oreilly.servlet.multipart.Part;
34
35 733 bojilova
import java.io.File;
36 46 jones
import java.io.PrintWriter;
37
import java.io.IOException;
38 50 jones
import java.io.StringReader;
39 185 jones
import java.io.FileInputStream;
40 731 bojilova
import java.io.BufferedInputStream;
41 46 jones
import java.util.Enumeration;
42
import java.util.Hashtable;
43 341 berkley
import java.util.ResourceBundle;
44 648 berkley
import java.util.Random;
45 82 jones
import java.util.PropertyResourceBundle;
46 50 jones
import java.net.URL;
47
import java.net.MalformedURLException;
48 85 jones
import java.sql.PreparedStatement;
49
import java.sql.ResultSet;
50 50 jones
import java.sql.Connection;
51 55 jones
import java.sql.SQLException;
52 361 berkley
import java.lang.reflect.*;
53 453 berkley
import java.net.*;
54 458 berkley
import java.util.zip.*;
55 46 jones
56
import javax.servlet.ServletConfig;
57
import javax.servlet.ServletContext;
58
import javax.servlet.ServletException;
59 48 jones
import javax.servlet.ServletInputStream;
60 46 jones
import javax.servlet.http.HttpServlet;
61
import javax.servlet.http.HttpServletRequest;
62
import javax.servlet.http.HttpServletResponse;
63 210 bojilova
import javax.servlet.http.HttpSession;
64 47 jones
import javax.servlet.http.HttpUtils;
65 458 berkley
import javax.servlet.ServletOutputStream;
66 46 jones
67 204 jones
import org.xml.sax.SAXException;
68
69 46 jones
/**
70
 * A metadata catalog server implemented as a Java Servlet
71 154 jones
 *
72
 * <p>Valid parameters are:<br>
73
 * action=query -- query the values of all elements and attributes
74
 *                     and return a result set of nodes<br>
75 943 tao
 * action=squery -- structured query (see pathquery.dtd)<br>
76
 * action= -- export a zip format for data packadge<br>
77 731 bojilova
 * action=read -- read any metadata/data file from Metacat and from Internet<br>
78 205 jones
 * action=insert -- insert an XML document into the database store<br>
79
 * action=update -- update an XML document that is in the database store<br>
80
 * action=delete --  delete an XML document from the database store<br>
81
 * action=validate -- vallidate the xml contained in valtext<br>
82
 * doctype -- document type list returned by the query (publicID)<br>
83 154 jones
 * qformat=xml -- display resultset from query in XML<br>
84
 * qformat=html -- display resultset from query in HTML<br>
85 731 bojilova
 * qformat=zip -- zip resultset from query<br>
86 154 jones
 * docid=34 -- display the document with the document ID number 34<br>
87 205 jones
 * doctext -- XML text of the document to load into the database<br>
88 598 bojilova
 * acltext -- XML access text for a document to load into the database<br>
89
 * dtdtext -- XML DTD text for a new DTD to load into Metacat XML Catalog<br>
90 183 jones
 * query -- actual query text (to go with 'action=query' or 'action=squery')<br>
91 205 jones
 * valtext -- XML text to be validated<br>
92 731 bojilova
 * abstractpath -- XPath in metadata document to read from<br>
93 688 bojilova
 * action=getaccesscontrol -- retrieve acl info for Metacat document<br>
94
 * action=getdoctypes -- retrieve all doctypes (publicID)<br>
95 699 bojilova
 * action=getdtdschema -- retrieve a DTD or Schema file<br>
96 688 bojilova
 * action=getdataguide -- retrieve a Data Guide<br>
97 725 bojilova
 * action=getprincipals -- retrieve a list of principals in XML<br>
98 205 jones
 * datadoc -- data document name (id)<br>
99
 * <p>
100
 * The particular combination of parameters that are valid for each
101
 * particular action value is quite specific.  This documentation
102
 * will be reorganized to reflect this information.
103 46 jones
 */
104
public class MetaCatServlet extends HttpServlet {
105
106 370 berkley
  private ServletConfig config = null;
107
  private ServletContext context = null;
108
  private String resultStyleURL = null;
109
  private String xmlcatalogfile = null;
110
  private String saxparser = null;
111 798 jones
  private String datafilepath = null;
112
  private File dataDirectory = null;
113 370 berkley
  private String servletpath = null;
114 822 jones
  private String htmlpath = null;
115 380 jones
  private PropertyResourceBundle options = null;
116
  private MetaCatUtil util = null;
117 1217 tao
  private DBConnectionPool connPool = null;
118 380 jones
119 50 jones
  /**
120
   * Initialize the servlet by creating appropriate database connections
121
   */
122 46 jones
  public void init( ServletConfig config ) throws ServletException {
123
    try {
124
      super.init( config );
125
      this.config = config;
126 332 bojilova
      this.context = config.getServletContext();
127 184 jones
      System.out.println("MetaCatServlet Initialize");
128 82 jones
129 184 jones
      util = new MetaCatUtil();
130 1217 tao
131
      //initial DBConnection pool
132
      connPool = DBConnectionPool.getInstance();
133 184 jones
134 83 jones
      // Get the configuration file information
135 184 jones
      resultStyleURL = util.getOption("resultStyleURL");
136
      xmlcatalogfile = util.getOption("xmlcatalogfile");
137
      saxparser = util.getOption("saxparser");
138 798 jones
      datafilepath = util.getOption("datafilepath");
139
      dataDirectory = new File(datafilepath);
140 360 bojilova
      servletpath = util.getOption("servletpath");
141
      htmlpath = util.getOption("htmlpath");
142 598 bojilova
143 1217 tao
144 46 jones
    } catch ( ServletException ex ) {
145
      throw ex;
146 1217 tao
    } catch (SQLException e) {
147
      MetaCatUtil.debugMessage("Error in MetacatServlet.init: "
148
                                          +e.getMessage(), 20);
149 46 jones
    }
150
  }
151
152 320 bojilova
  /**
153
   * Close all db connections from the pool
154
   */
155
  public void destroy() {
156 1217 tao
      // Close all db connection
157
      connPool.release();
158 320 bojilova
  }
159
160 50 jones
  /** Handle "GET" method requests from HTTP clients */
161 46 jones
  public void doGet (HttpServletRequest request, HttpServletResponse response)
162
    throws ServletException, IOException {
163
164 48 jones
    // Process the data and send back the response
165 59 jones
    handleGetOrPost(request, response);
166 48 jones
  }
167
168 50 jones
  /** Handle "POST" method requests from HTTP clients */
169 48 jones
  public void doPost( HttpServletRequest request, HttpServletResponse response)
170
    throws ServletException, IOException {
171
172
    // Process the data and send back the response
173 59 jones
    handleGetOrPost(request, response);
174 48 jones
  }
175
176 49 jones
  /**
177 50 jones
   * Control servlet response depending on the action parameter specified
178 49 jones
   */
179 382 berkley
  private void handleGetOrPost(HttpServletRequest request,
180 798 jones
                               HttpServletResponse response)
181
                               throws ServletException, IOException
182
  {
183 48 jones
184 309 bojilova
    if ( util == null ) {
185
        util = new MetaCatUtil();
186
    }
187 1221 tao
    /*MetaCatUtil.debugMessage("Connection pool size: "
188 1217 tao
                                     +connPool.getSizeOfDBConnectionPool(),10);
189
    MetaCatUtil.debugMessage("Free DBConnection number: "
190 1221 tao
                                  +connPool.getFreeDBConnectionNumber(), 10);*/
191
    //If all DBConnection in the pool are free and DBConnection pool
192
    //size is greater than initial value, shrink the connection pool
193
    //size to initial value
194
    DBConnectionPool.shrinkDBConnectionPoolSize();
195
196 1217 tao
    //Debug message to print out the method which have a busy DBConnection
197
    connPool.printMethodNameHavingBusyDBConnection();
198
199 800 jones
    String ctype = request.getContentType();
200
    if (ctype != null && ctype.startsWith("multipart/form-data")) {
201 798 jones
      handleMultipartForm(request, response);
202
    } else {
203 943 tao
204 49 jones
205 798 jones
      String name = null;
206
      String[] value = null;
207
      String[] docid = new String[3];
208
      Hashtable params = new Hashtable();
209
      Enumeration paramlist = request.getParameterNames();
210 1217 tao
211
212 798 jones
      while (paramlist.hasMoreElements()) {
213 1217 tao
214 798 jones
        name = (String)paramlist.nextElement();
215
        value = request.getParameterValues(name);
216
217
        // Decode the docid and mouse click information
218
        if (name.endsWith(".y")) {
219
          docid[0] = name.substring(0,name.length()-2);
220
          params.put("docid", docid);
221
          name = "ypos";
222 648 berkley
        }
223 798 jones
        if (name.endsWith(".x")) {
224
          name = "xpos";
225
        }
226
227
        params.put(name,value);
228 425 bojilova
      }
229 798 jones
230 1217 tao
231
      //handle param is emptpy
232
      if (params.isEmpty() || params == null)
233
      {
234
        return;
235
      }
236 798 jones
      //if the user clicked on the input images, decode which image
237
      //was clicked then set the action.
238
      String action = ((String[])params.get("action"))[0];
239 1217 tao
      util.debugMessage("Line 230: Action is: " + action, 1);
240 798 jones
241
      // This block handles session management for the servlet
242
      // by looking up the current session information for all actions
243
      // other than "login" and "logout"
244
      String username = null;
245
      String password = null;
246 802 bojilova
      String[] groupnames = null;
247 798 jones
      String sess_id = null;
248
249
      // handle login action
250
      if (action.equals("login")) {
251 1217 tao
        PrintWriter out = response.getWriter();
252
        handleLoginAction(out, params, request, response);
253
        out.close();
254 798 jones
255
      // handle logout action
256
      } else if (action.equals("logout")) {
257 1217 tao
        PrintWriter out = response.getWriter();
258
        handleLogoutAction(out, params, request, response);
259
        out.close();
260 1221 tao
261
      // handle shrink DBConnection request
262
      } else if (action.equals("shrink")) {
263
        PrintWriter out = response.getWriter();
264
        boolean success = false;
265
        //If all DBConnection in the pool are free and DBConnection pool
266
        //size is greater than initial value, shrink the connection pool
267
        //size to initial value
268
        success = DBConnectionPool.shrinkConnectionPoolSize();
269
        if (success)
270
        {
271
          //if successfully shrink the pool size to initial value
272
          out.println("DBConnection Pool shrink successfully");
273
        }//if
274
        else
275
        {
276
          out.println("DBConnection pool couldn't shrink successfully");
277
        }
278
       //close out put
279
        out.close();
280
281 798 jones
      // aware of session expiration on every request
282
      } else {
283
284
        HttpSession sess = request.getSession(true);
285
        if (sess.isNew()) {
286
          // session expired or has not been stored b/w user requests
287
          username = "public";
288
          sess.setAttribute("username", username);
289
        } else {
290
          username = (String)sess.getAttribute("username");
291
          password = (String)sess.getAttribute("password");
292 802 bojilova
          groupnames = (String[])sess.getAttribute("groupnames");
293 798 jones
          try {
294
            sess_id = (String)sess.getId();
295
          } catch(IllegalStateException ise) {
296
            System.out.println("error in handleGetOrPost: this shouldn't " +
297
                               "happen: the session should be valid: " +
298
                               ise.getMessage());
299
          }
300
        }
301
      }
302
303 947 tao
       // Now that we know the session is valid, we can delegate the request
304 798 jones
      // to a particular action handler
305
      if(action.equals("query")) {
306 1217 tao
        PrintWriter out = response.getWriter();
307
        handleQuery(out,params,response,username,groupnames);
308
        out.close();
309 798 jones
      } else if(action.equals("squery")) {
310 1217 tao
        PrintWriter out = response.getWriter();
311 798 jones
        if(params.containsKey("query")) {
312 1217 tao
         handleSQuery(out, params,response,username,groupnames);
313
         out.close();
314 798 jones
        } else {
315
          out.println("Illegal action squery without \"query\" parameter");
316 1217 tao
          out.close();
317 798 jones
        }
318 943 tao
      } else if (action.equals("export")) {
319 949 tao
320 1292 tao
        handleExportAction(params, response, username, groupnames, password);
321 798 jones
      } else if (action.equals("read")) {
322 1292 tao
        handleReadAction(params, response, username,password, groupnames);
323 798 jones
      } else if (action.equals("insert") || action.equals("update")) {
324 458 berkley
        PrintWriter out = response.getWriter();
325 798 jones
        if ( (username != null) &&  !username.equals("public") ) {
326 802 bojilova
          handleInsertOrUpdateAction(out,params,response,username,groupnames);
327 798 jones
        } else {
328
          out.println("Permission denied for " + action);
329 1217 tao
        }
330
        out.close();
331 798 jones
      } else if (action.equals("delete")) {
332
        PrintWriter out = response.getWriter();
333
        if ( (username != null) &&  !username.equals("public") ) {
334 802 bojilova
          handleDeleteAction(out, params, response, username, groupnames);
335 798 jones
        } else {
336
          out.println("Permission denied for " + action);
337 1217 tao
        }
338
        out.close();
339 798 jones
      } else if (action.equals("validate")) {
340
        PrintWriter out = response.getWriter();
341 1217 tao
        handleValidateAction(out, params, response);
342
        out.close();
343 798 jones
      } else if (action.equals("getaccesscontrol")) {
344
        PrintWriter out = response.getWriter();
345 802 bojilova
        handleGetAccessControlAction(out,params,response,username,groupnames);
346 1217 tao
        out.close();
347 798 jones
      } else if (action.equals("getprincipals")) {
348
        PrintWriter out = response.getWriter();
349 1217 tao
        handleGetPrincipalsAction(out, username, password);
350
        out.close();
351 798 jones
      } else if (action.equals("getdoctypes")) {
352
        PrintWriter out = response.getWriter();
353 1217 tao
        handleGetDoctypesAction(out, params, response);
354
        out.close();
355 798 jones
      } else if (action.equals("getdtdschema")) {
356
        PrintWriter out = response.getWriter();
357 1217 tao
        handleGetDTDSchemaAction(out, params, response);
358
        out.close();
359 798 jones
      } else if (action.equals("getdataguide")) {
360
        PrintWriter out = response.getWriter();
361 1217 tao
        handleGetDataGuideAction(out, params, response);
362
        out.close();
363 798 jones
      } else if (action.equals("getlastdocid")) {
364
        PrintWriter out = response.getWriter();
365 1217 tao
        handleGetMaxDocidAction(out, params, response);
366
        out.close();
367 1292 tao
      } else if (action.equals("getrevisionanddoctype")) {
368
        PrintWriter out = response.getWriter();
369
        handleGetRevisionAndDocTypeAction(out, params);
370
        out.close();
371 798 jones
      } else if (action.equals("login") || action.equals("logout")) {
372
      } else if (action.equals("protocoltest")) {
373
        String testURL = "metacat://dev.nceas.ucsb.edu/NCEAS.897766.9";
374
        try {
375
          testURL = ((String[])params.get("url"))[0];
376
        } catch (Throwable t) {
377
        }
378
        String phandler = System.getProperty("java.protocol.handler.pkgs");
379
        response.setContentType("text/html");
380
        PrintWriter out = response.getWriter();
381
        out.println("<body bgcolor=\"white\">");
382
        out.println("<p>Handler property: <code>" + phandler + "</code></p>");
383
        out.println("<p>Starting test for:<br>");
384
        out.println("    " + testURL + "</p>");
385
        try {
386
          URL u = new URL(testURL);
387
          out.println("<pre>");
388
          out.println("Protocol: " + u.getProtocol());
389
          out.println("    Host: " + u.getHost());
390
          out.println("    Port: " + u.getPort());
391
          out.println("    Path: " + u.getPath());
392
          out.println("     Ref: " + u.getRef());
393
          String pquery = u.getQuery();
394
          out.println("   Query: " + pquery);
395
          out.println("  Params: ");
396
          if (pquery != null) {
397
            Hashtable qparams = util.parseQuery(u.getQuery());
398
            for (Enumeration en = qparams.keys(); en.hasMoreElements(); ) {
399
              String pname = (String)en.nextElement();
400
              String pvalue = (String)qparams.get(pname);
401
              out.println("    " + pname + ": " + pvalue);
402
            }
403 566 jones
          }
404 798 jones
          out.println("</pre>");
405
          out.println("</body>");
406
          out.close();
407
        } catch (MalformedURLException mue) {
408
          System.out.println("bad url from MetacatServlet.handleGetOrPost");
409
          out.println(mue.getMessage());
410
          mue.printStackTrace(out);
411
          out.close();
412 566 jones
        }
413 798 jones
      } else {
414
        PrintWriter out = response.getWriter();
415
        out.println("<?xml version=\"1.0\"?>");
416
        out.println("<error>");
417
        out.println("Error: action not registered.  Please report this error.");
418
        out.println("</error>");
419 1217 tao
        out.close();
420 566 jones
      }
421 798 jones
422 1217 tao
      //util.closeConnections();
423 798 jones
      // Close the stream to the client
424 1217 tao
      //out.close();
425 46 jones
    }
426
  }
427 355 berkley
428 731 bojilova
  // LOGIN & LOGOUT SECTION
429 50 jones
  /**
430 509 bojilova
   * Handle the login request. Create a new session object.
431 503 bojilova
   * Do user authentication through the session.
432 210 bojilova
   */
433
  private void handleLoginAction(PrintWriter out, Hashtable params,
434
               HttpServletRequest request, HttpServletResponse response) {
435 251 bojilova
436 503 bojilova
    AuthSession sess = null;
437 228 bojilova
    String un = ((String[])params.get("username"))[0];
438
    String pw = ((String[])params.get("password"))[0];
439 297 bojilova
    String action = ((String[])params.get("action"))[0];
440 509 bojilova
    String qformat = ((String[])params.get("qformat"))[0];
441 332 bojilova
442 297 bojilova
    try {
443 509 bojilova
      sess = new AuthSession();
444 297 bojilova
    } catch (Exception e) {
445 675 berkley
      System.out.println("error in MetacatServlet.handleLoginAction: " +
446
                          e.getMessage());
447 297 bojilova
      out.println(e.getMessage());
448 509 bojilova
      return;
449 297 bojilova
    }
450 509 bojilova
    boolean isValid = sess.authenticate(request, un, pw);
451
    // format and transform the output
452 832 jones
    if (qformat.equals("xml")) {
453
      response.setContentType("text/xml");
454
      out.println(sess.getMessage());
455
    } else {
456 1217 tao
457 503 bojilova
      try {
458 1217 tao
459
        DBTransform trans = new DBTransform();
460 509 bojilova
        response.setContentType("text/html");
461 510 bojilova
        trans.transformXMLDocument(sess.getMessage(), "-//NCEAS//login//EN",
462 832 jones
                                   "-//W3C//HTML//EN", qformat, out);
463 1217 tao
464 509 bojilova
      } catch(Exception e) {
465 1217 tao
466
        MetaCatUtil.debugMessage("Error in MetaCatServlet.handleLoginAction: "
467
                                +e.getMessage(), 30);
468 509 bojilova
      }
469
470
    // any output is returned
471 503 bojilova
    }
472 370 berkley
  }
473 509 bojilova
474
  /**
475
   * Handle the logout request. Close the connection.
476
   */
477
  private void handleLogoutAction(PrintWriter out, Hashtable params,
478
               HttpServletRequest request, HttpServletResponse response) {
479
480
    String qformat = ((String[])params.get("qformat"))[0];
481
482
    // close the connection
483
    HttpSession sess = request.getSession(false);
484
    if (sess != null) { sess.invalidate();  }
485
486
    // produce output
487
    StringBuffer output = new StringBuffer();
488
    output.append("<?xml version=\"1.0\"?>");
489 510 bojilova
    output.append("<logout>");
490
    output.append("User logged out");
491
    output.append("</logout>");
492 509 bojilova
493
    //format and transform the output
494 832 jones
    if (qformat.equals("xml")) {
495
      response.setContentType("text/xml");
496
      out.println(output.toString());
497
    } else {
498 1217 tao
499 509 bojilova
      try {
500 1217 tao
501
        DBTransform trans = new DBTransform();
502 509 bojilova
        response.setContentType("text/html");
503 510 bojilova
        trans.transformXMLDocument(output.toString(), "-//NCEAS//login//EN",
504 832 jones
                                   "-//W3C//HTML//EN", qformat, out);
505 1217 tao
506 509 bojilova
      } catch(Exception e) {
507 1217 tao
508
        MetaCatUtil.debugMessage("Error in MetaCatServlet.handleLogoutAction"
509
                                  +e.getMessage(), 30);
510 509 bojilova
      }
511
    }
512
  }
513 731 bojilova
  // END OF LOGIN & LOGOUT SECTION
514 370 berkley
515 731 bojilova
  // SQUERY & QUERY SECTION
516 373 berkley
  /**
517 380 jones
   * Retreive the squery xml, execute it and display it
518
   *
519
   * @param out the output stream to the client
520
   * @param params the Hashtable of parameters that should be included
521
   * in the squery.
522
   * @param response the response object linked to the client
523
   * @param conn the database connection
524
   */
525
  protected void handleSQuery(PrintWriter out, Hashtable params,
526 802 bojilova
                 HttpServletResponse response, String user, String[] groups)
527 373 berkley
  {
528 380 jones
    String xmlquery = ((String[])params.get("query"))[0];
529
    String qformat = ((String[])params.get("qformat"))[0];
530 465 berkley
    String resultdoc = null;
531 1298 tao
    MetaCatUtil.debugMessage("xmlquery: "+xmlquery, 30);
532
    double startTime = System.currentTimeMillis()/1000;
533 802 bojilova
    Hashtable doclist = runQuery(xmlquery, user, groups);
534 1298 tao
    double docListTime = System.currentTimeMillis()/1000;
535
    MetaCatUtil.debugMessage("Time for getting doc list: "
536
                                            +(docListTime-startTime), 30);
537
538 465 berkley
    resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
539 1298 tao
    double toStringTime = System.currentTimeMillis()/1000;
540
    MetaCatUtil.debugMessage("Time to create xml string: "
541
                              +(toStringTime-docListTime), 30);
542
    //format and transform the results
543
    double outPutTime = 0;
544 832 jones
    if(qformat.equals("xml")) {
545 380 jones
      response.setContentType("text/xml");
546
      out.println(resultdoc);
547 1298 tao
      outPutTime = System.currentTimeMillis()/1000;
548
      MetaCatUtil.debugMessage("Output time: "+(outPutTime-toStringTime), 30);
549 380 jones
    } else {
550 832 jones
      transformResultset(resultdoc, response, out, qformat);
551 1298 tao
      outPutTime = System.currentTimeMillis()/1000;
552
      MetaCatUtil.debugMessage("Output time: "+(outPutTime-toStringTime), 30);
553 380 jones
    }
554 341 berkley
  }
555 1298 tao
556 341 berkley
   /**
557 380 jones
    * Create the xml query, execute it and display the results.
558
    *
559
    * @param out the output stream to the client
560
    * @param params the Hashtable of parameters that should be included
561 370 berkley
    * in the squery.
562 380 jones
    * @param response the response object linked to the client
563 370 berkley
    */
564 375 berkley
  protected void handleQuery(PrintWriter out, Hashtable params,
565 802 bojilova
                 HttpServletResponse response, String user, String[] groups)
566 341 berkley
  {
567 370 berkley
    //create the query and run it
568 373 berkley
    String xmlquery = DBQuery.createSQuery(params);
569 802 bojilova
    Hashtable doclist = runQuery(xmlquery, user, groups);
570 465 berkley
    String qformat = ((String[])params.get("qformat"))[0];
571
    String resultdoc = null;
572
573
    resultdoc = createResultDocument(doclist, transformQuery(params));
574 425 bojilova
575 370 berkley
    //format and transform the results
576 832 jones
    if(qformat.equals("xml")) {
577 370 berkley
      response.setContentType("text/xml");
578
      out.println(resultdoc);
579 443 berkley
    } else {
580 832 jones
      transformResultset(resultdoc, response, out, qformat);
581 370 berkley
    }
582 341 berkley
  }
583
584
  /**
585 384 berkley
   * Removes the <?xml version="x"?> tag from the beginning of xmlquery
586
   * so it can properly be placed in the <query> tag of the resultset.
587
   * This method is overwritable so that other applications can customize
588
   * the structure of what is in the <query> tag.
589
   *
590
   * @param xmlquery is the query to remove the <?xml version="x"?> tag from.
591
   */
592
  protected String transformQuery(Hashtable params)
593
  {
594
    //DBQuery.createSQuery is a re-calling of a previously called
595
    //function but it is necessary
596
    //so that overriding methods have access to the params hashtable
597
    String xmlquery = DBQuery.createSQuery(params);
598
    //the <?xml version="1.0"?> tag is the first 22 characters of the
599
    xmlquery = xmlquery.trim();
600
    int index = xmlquery.indexOf("?>");
601
    return xmlquery.substring(index + 2, xmlquery.length());
602
  }
603
604
  /**
605 443 berkley
   * removes the <?xml version="1.0"?> tag from the beginning.  This takes a
606
   * string as a param instead of a hashtable.
607
   *
608
   * @param xmlquery a string representing a query.
609
   */
610
  protected String transformQuery(String xmlquery)
611
  {
612
    xmlquery = xmlquery.trim();
613
    int index = xmlquery.indexOf("?>");
614
    return xmlquery.substring(index + 2, xmlquery.length());
615
  }
616
617
  /**
618 380 jones
   * Run the query and return a hashtable of results.
619
   *
620
   * @param xmlquery the query to run
621
   */
622 802 bojilova
  private Hashtable runQuery(String xmlquery, String user, String[] groups)
623 341 berkley
  {
624
    Hashtable doclist=null;
625 1217 tao
626 341 berkley
    try
627
    {
628 1217 tao
629
      DBQuery queryobj = new DBQuery(saxparser);
630 802 bojilova
      doclist = queryobj.findDocuments(new StringReader(xmlquery),user,groups);
631 1217 tao
632 441 bojilova
      return doclist;
633 341 berkley
    }
634
    catch (Exception e)
635
    {
636 1217 tao
637
      MetaCatUtil.debugMessage("Error in MetacatServlet.runQuery: "
638
                                                      + e.getMessage(), 30);
639 341 berkley
      doclist = null;
640
      return doclist;
641
    }
642
  }
643
644 380 jones
  /**
645 370 berkley
   * Transorms an xml resultset document to html and sends it to the browser
646 380 jones
   *
647 370 berkley
   * @param resultdoc the string representation of the document that needs
648
   * to be transformed.
649
   * @param response the HttpServletResponse object bound to the client.
650
   * @param out the output stream to the client
651 832 jones
   * @param qformat the name of the style-set to use for transformations
652 375 berkley
   */
653
  protected void transformResultset(String resultdoc,
654 380 jones
                                    HttpServletResponse response,
655 832 jones
                                    PrintWriter out, String qformat)
656 370 berkley
  {
657 1217 tao
658 380 jones
    try {
659 1217 tao
660
      DBTransform trans = new DBTransform();
661 370 berkley
      response.setContentType("text/html");
662
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN",
663 832 jones
                                 "-//W3C//HTML//EN", qformat, out);
664 1217 tao
665 382 berkley
    }
666
    catch(Exception e)
667
    {
668 1217 tao
669
      MetaCatUtil.debugMessage("Error in MetaCatServlet.transformResultset:"
670
                                +e.getMessage(), 30);
671 370 berkley
    }
672
  }
673
674 355 berkley
  /**
675
   * Transforms a hashtable of documents to an xml or html result.
676 380 jones
   *
677 355 berkley
   * @param doclist- the hashtable to transform
678 744 jones
   * @param xmlquery- the query that returned the doclist result
679 355 berkley
   */
680 375 berkley
  protected String createResultDocument(Hashtable doclist, String xmlquery)
681 341 berkley
  {
682
    // Create a buffer to hold the xml result
683
    StringBuffer resultset = new StringBuffer();
684
685 382 berkley
    // Print the resulting root nodes
686 341 berkley
    String docid = null;
687
    String document = null;
688
    resultset.append("<?xml version=\"1.0\"?>\n");
689
    resultset.append("<resultset>\n");
690 465 berkley
691 384 berkley
    resultset.append("  <query>" + xmlquery + "</query>");
692 478 berkley
693
    if(doclist != null)
694 341 berkley
    {
695 478 berkley
      Enumeration doclistkeys = doclist.keys();
696
      while (doclistkeys.hasMoreElements())
697
      {
698
        docid = (String)doclistkeys.nextElement();
699
        document = (String)doclist.get(docid);
700
        resultset.append("  <document>" + document + "</document>");
701
      }
702
    }
703
704 341 berkley
    resultset.append("</resultset>");
705 370 berkley
    return resultset.toString();
706 341 berkley
  }
707 731 bojilova
  // END OF SQUERY & QUERY SECTION
708 437 berkley
709 943 tao
 //Exoport section
710
 /**
711
   * Handle the "export" request of data package from Metacat in zip format
712
   * @param params the Hashtable of HTTP request parameters
713
   * @param response the HTTP response object linked to the client
714
   * @param user the username sent the request
715
   * @param groups the user's groupnames
716
   */
717 1292 tao
  private void handleExportAction(Hashtable params,
718
    HttpServletResponse response, String user, String[] groups, String passWord)
719 943 tao
  {
720 1292 tao
    // Output stream
721 943 tao
    ServletOutputStream out = null;
722 1292 tao
    // Zip output stream
723 943 tao
    ZipOutputStream zOut = null;
724
    DocumentImpl docImpls=null;
725
    DBQuery queryObj=null;
726 1217 tao
727 943 tao
    String[] docs = new String[10];
728
    String docId = "";
729
730
    try
731
    {
732
      // read the params
733 1292 tao
      if (params.containsKey("docid"))
734
      {
735 943 tao
        docs = (String[])params.get("docid");
736 1292 tao
      }//if
737
      // Create a DBuery to handle export
738
      queryObj = new DBQuery(saxparser);
739
      // Get the docid
740 943 tao
      docId=docs[0];
741 1292 tao
      // Make sure the client specify docid
742
      if (docId == null || docId.equals(""))
743
      {
744
        response.setContentType("text/xml"); //MIME type
745
        // Get a printwriter
746
        PrintWriter pw = response.getWriter();
747
        // Send back message
748
        pw.println("<?xml version=\"1.0\"?>");
749
        pw.println("<error>");
750
        pw.println("You didn't specify requested docid");
751
        pw.println("</error>");
752
        // Close printwriter
753
        pw.close();
754
        return;
755
      }//if
756
      // Get output stream
757 943 tao
      out = response.getOutputStream();
758
      response.setContentType("application/zip"); //MIME type
759
      zOut = new ZipOutputStream(out);
760 1292 tao
      zOut =queryObj.getZippedPackage(docId, out, user, groups, passWord);
761 943 tao
      zOut.finish(); //terminate the zip file
762
      zOut.close();  //close the zip stream
763 1056 tao
764 1292 tao
    }//try
765 943 tao
    catch (Exception e)
766
    {
767
      try
768
      {
769
        response.setContentType("text/xml"); //MIME type
770 1292 tao
        // Send error message back
771 943 tao
        if (out != null)
772
        {
773
            PrintWriter pw = new PrintWriter(out);
774
            pw.println("<?xml version=\"1.0\"?>");
775
            pw.println("<error>");
776
            pw.println(e.getMessage());
777
            pw.println("</error>");
778 1292 tao
            // Close printwriter
779 943 tao
            pw.close();
780 1292 tao
            // Close output stream
781
            out.close();
782
        }//if
783
        // Close zip output stream
784 943 tao
        if ( zOut != null )
785
        {
786
          zOut.close();
787 1292 tao
        }//if
788
      }//try
789 943 tao
      catch (IOException ioe)
790
      {
791 1217 tao
        MetaCatUtil.debugMessage("Problem with the servlet output " +
792 1292 tao
                           "in MetacatServlet.handleExportAction: " +
793 1217 tao
                           ioe.getMessage(), 30);
794 1292 tao
      }//catch
795 943 tao
796 1292 tao
      MetaCatUtil.debugMessage("Error in MetacatServlet.handleExportAction: " +
797 1217 tao
                         e.getMessage(), 30);
798 1292 tao
      e.printStackTrace(System.out);
799 943 tao
800
    }//catch
801 1292 tao
802 943 tao
  }//handleExportAction
803
804 731 bojilova
  // READ SECTION
805
  /**
806
   * Handle the "read" request of metadata/data files from Metacat
807
   * or any files from Internet;
808
   * transformed metadata XML document into HTML presentation if requested;
809
   * zip files when more than one were requested.
810
   *
811
   * @param params the Hashtable of HTTP request parameters
812
   * @param response the HTTP response object linked to the client
813
   * @param user the username sent the request
814 802 bojilova
   * @param groups the user's groupnames
815 437 berkley
   */
816 731 bojilova
  private void handleReadAction(Hashtable params, HttpServletResponse response,
817 1292 tao
                                String user, String passWord, String[] groups)
818 437 berkley
  {
819 731 bojilova
    ServletOutputStream out = null;
820
    ZipOutputStream zout = null;
821 1292 tao
    PrintWriter pw = null;
822
    boolean zip = false;
823 731 bojilova
824
    try {
825
      String[] docs = new String[0];
826
      String docid = "";
827
      String qformat = "";
828
      String abstrpath = null;
829 1292 tao
830 731 bojilova
      // read the params
831
      if (params.containsKey("docid")) {
832
        docs = (String[])params.get("docid");
833 437 berkley
      }
834 731 bojilova
      if (params.containsKey("qformat")) {
835
        qformat = ((String[])params.get("qformat"))[0];
836 437 berkley
      }
837 731 bojilova
      if (params.containsKey("abstractpath")) {
838
        abstrpath = ((String[])params.get("abstractpath"))[0];
839 738 bojilova
        if ( !abstrpath.equals("") && (abstrpath != null) ) {
840
          viewAbstract(response, abstrpath, docs[0]);
841
          return;
842
        }
843 437 berkley
      }
844 731 bojilova
      if ( (docs.length > 1) || qformat.equals("zip") ) {
845
        zip = true;
846
        out = response.getOutputStream();
847
        response.setContentType("application/zip"); //MIME type
848
        zout = new ZipOutputStream(out);
849
      }
850
      // go through the list of docs to read
851
      for (int i=0; i < docs.length; i++ ) {
852
        try {
853
854
          URL murl = new URL(docs[i]);
855
          Hashtable murlQueryStr = util.parseQuery(murl.getQuery());
856
          // case docid="http://.../?docid=aaa"
857
          // or docid="metacat://.../?docid=bbb"
858
          if (murlQueryStr.containsKey("docid")) {
859
            // get only docid, eliminate the rest
860
            docid = (String)murlQueryStr.get("docid");
861
            if ( zip ) {
862 947 tao
              addDocToZip(docid, zout, user, groups);
863 731 bojilova
            } else {
864
              readFromMetacat(response, docid, qformat, abstrpath,
865 802 bojilova
                              user, groups, zip, zout);
866 731 bojilova
            }
867
868
          // case docid="http://.../filename"
869
          } else {
870
            docid = docs[i];
871
            if ( zip ) {
872 947 tao
              addDocToZip(docid, zout, user, groups);
873 731 bojilova
            } else {
874
              readFromURLConnection(response, docid);
875
            }
876
          }
877
878
        // case docid="ccc"
879
        } catch (MalformedURLException mue) {
880
          docid = docs[i];
881
          if ( zip ) {
882 947 tao
            addDocToZip(docid, zout, user, groups);
883 731 bojilova
          } else {
884
            readFromMetacat(response, docid, qformat, abstrpath,
885 802 bojilova
                            user, groups, zip, zout);
886 731 bojilova
          }
887
        }
888
889
      } /* end for */
890
891
      if ( zip ) {
892
        zout.finish(); //terminate the zip file
893
        zout.close();  //close the zip stream
894
      }
895
896 947 tao
897 1292 tao
    }
898
    // To handle doc not found exception
899
    catch (McdbDocNotFoundException notFoundE)
900
    {
901
      // the docid which didn't be found
902
      String notFoundDocId = notFoundE.getUnfoundDocId();
903
      String notFoundRevision = notFoundE.getUnfoundRevision();
904
      MetaCatUtil.debugMessage("Missed id: "+ notFoundDocId, 30);
905
      MetaCatUtil.debugMessage("Missed rev: "+ notFoundRevision, 30);
906
      try
907
      {
908
        // read docid from remote server
909
        readFromRemoteMetaCat(response, notFoundDocId, notFoundRevision,
910
                                              user, passWord, out, zip, zout);
911
        // Close zout outputstream
912
        if ( zout != null)
913
        {
914
          zout.close();
915
        }
916
        // close output stream
917
        if (out != null)
918
        {
919
          out.close();
920
        }
921
922
      }//try
923
      catch ( Exception exc)
924
      {
925
        MetaCatUtil.debugMessage("Erorr in MetacatServlet.hanldReadAction: "+
926
                                      exc.getMessage(), 30);
927
        try
928
        {
929
          if (out != null)
930
          {
931
            response.setContentType("text/xml");
932
            // Send back error message by printWriter
933
            pw = new PrintWriter(out);
934
            pw.println("<?xml version=\"1.0\"?>");
935
            pw.println("<error>");
936
            pw.println(notFoundE.getMessage());
937
            pw.println("</error>");
938
            pw.close();
939
            out.close();
940
941
          }
942
          else
943
          {
944
           response.setContentType("text/xml"); //MIME type
945
           // Send back error message if out = null
946
           if (pw == null)
947
           {
948
             // If pw is null, open the respnose
949
            pw = response.getWriter();
950
           }
951
           pw.println("<?xml version=\"1.0\"?>");
952
           pw.println("<error>");
953
           pw.println(notFoundE.getMessage());
954
           pw.println("</error>");
955
           pw.close();
956
        }
957
        // close zout
958
        if ( zout != null )
959
        {
960
          zout.close();
961
        }
962
        }//try
963
        catch (IOException ie)
964
        {
965
          MetaCatUtil.debugMessage("Problem with the servlet output " +
966
                           "in MetacatServlet.handleReadAction: " +
967
                           ie.getMessage(), 30);
968
        }//cathch
969
      }//catch
970
    }// catch McdbDocNotFoundException
971
    catch (Exception e)
972
    {
973 731 bojilova
      try {
974 1292 tao
975 845 jones
        if (out != null) {
976 1292 tao
            response.setContentType("text/xml"); //MIME type
977
            pw = new PrintWriter(out);
978 845 jones
            pw.println("<?xml version=\"1.0\"?>");
979
            pw.println("<error>");
980
            pw.println(e.getMessage());
981
            pw.println("</error>");
982
            pw.close();
983 1292 tao
            out.close();
984 845 jones
        }
985 1292 tao
        else
986
        {
987
           response.setContentType("text/xml"); //MIME type
988
           // Send back error message if out = null
989
           if ( pw == null)
990
           {
991
            pw = response.getWriter();
992
           }
993
           pw.println("<?xml version=\"1.0\"?>");
994
           pw.println("<error>");
995
           pw.println(e.getMessage());
996
           pw.println("</error>");
997
           pw.close();
998
999
        }
1000
        // Close zip output stream
1001 731 bojilova
        if ( zout != null ) { zout.close(); }
1002 1292 tao
1003 731 bojilova
      } catch (IOException ioe) {
1004 1292 tao
        MetaCatUtil.debugMessage("Problem with the servlet output " +
1005 731 bojilova
                           "in MetacatServlet.handleReadAction: " +
1006 1292 tao
                           ioe.getMessage(), 30);
1007 731 bojilova
        ioe.printStackTrace(System.out);
1008
1009
      }
1010
1011
      System.out.println("Error in MetacatServlet.handleReadAction: " +
1012 675 berkley
                         e.getMessage());
1013 731 bojilova
      e.printStackTrace(System.out);
1014 437 berkley
    }
1015
1016
  }
1017 731 bojilova
1018
  // read metadata or data from Metacat
1019
  private void readFromMetacat(HttpServletResponse response, String docid,
1020
                               String qformat, String abstrpath, String user,
1021 943 tao
                             String[] groups, boolean zip, ZipOutputStream zout)
1022 731 bojilova
               throws ClassNotFoundException, IOException, SQLException,
1023
                      McdbException, Exception
1024 453 berkley
  {
1025 1217 tao
1026 731 bojilova
    try {
1027 1217 tao
1028 453 berkley
1029 1217 tao
      DocumentImpl doc = new DocumentImpl(docid);
1030
1031 947 tao
      //check the permission for read
1032 1217 tao
      if (!doc.hasReadPermission(user, groups, docid))
1033 947 tao
      {
1034
        Exception e = new Exception("User " + user + " does not have permission"
1035
                       +" to read the document with the docid " + docid);
1036 1217 tao
1037 947 tao
        throw e;
1038
      }
1039
1040 731 bojilova
      if ( doc.getRootNodeID() == 0 ) {
1041
        // this is data file
1042
        String filepath = util.getOption("datafilepath");
1043
        if(!filepath.endsWith("/")) {
1044
          filepath += "/";
1045
        }
1046 1292 tao
        String filename = filepath + docid;
1047
        FileInputStream fin = null;
1048
        fin = new FileInputStream(filename);
1049
1050
        //MIME type
1051 731 bojilova
        String contentType = getServletContext().getMimeType(filename);
1052
        if (contentType == null) {
1053
          if (filename.endsWith(".xml")) {
1054
            contentType="text/xml";
1055
          } else if (filename.endsWith(".css")) {
1056
            contentType="text/css";
1057
          } else if (filename.endsWith(".dtd")) {
1058
            contentType="text/plain";
1059
          } else if (filename.endsWith(".xsd")) {
1060 733 bojilova
            contentType="text/xml";
1061 731 bojilova
          } else if (filename.endsWith("/")) {
1062 733 bojilova
            contentType="text/html";
1063 731 bojilova
          } else {
1064 733 bojilova
            File f = new File(filename);
1065
            if ( f.isDirectory() ) {
1066
              contentType="text/html";
1067
            } else {
1068
              contentType="application/octet-stream";
1069
            }
1070 453 berkley
          }
1071
        }
1072 731 bojilova
        response.setContentType(contentType);
1073 733 bojilova
        // if we decide to use "application/octet-stream" for all data returns
1074
        // response.setContentType("application/octet-stream");
1075 1292 tao
1076 731 bojilova
        try {
1077 1292 tao
1078
          ServletOutputStream out = response.getOutputStream();
1079 731 bojilova
          byte[] buf = new byte[4 * 1024]; // 4K buffer
1080
          int b = fin.read(buf);
1081
          while (b != -1) {
1082
            out.write(buf, 0, b);
1083
            b = fin.read(buf);
1084 453 berkley
          }
1085 731 bojilova
        } finally {
1086
          if (fin != null) fin.close();
1087 453 berkley
        }
1088 731 bojilova
1089
      } else {
1090
        // this is metadata doc
1091 832 jones
        if ( qformat.equals("xml") ) {
1092 1217 tao
1093 832 jones
          // set content type first
1094
          response.setContentType("text/xml");   //MIME type
1095
          PrintWriter out = response.getWriter();
1096
          doc.toXml(out);
1097
        } else {
1098 731 bojilova
          response.setContentType("text/html");  //MIME type
1099
          PrintWriter out = response.getWriter();
1100
1101
          // Look up the document type
1102
          String doctype = doc.getDoctype();
1103
          // Transform the document to the new doctype
1104 1217 tao
          DBTransform dbt = new DBTransform();
1105 731 bojilova
          dbt.transformXMLDocument(doc.toString(),
1106 832 jones
                                   doctype,"-//W3C//HTML//EN", qformat, out);
1107 731 bojilova
        }
1108
1109 453 berkley
      }
1110 1292 tao
    }
1111
    catch (Exception except)
1112
    {
1113 1217 tao
      throw except;
1114
1115 731 bojilova
    }
1116
1117
  }
1118 453 berkley
1119 731 bojilova
  // read data from URLConnection
1120
  private void readFromURLConnection(HttpServletResponse response, String docid)
1121
               throws IOException, MalformedURLException
1122 566 jones
  {
1123 731 bojilova
    ServletOutputStream out = response.getOutputStream();
1124
    String contentType = getServletContext().getMimeType(docid); //MIME type
1125
    if (contentType == null) {
1126
      if (docid.endsWith(".xml")) {
1127
        contentType="text/xml";
1128
      } else if (docid.endsWith(".css")) {
1129
        contentType="text/css";
1130
      } else if (docid.endsWith(".dtd")) {
1131
        contentType="text/plain";
1132
      } else if (docid.endsWith(".xsd")) {
1133 733 bojilova
        contentType="text/xml";
1134 731 bojilova
      } else if (docid.endsWith("/")) {
1135 733 bojilova
        contentType="text/html";
1136 731 bojilova
      } else {
1137 733 bojilova
        File f = new File(docid);
1138
        if ( f.isDirectory() ) {
1139
          contentType="text/html";
1140
        } else {
1141
          contentType="application/octet-stream";
1142
        }
1143 731 bojilova
      }
1144
    }
1145
    response.setContentType(contentType);
1146 733 bojilova
    // if we decide to use "application/octet-stream" for all data returns
1147
    // response.setContentType("application/octet-stream");
1148 731 bojilova
1149
    // this is http url
1150
    URL url = new URL(docid);
1151
    BufferedInputStream bis = null;
1152 566 jones
    try {
1153 731 bojilova
      bis = new BufferedInputStream(url.openStream());
1154
      byte[] buf = new byte[4 * 1024]; // 4K buffer
1155
      int b = bis.read(buf);
1156
      while (b != -1) {
1157
        out.write(buf, 0, b);
1158
        b = bis.read(buf);
1159 636 berkley
      }
1160 731 bojilova
    } finally {
1161
      if (bis != null) bis.close();
1162 566 jones
    }
1163 731 bojilova
1164 566 jones
  }
1165 636 berkley
1166 731 bojilova
  // read file/doc and write to ZipOutputStream
1167 947 tao
  private void addDocToZip(String docid, ZipOutputStream zout,
1168
                              String user, String[] groups)
1169 731 bojilova
               throws ClassNotFoundException, IOException, SQLException,
1170
                      McdbException, Exception
1171 636 berkley
  {
1172 731 bojilova
    byte[] bytestring = null;
1173
    ZipEntry zentry = null;
1174
1175
    try {
1176
      URL url = new URL(docid);
1177
1178
      // this http url; read from URLConnection; add to zip
1179
      zentry = new ZipEntry(docid);
1180
      zout.putNextEntry(zentry);
1181
      BufferedInputStream bis = null;
1182
      try {
1183
        bis = new BufferedInputStream(url.openStream());
1184
        byte[] buf = new byte[4 * 1024]; // 4K buffer
1185
        int b = bis.read(buf);
1186
        while(b != -1) {
1187
          zout.write(buf, 0, b);
1188
          b = bis.read(buf);
1189
        }
1190
      } finally {
1191
        if (bis != null) bis.close();
1192 636 berkley
      }
1193 731 bojilova
      zout.closeEntry();
1194
1195
    } catch (MalformedURLException mue) {
1196 661 berkley
1197 731 bojilova
      // this is metacat doc (data file or metadata doc)
1198 1217 tao
1199 731 bojilova
      try {
1200 1217 tao
1201
        DocumentImpl doc = new DocumentImpl(docid);
1202 947 tao
1203
        //check the permission for read
1204 1217 tao
        if (!doc.hasReadPermission(user, groups, docid))
1205 947 tao
        {
1206
          Exception e = new Exception("User " + user + " does not have "
1207
                    +"permission to read the document with the docid " + docid);
1208 1217 tao
1209 947 tao
          throw e;
1210
        }
1211
1212 731 bojilova
        if ( doc.getRootNodeID() == 0 ) {
1213
          // this is data file; add file to zip
1214
          String filepath = util.getOption("datafilepath");
1215
          if(!filepath.endsWith("/")) {
1216
            filepath += "/";
1217
          }
1218 1292 tao
          String filename = filepath + docid;
1219 731 bojilova
          FileInputStream fin = null;
1220 1292 tao
          fin = new FileInputStream(filename);
1221 731 bojilova
          try {
1222 1292 tao
1223
            zentry = new ZipEntry(docid);
1224
            zout.putNextEntry(zentry);
1225 731 bojilova
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1226
            int b = fin.read(buf);
1227
            while (b != -1) {
1228
              zout.write(buf, 0, b);
1229
              b = fin.read(buf);
1230
            }
1231
          } finally {
1232
            if (fin != null) fin.close();
1233
          }
1234
          zout.closeEntry();
1235
1236
        } else {
1237
          // this is metadata doc; add doc to zip
1238
          bytestring = doc.toString().getBytes();
1239
          zentry = new ZipEntry(docid + ".xml");
1240
          zentry.setSize(bytestring.length);
1241
          zout.putNextEntry(zentry);
1242
          zout.write(bytestring, 0, bytestring.length);
1243
          zout.closeEntry();
1244 636 berkley
        }
1245 1217 tao
      } catch (Exception except) {
1246
        throw except;
1247
1248 636 berkley
      }
1249
1250
    }
1251 731 bojilova
1252 636 berkley
  }
1253 731 bojilova
1254
  // view abstract within document
1255
  private void viewAbstract(HttpServletResponse response,
1256
                            String abstractpath, String docid)
1257
               throws ClassNotFoundException, IOException, SQLException,
1258
                      McdbException, Exception
1259
  {
1260 1217 tao
1261
    PrintWriter out =null;
1262 102 jones
    try {
1263 1217 tao
1264 731 bojilova
      response.setContentType("text/html");  //MIME type
1265 1217 tao
      out = response.getWriter();
1266
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid);
1267 731 bojilova
      out.println("<html><head><title>Abstract</title></head>");
1268
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
1269
      for (int i=0; i<abstracts.length; i++) {
1270
        out.println("<p>" + (String)abstracts[i] + "</p>");
1271
      }
1272
      out.println("</body></html>");
1273 85 jones
1274 1217 tao
    } catch (Exception e) {
1275
       out.println("<?xml version=\"1.0\"?>");
1276
       out.println("<error>");
1277
       out.println(e.getMessage());
1278
       out.println("</error>");
1279
1280
1281 731 bojilova
    }
1282 49 jones
  }
1283 1292 tao
  /**
1284
   * If metacat couldn't find a data file or document locally, it will read this
1285
   * docid from its home server. This is for the replication feature
1286
   */
1287
  private void readFromRemoteMetaCat(HttpServletResponse response, String docid,
1288
                     String rev, String user, String password,
1289
                     ServletOutputStream out, boolean zip, ZipOutputStream zout)
1290
                        throws Exception
1291
 {
1292
   // Create a object of RemoteDocument, "" is for zipEntryPath
1293
   RemoteDocument remoteDoc =
1294
                        new RemoteDocument (docid, rev,user, password, "");
1295 1293 tao
   String docType = remoteDoc.getDocType();
1296
   // Only read data file
1297
   if (docType.equals("BIN"))
1298 1292 tao
   {
1299 1293 tao
    // If it is zip format
1300
    if (zip)
1301
    {
1302
      remoteDoc.readDocumentFromRemoteServerByZip(zout);
1303
    }//if
1304
    else
1305
    {
1306
      if (out == null)
1307
      {
1308
        out = response.getOutputStream();
1309
      }//if
1310
      response.setContentType("application/octet-stream");
1311
      remoteDoc.readDocumentFromRemoteServer(out);
1312
    }//else (not zip)
1313
   }//if doctype=bin
1314 1292 tao
   else
1315
   {
1316 1293 tao
     throw new Exception("Docid: "+docid+"."+rev+" couldn't find");
1317
   }//else
1318 1292 tao
 }//readFromRemoteMetaCat
1319
1320 731 bojilova
  // END OF READ SECTION
1321
1322
  // INSERT/UPDATE SECTION
1323 55 jones
  /**
1324
   * Handle the database putdocument request and write an XML document
1325
   * to the database connection
1326
   */
1327 382 berkley
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params,
1328 802 bojilova
               HttpServletResponse response, String user, String[] groups) {
1329 59 jones
1330 1217 tao
    DBConnection dbConn = null;
1331
    int serialNumber = -1;
1332 309 bojilova
1333 204 jones
    try {
1334
      // Get the document indicated
1335
      String[] doctext = (String[])params.get("doctext");
1336 557 bojilova
1337 680 bojilova
      String pub = null;
1338
      if (params.containsKey("public")) {
1339
        pub = ((String[])params.get("public"))[0];
1340 557 bojilova
      }
1341 680 bojilova
1342 598 bojilova
      StringReader dtd = null;
1343 680 bojilova
      if (params.containsKey("dtdtext")) {
1344 598 bojilova
        String[] dtdtext = (String[])params.get("dtdtext");
1345
        try {
1346 619 bojilova
          if ( !dtdtext[0].equals("") ) {
1347
            dtd = new StringReader(dtdtext[0]);
1348
          }
1349 598 bojilova
        } catch (NullPointerException npe) {}
1350
      }
1351 557 bojilova
1352 204 jones
      StringReader xml = null;
1353 695 bojilova
      boolean validate = false;
1354 204 jones
      try {
1355 695 bojilova
        // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ... >
1356
        // in order to decide whether to use validation parser
1357
        validate = validateXML(doctext[0]);
1358 204 jones
        xml = new StringReader(doctext[0]);
1359 59 jones
1360 204 jones
        String[] action = (String[])params.get("action");
1361
        String[] docid = (String[])params.get("docid");
1362
        String newdocid = null;
1363 203 jones
1364 204 jones
        String doAction = null;
1365
        if (action[0].equals("insert")) {
1366
          doAction = "INSERT";
1367
        } else if (action[0].equals("update")) {
1368
          doAction = "UPDATE";
1369
        }
1370 1217 tao
1371
        try
1372
        {
1373 680 bojilova
          // get a connection from the pool
1374 1217 tao
          dbConn=DBConnectionPool.
1375
                  getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1376
          serialNumber=dbConn.getCheckOutSerialNumber();
1377
1378 1292 tao
1379 680 bojilova
          // write the document to the database
1380 1217 tao
          try
1381
          {
1382 680 bojilova
            String accNumber = docid[0];
1383 1292 tao
            MetaCatUtil.debugMessage(""+ doAction + " " + accNumber +"...", 10);
1384 1217 tao
            if (accNumber.equals(""))
1385
            {
1386 680 bojilova
              accNumber = null;
1387 1217 tao
            }//if
1388
            newdocid = DocumentImpl.write(dbConn, xml, pub, dtd, doAction,
1389 802 bojilova
                                          accNumber, user, groups, validate);
1390 1217 tao
1391
          }//try
1392
          catch (NullPointerException npe)
1393
          {
1394
            newdocid = DocumentImpl.write(dbConn, xml, pub, dtd, doAction,
1395 802 bojilova
                                          null, user, groups, validate);
1396 1217 tao
          }//catch
1397
        }//try
1398
        finally
1399
        {
1400
          // Return db connection
1401
          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1402 309 bojilova
        }
1403
1404 204 jones
        // set content type and other response header fields first
1405
        response.setContentType("text/xml");
1406
        out.println("<?xml version=\"1.0\"?>");
1407
        out.println("<success>");
1408
        out.println("<docid>" + newdocid + "</docid>");
1409
        out.println("</success>");
1410
1411 203 jones
      } catch (NullPointerException npe) {
1412 204 jones
        response.setContentType("text/xml");
1413
        out.println("<?xml version=\"1.0\"?>");
1414
        out.println("<error>");
1415
        out.println(npe.getMessage());
1416
        out.println("</error>");
1417 55 jones
      }
1418 204 jones
    } catch (Exception e) {
1419
      response.setContentType("text/xml");
1420
      out.println("<?xml version=\"1.0\"?>");
1421
      out.println("<error>");
1422
      out.println(e.getMessage());
1423
      if (e instanceof SAXException) {
1424
        Exception e2 = ((SAXException)e).getException();
1425
        out.println("<error>");
1426 780 berkley
        try
1427
        {
1428
          out.println(e2.getMessage());
1429
        }
1430
        catch(NullPointerException npe)
1431
        {
1432
          out.println(e.getMessage());
1433
        }
1434 204 jones
        out.println("</error>");
1435
      }
1436
      //e.printStackTrace(out);
1437
      out.println("</error>");
1438 203 jones
    }
1439 55 jones
  }
1440 203 jones
1441
  /**
1442 695 bojilova
   * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... >
1443
   * in order to decide whether to use validation parser
1444
   */
1445
  private static boolean validateXML(String xmltext) throws IOException {
1446
1447
    StringReader xmlreader = new StringReader(xmltext);
1448
    StringBuffer cbuff = new StringBuffer();
1449
    java.util.Stack st = new java.util.Stack();
1450
    boolean validate = false;
1451
    int c;
1452
    int inx;
1453
1454
    // read from the stream until find the keywords
1455
    while ( (st.empty() || st.size()<4) && ((c = xmlreader.read()) != -1) ) {
1456
      cbuff.append((char)c);
1457
1458
      // "<!DOCTYPE" keyword is found; put it in the stack
1459
      if ( (inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1 ) {
1460
        cbuff = new StringBuffer();
1461
        st.push("<!DOCTYPE");
1462
      }
1463
      // "PUBLIC" keyword is found; put it in the stack
1464
      if ( (inx = cbuff.toString().indexOf("PUBLIC")) != -1 ) {
1465
        cbuff = new StringBuffer();
1466
        st.push("PUBLIC");
1467
      }
1468
      // "SYSTEM" keyword is found; put it in the stack
1469
      if ( (inx = cbuff.toString().indexOf("SYSTEM")) != -1 ) {
1470
        cbuff = new StringBuffer();
1471
        st.push("SYSTEM");
1472
      }
1473
      // ">" character is found; put it in the stack
1474
      // ">" is found twice: fisrt from <?xml ...?>
1475
      // and second from <!DOCTYPE ... >
1476
      if ( (inx = cbuff.toString().indexOf(">")) != -1 ) {
1477
        cbuff = new StringBuffer();
1478
        st.push(">");
1479
      }
1480
    }
1481
1482
    // close the stream
1483
    xmlreader.close();
1484
1485
    // check the stack whether it contains the keywords:
1486
    // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1487
    if ( st.size() == 4 ) {
1488
      if ( ((String)st.pop()).equals(">") &&
1489
           ( ((String)st.peek()).equals("PUBLIC") |
1490
             ((String)st.pop()).equals("SYSTEM") ) &&
1491
           ((String)st.pop()).equals("<!DOCTYPE") )  {
1492
        validate = true;
1493
      }
1494
    }
1495
1496
System.out.println("Validation is " + validate);
1497
    return validate;
1498
  }
1499 731 bojilova
  // END OF INSERT/UPDATE SECTION
1500 695 bojilova
1501 731 bojilova
  // DELETE SECTION
1502 695 bojilova
  /**
1503 203 jones
   * Handle the database delete request and delete an XML document
1504
   * from the database connection
1505
   */
1506
  private void handleDeleteAction(PrintWriter out, Hashtable params,
1507 802 bojilova
               HttpServletResponse response, String user, String[] groups) {
1508 203 jones
1509
    String[] docid = (String[])params.get("docid");
1510 1217 tao
1511 203 jones
    // delete the document from the database
1512
    try {
1513 1217 tao
1514 203 jones
                                      // NOTE -- NEED TO TEST HERE
1515 408 jones
                                      // FOR EXISTENCE OF DOCID PARAM
1516 203 jones
                                      // BEFORE ACCESSING ARRAY
1517 375 berkley
      try {
1518 1217 tao
        DocumentImpl.delete(docid[0], user, groups);
1519 204 jones
        response.setContentType("text/xml");
1520
        out.println("<?xml version=\"1.0\"?>");
1521
        out.println("<success>");
1522 203 jones
        out.println("Document deleted.");
1523 204 jones
        out.println("</success>");
1524 203 jones
      } catch (AccessionNumberException ane) {
1525 204 jones
        response.setContentType("text/xml");
1526
        out.println("<?xml version=\"1.0\"?>");
1527
        out.println("<error>");
1528
        out.println("Error deleting document!!!");
1529 203 jones
        out.println(ane.getMessage());
1530 204 jones
        out.println("</error>");
1531 203 jones
      }
1532 204 jones
    } catch (Exception e) {
1533
      response.setContentType("text/xml");
1534
      out.println("<?xml version=\"1.0\"?>");
1535
      out.println("<error>");
1536
      out.println(e.getMessage());
1537
      out.println("</error>");
1538 1217 tao
    }
1539 203 jones
  }
1540 731 bojilova
  // END OF DELETE SECTION
1541 68 higgins
1542 731 bojilova
  // VALIDATE SECTION
1543 68 higgins
  /**
1544 380 jones
   * Handle the validation request and return the results to the requestor
1545 68 higgins
   */
1546 185 jones
  private void handleValidateAction(PrintWriter out, Hashtable params,
1547
               HttpServletResponse response) {
1548 68 higgins
1549 103 jones
    // Get the document indicated
1550
    String valtext = null;
1551 1217 tao
    DBConnection dbConn = null;
1552
    int serialNumber = -1;
1553 309 bojilova
1554 103 jones
    try {
1555
      valtext = ((String[])params.get("valtext"))[0];
1556
    } catch (Exception nullpe) {
1557 68 higgins
1558 1217 tao
1559 162 bojilova
      String docid = null;
1560 103 jones
      try {
1561
        // Find the document id number
1562 185 jones
        docid = ((String[])params.get("docid"))[0];
1563 309 bojilova
1564 1217 tao
1565 309 bojilova
        // Get the document indicated from the db
1566 1217 tao
        DocumentImpl xmldoc = new DocumentImpl(docid);
1567 393 jones
        valtext = xmldoc.toString();
1568 185 jones
1569 103 jones
      } catch (NullPointerException npe) {
1570 253 jones
        response.setContentType("text/xml");
1571
        out.println("<error>Error getting document ID: " + docid + "</error>");
1572 1217 tao
        //if ( conn != null ) { util.returnConnection(conn); }
1573 380 jones
        return;
1574 309 bojilova
      } catch (Exception e) {
1575
        response.setContentType("text/html");
1576
        out.println(e.getMessage());
1577 1217 tao
      }
1578 103 jones
    }
1579 68 higgins
1580 1217 tao
1581 103 jones
    try {
1582 309 bojilova
      // get a connection from the pool
1583 1217 tao
      dbConn=DBConnectionPool.
1584
                  getDBConnection("MetaCatServlet.handleValidateAction");
1585
      serialNumber=dbConn.getCheckOutSerialNumber();
1586
      DBValidate valobj = new DBValidate(saxparser,dbConn);
1587 185 jones
      boolean valid = valobj.validateString(valtext);
1588 68 higgins
1589
      // set content type and other response header fields first
1590 253 jones
      response.setContentType("text/xml");
1591
      out.println(valobj.returnErrors());
1592
1593 103 jones
    } catch (NullPointerException npe2) {
1594
      // set content type and other response header fields first
1595 253 jones
      response.setContentType("text/xml");
1596
      out.println("<error>Error validating document.</error>");
1597 309 bojilova
    } catch (Exception e) {
1598
      response.setContentType("text/html");
1599
      out.println(e.getMessage());
1600
    } finally {
1601 1217 tao
      // Return db connection
1602
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1603 309 bojilova
    }
1604 103 jones
  }
1605 731 bojilova
  // END OF VALIDATE SECTION
1606
1607
  // OTHER ACTION HANDLERS
1608 302 bojilova
1609 1292 tao
  /**
1610
   * Handle "getrevsionanddoctype" action
1611
   * Given a docid, return it's current revision and doctype from data base
1612
   * The output is String look like "rev;doctype"
1613
   */
1614
  private void handleGetRevisionAndDocTypeAction(PrintWriter out,
1615
                                                              Hashtable params)
1616
  {
1617
    // To store doc parameter
1618
    String [] docs = new String[10];
1619
    // Store a single doc id
1620
    String givenDocId = null;
1621
    // Get docid from parameters
1622
    if (params.containsKey("docid"))
1623
    {
1624
      docs = (String[])params.get("docid");
1625
    }
1626
    // Get first docid form string array
1627
    givenDocId = docs[0];
1628
1629
    try
1630
    {
1631
      // Make sure there is a docid
1632
      if (givenDocId == null || givenDocId.equals(""))
1633
      {
1634
        throw new Exception("User didn't specify docid!");
1635
      }//if
1636
1637
      // Create a DBUtil object
1638
      DBUtil dbutil = new DBUtil();
1639
      // Get a rev and doctype
1640
      String revAndDocType =
1641
                dbutil.getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
1642
      out.println(revAndDocType);
1643
1644
    }//try
1645
    catch (Exception e)
1646
    {
1647
      // Handle exception
1648
      out.println("<?xml version=\"1.0\"?>");
1649
      out.println("<error>");
1650
      out.println(e.getMessage());
1651
      out.println("</error>");
1652
    }//catch
1653
1654
  }//handleGetRevisionAndDocTypeAction
1655
1656 302 bojilova
  /**
1657 688 bojilova
   * Handle "getaccesscontrol" action.
1658
   * Read Access Control List from db connection in XML format
1659
   */
1660
  private void handleGetAccessControlAction(PrintWriter out, Hashtable params,
1661
                                       HttpServletResponse response,
1662 802 bojilova
                                       String username, String[] groupnames) {
1663 688 bojilova
1664 1217 tao
    DBConnection dbConn = null;
1665
    int serialNumber = -1;
1666 688 bojilova
    String docid = ((String[])params.get("docid"))[0];
1667
1668
    try {
1669
1670
        // get connection from the pool
1671 1217 tao
        dbConn=DBConnectionPool.
1672
                 getDBConnection("MetaCatServlet.handleGetAccessControlAction");
1673
        serialNumber=dbConn.getCheckOutSerialNumber();
1674
        AccessControlList aclobj = new AccessControlList(dbConn);
1675 802 bojilova
        String acltext = aclobj.getACL(docid, username, groupnames);
1676 688 bojilova
        out.println(acltext);
1677
1678
    } catch (Exception e) {
1679
      out.println("<?xml version=\"1.0\"?>");
1680
      out.println("<error>");
1681
      out.println(e.getMessage());
1682
      out.println("</error>");
1683
    } finally {
1684 1217 tao
      // Retrun db connection to pool
1685
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1686 688 bojilova
    }
1687
1688
  }
1689
1690
  /**
1691 731 bojilova
   * Handle the "getprincipals" action.
1692
   * Read all principals from authentication scheme in XML format
1693
   */
1694
  private void handleGetPrincipalsAction(PrintWriter out, String user,
1695
                                         String password) {
1696
1697 1217 tao
1698 731 bojilova
    try {
1699
1700 1217 tao
1701 731 bojilova
        AuthSession auth = new AuthSession();
1702
        String principals = auth.getPrincipals(user, password);
1703
        out.println(principals);
1704
1705
    } catch (Exception e) {
1706
      out.println("<?xml version=\"1.0\"?>");
1707
      out.println("<error>");
1708
      out.println(e.getMessage());
1709
      out.println("</error>");
1710 1217 tao
    }
1711 731 bojilova
1712
  }
1713
1714
  /**
1715 688 bojilova
   * Handle "getdoctypes" action.
1716 302 bojilova
   * Read all doctypes from db connection in XML format
1717
   */
1718
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
1719
                                       HttpServletResponse response) {
1720
1721 1217 tao
1722 302 bojilova
    try {
1723
1724 1217 tao
1725
        DBUtil dbutil = new DBUtil();
1726 302 bojilova
        String doctypes = dbutil.readDoctypes();
1727
        out.println(doctypes);
1728
1729
    } catch (Exception e) {
1730
      out.println("<?xml version=\"1.0\"?>");
1731
      out.println("<error>");
1732
      out.println(e.getMessage());
1733
      out.println("</error>");
1734 1217 tao
    }
1735 302 bojilova
1736
  }
1737
1738
  /**
1739 699 bojilova
   * Handle the "getdtdschema" action.
1740
   * Read DTD or Schema file for a given doctype from Metacat catalog system
1741
   */
1742
  private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
1743
                                        HttpServletResponse response) {
1744
1745 1217 tao
1746 699 bojilova
    String doctype = null;
1747
    String[] doctypeArr = (String[])params.get("doctype");
1748
1749
    // get only the first doctype specified in the list of doctypes
1750
    // it could be done for all doctypes in that list
1751
    if (doctypeArr != null) {
1752
        doctype = ((String[])params.get("doctype"))[0];
1753
    }
1754
1755
    try {
1756
1757 1217 tao
1758
        DBUtil dbutil = new DBUtil();
1759 699 bojilova
        String dtdschema = dbutil.readDTDSchema(doctype);
1760
        out.println(dtdschema);
1761
1762
    } catch (Exception e) {
1763
      out.println("<?xml version=\"1.0\"?>");
1764
      out.println("<error>");
1765
      out.println(e.getMessage());
1766
      out.println("</error>");
1767 1217 tao
    }
1768 699 bojilova
1769
  }
1770
1771
  /**
1772 688 bojilova
   * Handle the "getdataguide" action.
1773 302 bojilova
   * Read Data Guide for a given doctype from db connection in XML format
1774
   */
1775
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params,
1776
                                        HttpServletResponse response) {
1777
1778 1217 tao
1779 316 bojilova
    String doctype = null;
1780
    String[] doctypeArr = (String[])params.get("doctype");
1781 309 bojilova
1782 316 bojilova
    // get only the first doctype specified in the list of doctypes
1783
    // it could be done for all doctypes in that list
1784
    if (doctypeArr != null) {
1785
        doctype = ((String[])params.get("doctype"))[0];
1786
    }
1787
1788 302 bojilova
    try {
1789
1790 1217 tao
1791
        DBUtil dbutil = new DBUtil();
1792 316 bojilova
        String dataguide = dbutil.readDataGuide(doctype);
1793 302 bojilova
        out.println(dataguide);
1794
1795
    } catch (Exception e) {
1796
      out.println("<?xml version=\"1.0\"?>");
1797
      out.println("<error>");
1798
      out.println(e.getMessage());
1799
      out.println("</error>");
1800 1217 tao
    }
1801 302 bojilova
1802
  }
1803
1804 793 bojilova
  /**
1805
   * Handle the "getlastdocid" action.
1806
   * Get the latest docid with rev number from db connection in XML format
1807
   */
1808 847 jones
  private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
1809 793 bojilova
                                        HttpServletResponse response) {
1810
1811 1217 tao
1812 847 jones
    String scope = ((String[])params.get("scope"))[0];
1813
    if (scope == null) {
1814
        scope = ((String[])params.get("username"))[0];
1815
    }
1816 793 bojilova
1817
    try {
1818
1819 1217 tao
1820
        DBUtil dbutil = new DBUtil();
1821 847 jones
        String lastDocid = dbutil.getMaxDocid(scope);
1822 793 bojilova
        out.println("<?xml version=\"1.0\"?>");
1823
        out.println("<lastDocid>");
1824 847 jones
        out.println("  <scope>" + scope + "</scope>");
1825 793 bojilova
        out.println("  <docid>" + lastDocid + "</docid>");
1826
        out.println("</lastDocid>");
1827
1828
    } catch (Exception e) {
1829
      out.println("<?xml version=\"1.0\"?>");
1830
      out.println("<error>");
1831
      out.println(e.getMessage());
1832
      out.println("</error>");
1833 1217 tao
    }
1834 793 bojilova
1835
  }
1836
1837 798 jones
  /**
1838
   * Handle documents passed to metacat that are encoded using the
1839
   * "multipart/form-data" mime type.  This is typically used for uploading
1840
   * data files which may be binary and large.
1841
   */
1842
  private void handleMultipartForm(HttpServletRequest request,
1843
                                   HttpServletResponse response)
1844
  {
1845
    PrintWriter out = null;
1846
    String action = null;
1847
1848
    // Parse the multipart form, and save the parameters in a Hashtable and
1849
    // save the FileParts in a hashtable
1850
1851
    Hashtable params = new Hashtable();
1852
    Hashtable fileList = new Hashtable();
1853
1854
    try {
1855
      // MBJ: need to put filesize limit in Metacat config (metacat.properties)
1856 943 tao
      MultipartParser mp = new MultipartParser(request, 200*1024*1024); //200MB
1857 798 jones
      Part part;
1858
      while ((part = mp.readNextPart()) != null) {
1859
        String name = part.getName();
1860
1861
        if (part.isParam()) {
1862
          // it's a parameter part
1863
          ParamPart paramPart = (ParamPart) part;
1864
          String value = paramPart.getStringValue();
1865
          params.put(name, value);
1866
          if (name.equals("action")) {
1867
            action = value;
1868
          }
1869
        } else if (part.isFile()) {
1870
          // it's a file part
1871
          FilePart filePart = (FilePart) part;
1872
          fileList.put(name, filePart);
1873
1874
          // Stop once the first file part is found, otherwise going onto the
1875
          // next part prevents access to the file contents.  So...for upload
1876
          // to work, the datafile must be the last part
1877
          break;
1878
        }
1879
      }
1880
    } catch (IOException ioe) {
1881
      try {
1882
        out = response.getWriter();
1883
      } catch (IOException ioe2) {
1884
        System.err.println("Fatal Error: couldn't get response output stream.");
1885
      }
1886
      out.println("<?xml version=\"1.0\"?>");
1887
      out.println("<error>");
1888
      out.println("Error: problem reading multipart data.");
1889
      out.println("</error>");
1890
    }
1891
1892
    // Get the session information
1893
    String username = null;
1894
    String password = null;
1895 802 bojilova
    String[] groupnames = null;
1896 798 jones
    String sess_id = null;
1897
1898
    // be aware of session expiration on every request
1899
    HttpSession sess = request.getSession(true);
1900
    if (sess.isNew()) {
1901
      // session expired or has not been stored b/w user requests
1902
      username = "public";
1903
      sess.setAttribute("username", username);
1904
    } else {
1905
      username = (String)sess.getAttribute("username");
1906
      password = (String)sess.getAttribute("password");
1907 802 bojilova
      groupnames = (String[])sess.getAttribute("groupnames");
1908 798 jones
      try {
1909
        sess_id = (String)sess.getId();
1910
      } catch(IllegalStateException ise) {
1911
        System.out.println("error in  handleMultipartForm: this shouldn't " +
1912
                           "happen: the session should be valid: " +
1913
                           ise.getMessage());
1914
      }
1915
    }
1916 1292 tao
1917
    // Get the out stream
1918
    try {
1919 798 jones
          out = response.getWriter();
1920
        } catch (IOException ioe2) {
1921 943 tao
          util.debugMessage("Fatal Error: couldn't get response "+
1922
                                                              "output stream.");
1923 798 jones
        }
1924 1292 tao
1925
    if ( action.equals("upload")) {
1926
      if (username != null &&  !username.equals("public")) {
1927
        handleUploadAction(request, out, params, fileList,
1928
                           username, groupnames);
1929
      } else {
1930
1931 798 jones
        out.println("<?xml version=\"1.0\"?>");
1932
        out.println("<error>");
1933
        out.println("Permission denied for " + action);
1934
        out.println("</error>");
1935
      }
1936
    } else {
1937 1292 tao
      /*try {
1938 798 jones
        out = response.getWriter();
1939
      } catch (IOException ioe2) {
1940
        System.err.println("Fatal Error: couldn't get response output stream.");
1941 1292 tao
      }*/
1942 798 jones
      out.println("<?xml version=\"1.0\"?>");
1943
      out.println("<error>");
1944
      out.println("Error: action not registered.  Please report this error.");
1945
      out.println("</error>");
1946
    }
1947 1217 tao
    out.close();
1948 798 jones
  }
1949
1950
  /**
1951
   * Handle the upload action by saving the attached file to disk and
1952
   * registering it in the Metacat db
1953
   */
1954
  private void handleUploadAction(HttpServletRequest request,
1955 1292 tao
                                  PrintWriter out,
1956 798 jones
                                  Hashtable params, Hashtable fileList,
1957 802 bojilova
                                  String username, String[] groupnames)
1958 798 jones
  {
1959 1292 tao
    //PrintWriter out = null;
1960 1217 tao
    //Connection conn = null;
1961 798 jones
    String action = null;
1962
    String docid = null;
1963 1041 tao
1964 1292 tao
    /*response.setContentType("text/xml");
1965 1041 tao
    try
1966
    {
1967 798 jones
      out = response.getWriter();
1968 1041 tao
    }
1969
    catch (IOException ioe2)
1970
    {
1971 798 jones
      System.err.println("Fatal Error: couldn't get response output stream.");
1972 1292 tao
    }*/
1973 798 jones
1974 1041 tao
    if (params.containsKey("docid"))
1975
    {
1976 798 jones
      docid = (String)params.get("docid");
1977
    }
1978
1979
    // Make sure we have a docid and datafile
1980
    if (docid != null && fileList.containsKey("datafile")) {
1981
1982
      // Get a reference to the file part of the form
1983
      FilePart filePart = (FilePart)fileList.get("datafile");
1984
      String fileName = filePart.getFileName();
1985 1056 tao
      MetaCatUtil.debugMessage("Uploading filename: " + fileName, 10);
1986 798 jones
1987
      // Check if the right file existed in the uploaded data
1988
      if (fileName != null) {
1989
1990 1028 tao
        try
1991
        {
1992 1292 tao
           //MetaCatUtil.debugMessage("Upload datafile " + docid +"...", 10);
1993 1028 tao
           //If document get lock data file grant
1994 1070 tao
           if (DocumentImpl.getDataFileLockGrant(docid))
1995
           {
1996 1064 tao
              // register the file in the database (which generates an exception
1997 1028 tao
              //if the docid is not acceptable or other untoward things happen
1998
              DocumentImpl.registerDocument(fileName, "BIN", docid, username);
1999 798 jones
2000 1028 tao
              // Save the data file to disk using "docid" as the name
2001
              dataDirectory.mkdirs();
2002
              File newFile = new File(dataDirectory, docid);
2003
              long size = filePart.writeTo(newFile);
2004 1292 tao
2005
              // Force replication this data file
2006
              // To data file, "insert" and update is same
2007
              // The fourth parameter is null. Because it is notification server
2008
              // and this method is in MetaCatServerlet. It is original command,
2009
              // not get force replication info from another metacat
2010
              ForceReplicationHandler frh = new ForceReplicationHandler
2011
                                                (docid, "insert", false, null);
2012
2013 1028 tao
              // set content type and other response header fields first
2014
              out.println("<?xml version=\"1.0\"?>");
2015
              out.println("<success>");
2016
              out.println("<docid>" + docid + "</docid>");
2017
              out.println("<size>" + size + "</size>");
2018
              out.println("</success>");
2019 1070 tao
          }//if
2020 798 jones
2021 1028 tao
        } //try
2022 1041 tao
        catch (Exception e)
2023
        {
2024 798 jones
          out.println("<?xml version=\"1.0\"?>");
2025
          out.println("<error>");
2026
          out.println(e.getMessage());
2027
          out.println("</error>");
2028
        }
2029 1217 tao
2030 1041 tao
      }
2031
      else
2032
      {
2033 798 jones
        // the field did not contain a file
2034
        out.println("<?xml version=\"1.0\"?>");
2035
        out.println("<error>");
2036
        out.println("The uploaded data did not contain a valid file.");
2037
        out.println("</error>");
2038
      }
2039 1041 tao
    }
2040
    else
2041
    {
2042 798 jones
      // Error bcse docid missing or file missing
2043
      out.println("<?xml version=\"1.0\"?>");
2044
      out.println("<error>");
2045
      out.println("The uploaded data did not contain a valid docid " +
2046
                  "or valid file.");
2047
      out.println("</error>");
2048
    }
2049
  }
2050 46 jones
}