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