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