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