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