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