Project

General

Profile

1
/**
2
 *  '$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
 *    Authors: Matt Jones, Dan Higgins, Jivka Bojilova, Chad Berkley
7
 *    Release: @release@
8
 *
9
 *   '$Author: tao $'
10
 *     '$Date: 2003-02-11 15:05:37 -0800 (Tue, 11 Feb 2003) $'
11
 * '$Revision: 1395 $'
12
 *
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
 */
27

    
28
package edu.ucsb.nceas.metacat;
29

    
30
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
import java.io.File;
36
import java.io.PrintWriter;
37
import java.io.IOException;
38
import java.io.StringReader;
39
import java.io.FileInputStream;
40
import java.io.BufferedInputStream;
41
import java.util.Enumeration;
42
import java.util.Hashtable;
43
import java.util.ResourceBundle;
44
import java.util.Random;
45
import java.util.PropertyResourceBundle;
46
import java.util.Vector;
47
import java.net.URL;
48
import java.net.MalformedURLException;
49
import java.sql.PreparedStatement;
50
import java.sql.ResultSet;
51
import java.sql.Connection;
52
import java.sql.SQLException;
53
import java.lang.reflect.*;
54
import java.net.*;
55
import java.util.zip.*;
56

    
57
import javax.servlet.ServletConfig;
58
import javax.servlet.ServletContext;
59
import javax.servlet.ServletException;
60
import javax.servlet.ServletInputStream;
61
import javax.servlet.http.HttpServlet;
62
import javax.servlet.http.HttpServletRequest;
63
import javax.servlet.http.HttpServletResponse;
64
import javax.servlet.http.HttpSession;
65
import javax.servlet.http.HttpUtils;
66
import javax.servlet.ServletOutputStream;
67

    
68
import org.xml.sax.SAXException;
69

    
70
/**
71
 * A metadata catalog server implemented as a Java Servlet
72
 *
73
 * <p>Valid parameters are:<br>
74
 * action=query -- query the values of all elements and attributes
75
 *                     and return a result set of nodes<br>
76
 * action=squery -- structured query (see pathquery.dtd)<br>
77
 * action= -- export a zip format for data packadge<br>
78
 * action=read -- read any metadata/data file from Metacat and from Internet<br>
79
 * action=insert -- insert an XML document into the database store<br>
80
 * action=update -- update an XML document that is in the database store<br>
81
 * action=delete --  delete an XML document from the database store<br>
82
 * action=validate -- vallidate the xml contained in valtext<br>
83
 * doctype -- document type list returned by the query (publicID)<br>
84
 * qformat=xml -- display resultset from query in XML<br>
85
 * qformat=html -- display resultset from query in HTML<br>
86
 * qformat=zip -- zip resultset from query<br>
87
 * docid=34 -- display the document with the document ID number 34<br>
88
 * doctext -- XML text of the document to load into the database<br>
89
 * acltext -- XML access text for a document to load into the database<br>
90
 * dtdtext -- XML DTD text for a new DTD to load into Metacat XML Catalog<br>
91
 * query -- actual query text (to go with 'action=query' or 'action=squery')<br>
92
 * valtext -- XML text to be validated<br>
93
 * abstractpath -- XPath in metadata document to read from<br>
94
 * action=getaccesscontrol -- retrieve acl info for Metacat document<br>
95
 * action=getdoctypes -- retrieve all doctypes (publicID)<br>
96
 * action=getdtdschema -- retrieve a DTD or Schema file<br>
97
 * action=getdataguide -- retrieve a Data Guide<br>
98
 * action=getprincipals -- retrieve a list of principals in XML<br>
99
 * datadoc -- data document name (id)<br>
100
 * <p>
101
 * The particular combination of parameters that are valid for each
102
 * particular action value is quite specific.  This documentation
103
 * will be reorganized to reflect this information.
104
 */
105
public class MetaCatServlet extends HttpServlet {
106

    
107
  private ServletConfig config = null;
108
  private ServletContext context = null;
109
  private String resultStyleURL = null;
110
  private String xmlcatalogfile = null;
111
  private String saxparser = null;
112
  private String datafilepath = null;
113
  private File dataDirectory = null;
114
  private String servletpath = null;
115
  private String htmlpath = null;
116
  private PropertyResourceBundle options = null;
117
  private MetaCatUtil util = null;
118
  private DBConnectionPool connPool = null;
119
  private static final String PROLOG = "<?xml version=\"1.0\"?>";
120
  private static final String SUCCESS = "<success>";
121
  private static final String SUCCESSCLOSE = "</success>";
122
  private static final String ERROR = "<error>";
123
  private static final String ERRORCLOSE = "</error>";
124
  public static final String SCHEMALOCATIONKEYWORD = "xsi:schemaLocation";
125

    
126
  /**
127
   * Initialize the servlet by creating appropriate database connections
128
   */
129
  public void init( ServletConfig config ) throws ServletException {
130
    try {
131
      super.init( config );
132
      this.config = config;
133
      this.context = config.getServletContext();
134
      System.out.println("MetaCatServlet Initialize");
135

    
136
      util = new MetaCatUtil();
137

    
138
      //initial DBConnection pool
139
      connPool = DBConnectionPool.getInstance();
140

    
141
      // Get the configuration file information
142
      resultStyleURL = util.getOption("resultStyleURL");
143
      xmlcatalogfile = util.getOption("xmlcatalogfile");
144
      saxparser = util.getOption("saxparser");
145
      datafilepath = util.getOption("datafilepath");
146
      dataDirectory = new File(datafilepath);
147
      servletpath = util.getOption("servletpath");
148
      htmlpath = util.getOption("htmlpath");
149

    
150

    
151
    } catch ( ServletException ex ) {
152
      throw ex;
153
    } catch (SQLException e) {
154
      MetaCatUtil.debugMessage("Error in MetacatServlet.init: "
155
                                          +e.getMessage(), 20);
156
    }
157
  }
158

    
159
  /**
160
   * Close all db connections from the pool
161
   */
162
  public void destroy() {
163
      // Close all db connection
164
      System.out.println("Destroying MetacatServlet");
165
      connPool.release();
166
  }
167

    
168
  /** Handle "GET" method requests from HTTP clients */
169
  public void doGet (HttpServletRequest request, HttpServletResponse response)
170
    throws ServletException, IOException {
171

    
172
    // Process the data and send back the response
173
    handleGetOrPost(request, response);
174
  }
175

    
176
  /** Handle "POST" method requests from HTTP clients */
177
  public void doPost( HttpServletRequest request, HttpServletResponse response)
178
    throws ServletException, IOException {
179

    
180
    // Process the data and send back the response
181
    handleGetOrPost(request, response);
182
  }
183

    
184
  /**
185
   * Control servlet response depending on the action parameter specified
186
   */
187
  private void handleGetOrPost(HttpServletRequest request,
188
                               HttpServletResponse response)
189
                               throws ServletException, IOException
190
  {
191

    
192
    if ( util == null ) {
193
        util = new MetaCatUtil();
194
    }
195
    /*MetaCatUtil.debugMessage("Connection pool size: "
196
                                     +connPool.getSizeOfDBConnectionPool(),10);
197
    MetaCatUtil.debugMessage("Free DBConnection number: "
198
                                  +connPool.getFreeDBConnectionNumber(), 10);*/
199
    //If all DBConnection in the pool are free and DBConnection pool
200
    //size is greater than initial value, shrink the connection pool
201
    //size to initial value
202
    DBConnectionPool.shrinkDBConnectionPoolSize();
203

    
204
    //Debug message to print out the method which have a busy DBConnection
205
    connPool.printMethodNameHavingBusyDBConnection();
206

    
207
    String ctype = request.getContentType();
208
    if (ctype != null && ctype.startsWith("multipart/form-data")) {
209
      handleMultipartForm(request, response);
210
    } else {
211

    
212

    
213
      String name = null;
214
      String[] value = null;
215
      String[] docid = new String[3];
216
      Hashtable params = new Hashtable();
217
      Enumeration paramlist = request.getParameterNames();
218

    
219

    
220
      while (paramlist.hasMoreElements()) {
221

    
222
        name = (String)paramlist.nextElement();
223
        value = request.getParameterValues(name);
224

    
225
        // Decode the docid and mouse click information
226
        if (name.endsWith(".y")) {
227
          docid[0] = name.substring(0,name.length()-2);
228
          params.put("docid", docid);
229
          name = "ypos";
230
        }
231
        if (name.endsWith(".x")) {
232
          name = "xpos";
233
        }
234

    
235
        params.put(name,value);
236
      }
237

    
238

    
239
      //handle param is emptpy
240
      if (params.isEmpty() || params == null)
241
      {
242
        return;
243
      }
244
      //if the user clicked on the input images, decode which image
245
      //was clicked then set the action.
246
      String action = ((String[])params.get("action"))[0];
247
      util.debugMessage("Line 230: Action is: " + action, 1);
248

    
249
      // This block handles session management for the servlet
250
      // by looking up the current session information for all actions
251
      // other than "login" and "logout"
252
      String username = null;
253
      String password = null;
254
      String[] groupnames = null;
255
      String sess_id = null;
256

    
257
      // handle login action
258
      if (action.equals("login")) {
259
        PrintWriter out = response.getWriter();
260
        handleLoginAction(out, params, request, response);
261
        out.close();
262

    
263
      // handle logout action
264
      } else if (action.equals("logout")) {
265
        PrintWriter out = response.getWriter();
266
        handleLogoutAction(out, params, request, response);
267
        out.close();
268

    
269
      // handle shrink DBConnection request
270
      } else if (action.equals("shrink")) {
271
        PrintWriter out = response.getWriter();
272
        boolean success = false;
273
        //If all DBConnection in the pool are free and DBConnection pool
274
        //size is greater than initial value, shrink the connection pool
275
        //size to initial value
276
        success = DBConnectionPool.shrinkConnectionPoolSize();
277
        if (success)
278
        {
279
          //if successfully shrink the pool size to initial value
280
          out.println("DBConnection Pool shrink successfully");
281
        }//if
282
        else
283
        {
284
          out.println("DBConnection pool couldn't shrink successfully");
285
        }
286
       //close out put
287
        out.close();
288

    
289
      // aware of session expiration on every request
290
      } else {
291

    
292
        HttpSession sess = request.getSession(true);
293
        if (sess.isNew()) {
294
          // session expired or has not been stored b/w user requests
295
          username = "public";
296
          sess.setAttribute("username", username);
297
        } else {
298
          username = (String)sess.getAttribute("username");
299
          password = (String)sess.getAttribute("password");
300
          groupnames = (String[])sess.getAttribute("groupnames");
301
          try {
302
            sess_id = (String)sess.getId();
303
          } catch(IllegalStateException ise) {
304
            System.out.println("error in handleGetOrPost: this shouldn't " +
305
                               "happen: the session should be valid: " +
306
                               ise.getMessage());
307
          }
308
        }
309
      }
310

    
311
       // Now that we know the session is valid, we can delegate the request
312
      // to a particular action handler
313
      if(action.equals("query")) {
314
        PrintWriter out = response.getWriter();
315
        handleQuery(out,params,response,username,groupnames);
316
        out.close();
317
      } else if(action.equals("squery")) {
318
        PrintWriter out = response.getWriter();
319
        if(params.containsKey("query")) {
320
         handleSQuery(out, params,response,username,groupnames);
321
         out.close();
322
        } else {
323
          out.println("Illegal action squery without \"query\" parameter");
324
          out.close();
325
        }
326
      } else if (action.equals("export")) {
327

    
328
        handleExportAction(params, response, username, groupnames, password);
329
      } else if (action.equals("read")) {
330
        handleReadAction(params, response, username,password, groupnames);
331
      } else if (action.equals("insert") || action.equals("update")) {
332
        PrintWriter out = response.getWriter();
333
        if ( (username != null) &&  !username.equals("public") ) {
334
          handleInsertOrUpdateAction(out,params,username,groupnames);
335
        } else {
336
          out.println("Permission denied for " + action);
337
        }
338
        out.close();
339
      } else if (action.equals("delete")) {
340
        PrintWriter out = response.getWriter();
341
        if ( (username != null) &&  !username.equals("public") ) {
342
          handleDeleteAction(out, params, response, username, groupnames);
343
        } else {
344
          out.println("Permission denied for " + action);
345
        }
346
        out.close();
347
      } else if (action.equals("validate")) {
348
        PrintWriter out = response.getWriter();
349
        handleValidateAction(out, params);
350
        out.close();
351
      } else if (action.equals("setaccess")) {
352
         PrintWriter out = response.getWriter();
353
         handleSetAccessAction(out, params, username);
354
        out.close();
355
      } else if (action.equals("getaccesscontrol")) {
356
        PrintWriter out = response.getWriter();
357
        handleGetAccessControlAction(out,params,response,username,groupnames);
358
        out.close();
359
      } else if (action.equals("getprincipals")) {
360
        PrintWriter out = response.getWriter();
361
        handleGetPrincipalsAction(out, username, password);
362
        out.close();
363
      } else if (action.equals("getdoctypes")) {
364
        PrintWriter out = response.getWriter();
365
        handleGetDoctypesAction(out, params, response);
366
        out.close();
367
      } else if (action.equals("getdtdschema")) {
368
        PrintWriter out = response.getWriter();
369
        handleGetDTDSchemaAction(out, params, response);
370
        out.close();
371
      } else if (action.equals("getdataguide")) {
372
        PrintWriter out = response.getWriter();
373
        handleGetDataGuideAction(out, params, response);
374
        out.close();
375
      } else if (action.equals("getlastdocid")) {
376
        PrintWriter out = response.getWriter();
377
        handleGetMaxDocidAction(out, params, response);
378
        out.close();
379
      } else if (action.equals("getrevisionanddoctype")) {
380
        PrintWriter out = response.getWriter();
381
        handleGetRevisionAndDocTypeAction(out, params);
382
        out.close();
383
      } else if (action.equals("login") || action.equals("logout")) {
384
      } else if (action.equals("protocoltest")) {
385
        String testURL = "metacat://dev.nceas.ucsb.edu/NCEAS.897766.9";
386
        try {
387
          testURL = ((String[])params.get("url"))[0];
388
        } catch (Throwable t) {
389
        }
390
        String phandler = System.getProperty("java.protocol.handler.pkgs");
391
        response.setContentType("text/html");
392
        PrintWriter out = response.getWriter();
393
        out.println("<body bgcolor=\"white\">");
394
        out.println("<p>Handler property: <code>" + phandler + "</code></p>");
395
        out.println("<p>Starting test for:<br>");
396
        out.println("    " + testURL + "</p>");
397
        try {
398
          URL u = new URL(testURL);
399
          out.println("<pre>");
400
          out.println("Protocol: " + u.getProtocol());
401
          out.println("    Host: " + u.getHost());
402
          out.println("    Port: " + u.getPort());
403
          out.println("    Path: " + u.getPath());
404
          out.println("     Ref: " + u.getRef());
405
          String pquery = u.getQuery();
406
          out.println("   Query: " + pquery);
407
          out.println("  Params: ");
408
          if (pquery != null) {
409
            Hashtable qparams = util.parseQuery(u.getQuery());
410
            for (Enumeration en = qparams.keys(); en.hasMoreElements(); ) {
411
              String pname = (String)en.nextElement();
412
              String pvalue = (String)qparams.get(pname);
413
              out.println("    " + pname + ": " + pvalue);
414
            }
415
          }
416
          out.println("</pre>");
417
          out.println("</body>");
418
          out.close();
419
        } catch (MalformedURLException mue) {
420
          System.out.println("bad url from MetacatServlet.handleGetOrPost");
421
          out.println(mue.getMessage());
422
          mue.printStackTrace(out);
423
          out.close();
424
        }
425
      } else {
426
        PrintWriter out = response.getWriter();
427
        out.println("<?xml version=\"1.0\"?>");
428
        out.println("<error>");
429
        out.println("Error: action not registered.  Please report this error.");
430
        out.println("</error>");
431
        out.close();
432
      }
433

    
434
      //util.closeConnections();
435
      // Close the stream to the client
436
      //out.close();
437
    }
438
  }
439

    
440
  // LOGIN & LOGOUT SECTION
441
  /**
442
   * Handle the login request. Create a new session object.
443
   * Do user authentication through the session.
444
   */
445
  private void handleLoginAction(PrintWriter out, Hashtable params,
446
               HttpServletRequest request, HttpServletResponse response) {
447

    
448
    AuthSession sess = null;
449
    String un = ((String[])params.get("username"))[0];
450
    String pw = ((String[])params.get("password"))[0];
451
    String action = ((String[])params.get("action"))[0];
452
    String qformat = ((String[])params.get("qformat"))[0];
453

    
454
    try {
455
      sess = new AuthSession();
456
    } catch (Exception e) {
457
      System.out.println("error in MetacatServlet.handleLoginAction: " +
458
                          e.getMessage());
459
      out.println(e.getMessage());
460
      return;
461
    }
462
    boolean isValid = sess.authenticate(request, un, pw);
463
    // format and transform the output
464
    if (qformat.equals("xml")) {
465
      response.setContentType("text/xml");
466
      out.println(sess.getMessage());
467
    } else {
468

    
469
      try {
470

    
471
        DBTransform trans = new DBTransform();
472
        response.setContentType("text/html");
473
        trans.transformXMLDocument(sess.getMessage(), "-//NCEAS//login//EN",
474
                                   "-//W3C//HTML//EN", qformat, out);
475

    
476
      } catch(Exception e) {
477

    
478
        MetaCatUtil.debugMessage("Error in MetaCatServlet.handleLoginAction: "
479
                                +e.getMessage(), 30);
480
      }
481

    
482
    // any output is returned
483
    }
484
  }
485

    
486
  /**
487
   * Handle the logout request. Close the connection.
488
   */
489
  private void handleLogoutAction(PrintWriter out, Hashtable params,
490
               HttpServletRequest request, HttpServletResponse response) {
491

    
492
    String qformat = ((String[])params.get("qformat"))[0];
493

    
494
    // close the connection
495
    HttpSession sess = request.getSession(false);
496
    if (sess != null) { sess.invalidate();  }
497

    
498
    // produce output
499
    StringBuffer output = new StringBuffer();
500
    output.append("<?xml version=\"1.0\"?>");
501
    output.append("<logout>");
502
    output.append("User logged out");
503
    output.append("</logout>");
504

    
505
    //format and transform the output
506
    if (qformat.equals("xml")) {
507
      response.setContentType("text/xml");
508
      out.println(output.toString());
509
    } else {
510

    
511
      try {
512

    
513
        DBTransform trans = new DBTransform();
514
        response.setContentType("text/html");
515
        trans.transformXMLDocument(output.toString(), "-//NCEAS//login//EN",
516
                                   "-//W3C//HTML//EN", qformat, out);
517

    
518
      } catch(Exception e) {
519

    
520
        MetaCatUtil.debugMessage("Error in MetaCatServlet.handleLogoutAction"
521
                                  +e.getMessage(), 30);
522
      }
523
    }
524
  }
525
  // END OF LOGIN & LOGOUT SECTION
526

    
527
  // SQUERY & QUERY SECTION
528
  /**
529
   * Retreive the squery xml, execute it and display it
530
   *
531
   * @param out the output stream to the client
532
   * @param params the Hashtable of parameters that should be included
533
   * in the squery.
534
   * @param response the response object linked to the client
535
   * @param conn the database connection
536
   */
537
  protected void handleSQuery(PrintWriter out, Hashtable params,
538
                 HttpServletResponse response, String user, String[] groups)
539
  {
540
    String xmlquery = ((String[])params.get("query"))[0];
541
    String qformat = ((String[])params.get("qformat"))[0];
542
    String resultdoc = null;
543
    MetaCatUtil.debugMessage("xmlquery: "+xmlquery, 30);
544
    double startTime = System.currentTimeMillis()/1000;
545
    Hashtable doclist = runQuery(xmlquery, user, groups);
546
    double docListTime = System.currentTimeMillis()/1000;
547
    MetaCatUtil.debugMessage("Time for getting doc list: "
548
                                            +(docListTime-startTime), 30);
549

    
550
    resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
551
    double toStringTime = System.currentTimeMillis()/1000;
552
    MetaCatUtil.debugMessage("Time to create xml string: "
553
                              +(toStringTime-docListTime), 30);
554
    //format and transform the results
555
    double outPutTime = 0;
556
    if(qformat.equals("xml")) {
557
      response.setContentType("text/xml");
558
      out.println(resultdoc);
559
      outPutTime = System.currentTimeMillis()/1000;
560
      MetaCatUtil.debugMessage("Output time: "+(outPutTime-toStringTime), 30);
561
    } else {
562
      transformResultset(resultdoc, response, out, qformat);
563
      outPutTime = System.currentTimeMillis()/1000;
564
      MetaCatUtil.debugMessage("Output time: "+(outPutTime-toStringTime), 30);
565
    }
566
  }
567

    
568
   /**
569
    * Create the xml query, execute it and display the results.
570
    *
571
    * @param out the output stream to the client
572
    * @param params the Hashtable of parameters that should be included
573
    * in the squery.
574
    * @param response the response object linked to the client
575
    */
576
  protected void handleQuery(PrintWriter out, Hashtable params,
577
                 HttpServletResponse response, String user, String[] groups)
578
  {
579
    //create the query and run it
580
    String xmlquery = DBQuery.createSQuery(params);
581
    Hashtable doclist = runQuery(xmlquery, user, groups);
582
    String qformat = ((String[])params.get("qformat"))[0];
583
    String resultdoc = null;
584

    
585
    resultdoc = createResultDocument(doclist, transformQuery(params));
586

    
587
    //format and transform the results
588
    if(qformat.equals("xml")) {
589
      response.setContentType("text/xml");
590
      out.println(resultdoc);
591
    } else {
592
      transformResultset(resultdoc, response, out, qformat);
593
    }
594
  }
595

    
596
  /**
597
   * Removes the <?xml version="x"?> tag from the beginning of xmlquery
598
   * so it can properly be placed in the <query> tag of the resultset.
599
   * This method is overwritable so that other applications can customize
600
   * the structure of what is in the <query> tag.
601
   *
602
   * @param xmlquery is the query to remove the <?xml version="x"?> tag from.
603
   */
604
  protected String transformQuery(Hashtable params)
605
  {
606
    //DBQuery.createSQuery is a re-calling of a previously called
607
    //function but it is necessary
608
    //so that overriding methods have access to the params hashtable
609
    String xmlquery = DBQuery.createSQuery(params);
610
    //the <?xml version="1.0"?> tag is the first 22 characters of the
611
    xmlquery = xmlquery.trim();
612
    int index = xmlquery.indexOf("?>");
613
    return xmlquery.substring(index + 2, xmlquery.length());
614
  }
615

    
616
  /**
617
   * removes the <?xml version="1.0"?> tag from the beginning.  This takes a
618
   * string as a param instead of a hashtable.
619
   *
620
   * @param xmlquery a string representing a query.
621
   */
622
  protected String transformQuery(String xmlquery)
623
  {
624
    xmlquery = xmlquery.trim();
625
    int index = xmlquery.indexOf("?>");
626
    return xmlquery.substring(index + 2, xmlquery.length());
627
  }
628

    
629
  /**
630
   * Run the query and return a hashtable of results.
631
   *
632
   * @param xmlquery the query to run
633
   */
634
  private Hashtable runQuery(String xmlquery, String user, String[] groups)
635
  {
636
    Hashtable doclist=null;
637

    
638
    try
639
    {
640

    
641
      DBQuery queryobj = new DBQuery(saxparser);
642
      doclist = queryobj.findDocuments(new StringReader(xmlquery),user,groups);
643

    
644
      return doclist;
645
    }
646
    catch (Exception e)
647
    {
648

    
649
      MetaCatUtil.debugMessage("Error in MetacatServlet.runQuery: "
650
                                                      + e.getMessage(), 30);
651
      doclist = null;
652
      return doclist;
653
    }
654
  }
655

    
656
  /**
657
   * Transorms an xml resultset document to html and sends it to the browser
658
   *
659
   * @param resultdoc the string representation of the document that needs
660
   * to be transformed.
661
   * @param response the HttpServletResponse object bound to the client.
662
   * @param out the output stream to the client
663
   * @param qformat the name of the style-set to use for transformations
664
   */
665
  protected void transformResultset(String resultdoc,
666
                                    HttpServletResponse response,
667
                                    PrintWriter out, String qformat)
668
  {
669

    
670
    try {
671

    
672
      DBTransform trans = new DBTransform();
673
      response.setContentType("text/html");
674
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN",
675
                                 "-//W3C//HTML//EN", qformat, out);
676

    
677
    }
678
    catch(Exception e)
679
    {
680

    
681
      MetaCatUtil.debugMessage("Error in MetaCatServlet.transformResultset:"
682
                                +e.getMessage(), 30);
683
    }
684
  }
685

    
686
  /**
687
   * Transforms a hashtable of documents to an xml or html result.
688
   *
689
   * @param doclist- the hashtable to transform
690
   * @param xmlquery- the query that returned the doclist result
691
   */
692
  protected String createResultDocument(Hashtable doclist, String xmlquery)
693
  {
694
    // Create a buffer to hold the xml result
695
    StringBuffer resultset = new StringBuffer();
696

    
697
    // Print the resulting root nodes
698
    String docid = null;
699
    String document = null;
700
    resultset.append("<?xml version=\"1.0\"?>\n");
701
    resultset.append("<resultset>\n");
702

    
703
    resultset.append("  <query>" + xmlquery + "</query>");
704

    
705
    if(doclist != null)
706
    {
707
      Enumeration doclistkeys = doclist.keys();
708
      while (doclistkeys.hasMoreElements())
709
      {
710
        docid = (String)doclistkeys.nextElement();
711
        document = (String)doclist.get(docid);
712
        resultset.append("  <document>" + document + "</document>");
713
      }
714
    }
715

    
716
    resultset.append("</resultset>");
717
    return resultset.toString();
718
  }
719
  // END OF SQUERY & QUERY SECTION
720

    
721
 //Exoport section
722
 /**
723
   * Handle the "export" request of data package from Metacat in zip format
724
   * @param params the Hashtable of HTTP request parameters
725
   * @param response the HTTP response object linked to the client
726
   * @param user the username sent the request
727
   * @param groups the user's groupnames
728
   */
729
  private void handleExportAction(Hashtable params,
730
    HttpServletResponse response, String user, String[] groups, String passWord)
731
  {
732
    // Output stream
733
    ServletOutputStream out = null;
734
    // Zip output stream
735
    ZipOutputStream zOut = null;
736
    DocumentImpl docImpls=null;
737
    DBQuery queryObj=null;
738

    
739
    String[] docs = new String[10];
740
    String docId = "";
741

    
742
    try
743
    {
744
      // read the params
745
      if (params.containsKey("docid"))
746
      {
747
        docs = (String[])params.get("docid");
748
      }//if
749
      // Create a DBuery to handle export
750
      queryObj = new DBQuery(saxparser);
751
      // Get the docid
752
      docId=docs[0];
753
      // Make sure the client specify docid
754
      if (docId == null || docId.equals(""))
755
      {
756
        response.setContentType("text/xml"); //MIME type
757
        // Get a printwriter
758
        PrintWriter pw = response.getWriter();
759
        // Send back message
760
        pw.println("<?xml version=\"1.0\"?>");
761
        pw.println("<error>");
762
        pw.println("You didn't specify requested docid");
763
        pw.println("</error>");
764
        // Close printwriter
765
        pw.close();
766
        return;
767
      }//if
768
      // Get output stream
769
      out = response.getOutputStream();
770
      response.setContentType("application/zip"); //MIME type
771
      zOut = new ZipOutputStream(out);
772
      zOut =queryObj.getZippedPackage(docId, out, user, groups, passWord);
773
      zOut.finish(); //terminate the zip file
774
      zOut.close();  //close the zip stream
775

    
776
    }//try
777
    catch (Exception e)
778
    {
779
      try
780
      {
781
        response.setContentType("text/xml"); //MIME type
782
        // Send error message back
783
        if (out != null)
784
        {
785
            PrintWriter pw = new PrintWriter(out);
786
            pw.println("<?xml version=\"1.0\"?>");
787
            pw.println("<error>");
788
            pw.println(e.getMessage());
789
            pw.println("</error>");
790
            // Close printwriter
791
            pw.close();
792
            // Close output stream
793
            out.close();
794
        }//if
795
        // Close zip output stream
796
        if ( zOut != null )
797
        {
798
          zOut.close();
799
        }//if
800
      }//try
801
      catch (IOException ioe)
802
      {
803
        MetaCatUtil.debugMessage("Problem with the servlet output " +
804
                           "in MetacatServlet.handleExportAction: " +
805
                           ioe.getMessage(), 30);
806
      }//catch
807

    
808
      MetaCatUtil.debugMessage("Error in MetacatServlet.handleExportAction: " +
809
                         e.getMessage(), 30);
810
      e.printStackTrace(System.out);
811

    
812
    }//catch
813

    
814
  }//handleExportAction
815

    
816
  // READ SECTION
817
  /**
818
   * Handle the "read" request of metadata/data files from Metacat
819
   * or any files from Internet;
820
   * transformed metadata XML document into HTML presentation if requested;
821
   * zip files when more than one were requested.
822
   *
823
   * @param params the Hashtable of HTTP request parameters
824
   * @param response the HTTP response object linked to the client
825
   * @param user the username sent the request
826
   * @param groups the user's groupnames
827
   */
828
  private void handleReadAction(Hashtable params, HttpServletResponse response,
829
                                String user, String passWord, String[] groups)
830
  {
831
    ServletOutputStream out = null;
832
    ZipOutputStream zout = null;
833
    PrintWriter pw = null;
834
    boolean zip = false;
835

    
836
    try {
837
      String[] docs = new String[0];
838
      String docid = "";
839
      String qformat = "";
840
      String abstrpath = null;
841

    
842
      // read the params
843
      if (params.containsKey("docid")) {
844
        docs = (String[])params.get("docid");
845
      }
846
      if (params.containsKey("qformat")) {
847
        qformat = ((String[])params.get("qformat"))[0];
848
      }
849
      if (params.containsKey("abstractpath")) {
850
        abstrpath = ((String[])params.get("abstractpath"))[0];
851
        if ( !abstrpath.equals("") && (abstrpath != null) ) {
852
          viewAbstract(response, abstrpath, docs[0]);
853
          return;
854
        }
855
      }
856
      if ( (docs.length > 1) || qformat.equals("zip") ) {
857
        zip = true;
858
        out = response.getOutputStream();
859
        response.setContentType("application/zip"); //MIME type
860
        zout = new ZipOutputStream(out);
861
      }
862
      // go through the list of docs to read
863
      for (int i=0; i < docs.length; i++ ) {
864
        try {
865

    
866
          URL murl = new URL(docs[i]);
867
          Hashtable murlQueryStr = util.parseQuery(murl.getQuery());
868
          // case docid="http://.../?docid=aaa"
869
          // or docid="metacat://.../?docid=bbb"
870
          if (murlQueryStr.containsKey("docid")) {
871
            // get only docid, eliminate the rest
872
            docid = (String)murlQueryStr.get("docid");
873
            if ( zip ) {
874
              addDocToZip(docid, zout, user, groups);
875
            } else {
876
              readFromMetacat(response, docid, qformat, abstrpath,
877
                              user, groups, zip, zout);
878
            }
879

    
880
          // case docid="http://.../filename"
881
          } else {
882
            docid = docs[i];
883
            if ( zip ) {
884
              addDocToZip(docid, zout, user, groups);
885
            } else {
886
              readFromURLConnection(response, docid);
887
            }
888
          }
889

    
890
        // case docid="ccc"
891
        } catch (MalformedURLException mue) {
892
          docid = docs[i];
893
          if ( zip ) {
894
            addDocToZip(docid, zout, user, groups);
895
          } else {
896
            readFromMetacat(response, docid, qformat, abstrpath,
897
                            user, groups, zip, zout);
898
          }
899
        }
900

    
901
      } /* end for */
902

    
903
      if ( zip ) {
904
        zout.finish(); //terminate the zip file
905
        zout.close();  //close the zip stream
906
      }
907

    
908

    
909
    }
910
    // To handle doc not found exception
911
    catch (McdbDocNotFoundException notFoundE)
912
    {
913
      // the docid which didn't be found
914
      String notFoundDocId = notFoundE.getUnfoundDocId();
915
      String notFoundRevision = notFoundE.getUnfoundRevision();
916
      MetaCatUtil.debugMessage("Missed id: "+ notFoundDocId, 30);
917
      MetaCatUtil.debugMessage("Missed rev: "+ notFoundRevision, 30);
918
      try
919
      {
920
        // read docid from remote server
921
        readFromRemoteMetaCat(response, notFoundDocId, notFoundRevision,
922
                                              user, passWord, out, zip, zout);
923
        // Close zout outputstream
924
        if ( zout != null)
925
        {
926
          zout.close();
927
        }
928
        // close output stream
929
        if (out != null)
930
        {
931
          out.close();
932
        }
933

    
934
      }//try
935
      catch ( Exception exc)
936
      {
937
        MetaCatUtil.debugMessage("Erorr in MetacatServlet.hanldReadAction: "+
938
                                      exc.getMessage(), 30);
939
        try
940
        {
941
          if (out != null)
942
          {
943
            response.setContentType("text/xml");
944
            // Send back error message by printWriter
945
            pw = new PrintWriter(out);
946
            pw.println("<?xml version=\"1.0\"?>");
947
            pw.println("<error>");
948
            pw.println(notFoundE.getMessage());
949
            pw.println("</error>");
950
            pw.close();
951
            out.close();
952

    
953
          }
954
          else
955
          {
956
           response.setContentType("text/xml"); //MIME type
957
           // Send back error message if out = null
958
           if (pw == null)
959
           {
960
             // If pw is null, open the respnose
961
            pw = response.getWriter();
962
           }
963
           pw.println("<?xml version=\"1.0\"?>");
964
           pw.println("<error>");
965
           pw.println(notFoundE.getMessage());
966
           pw.println("</error>");
967
           pw.close();
968
        }
969
        // close zout
970
        if ( zout != null )
971
        {
972
          zout.close();
973
        }
974
        }//try
975
        catch (IOException ie)
976
        {
977
          MetaCatUtil.debugMessage("Problem with the servlet output " +
978
                           "in MetacatServlet.handleReadAction: " +
979
                           ie.getMessage(), 30);
980
        }//cathch
981
      }//catch
982
    }// catch McdbDocNotFoundException
983
    catch (Exception e)
984
    {
985
      try {
986

    
987
        if (out != null) {
988
            response.setContentType("text/xml"); //MIME type
989
            pw = new PrintWriter(out);
990
            pw.println("<?xml version=\"1.0\"?>");
991
            pw.println("<error>");
992
            pw.println(e.getMessage());
993
            pw.println("</error>");
994
            pw.close();
995
            out.close();
996
        }
997
        else
998
        {
999
           response.setContentType("text/xml"); //MIME type
1000
           // Send back error message if out = null
1001
           if ( pw == null)
1002
           {
1003
            pw = response.getWriter();
1004
           }
1005
           pw.println("<?xml version=\"1.0\"?>");
1006
           pw.println("<error>");
1007
           pw.println(e.getMessage());
1008
           pw.println("</error>");
1009
           pw.close();
1010

    
1011
        }
1012
        // Close zip output stream
1013
        if ( zout != null ) { zout.close(); }
1014

    
1015
      } catch (IOException ioe) {
1016
        MetaCatUtil.debugMessage("Problem with the servlet output " +
1017
                           "in MetacatServlet.handleReadAction: " +
1018
                           ioe.getMessage(), 30);
1019
        ioe.printStackTrace(System.out);
1020

    
1021
      }
1022

    
1023
      System.out.println("Error in MetacatServlet.handleReadAction: " +
1024
                         e.getMessage());
1025
      e.printStackTrace(System.out);
1026
    }
1027

    
1028
  }
1029

    
1030
  // read metadata or data from Metacat
1031
  private void readFromMetacat(HttpServletResponse response, String docid,
1032
                               String qformat, String abstrpath, String user,
1033
                             String[] groups, boolean zip, ZipOutputStream zout)
1034
               throws ClassNotFoundException, IOException, SQLException,
1035
                      McdbException, Exception
1036
  {
1037

    
1038
    try {
1039

    
1040

    
1041
      DocumentImpl doc = new DocumentImpl(docid);
1042

    
1043
      //check the permission for read
1044
      if (!doc.hasReadPermission(user, groups, docid))
1045
      {
1046
        Exception e = new Exception("User " + user + " does not have permission"
1047
                       +" to read the document with the docid " + docid);
1048

    
1049
        throw e;
1050
      }
1051

    
1052
      if ( doc.getRootNodeID() == 0 ) {
1053
        // this is data file
1054
        String filepath = util.getOption("datafilepath");
1055
        if(!filepath.endsWith("/")) {
1056
          filepath += "/";
1057
        }
1058
        String filename = filepath + docid;
1059
        FileInputStream fin = null;
1060
        fin = new FileInputStream(filename);
1061

    
1062
        //MIME type
1063
        String contentType = getServletContext().getMimeType(filename);
1064
        if (contentType == null) {
1065
          if (filename.endsWith(".xml")) {
1066
            contentType="text/xml";
1067
          } else if (filename.endsWith(".css")) {
1068
            contentType="text/css";
1069
          } else if (filename.endsWith(".dtd")) {
1070
            contentType="text/plain";
1071
          } else if (filename.endsWith(".xsd")) {
1072
            contentType="text/xml";
1073
          } else if (filename.endsWith("/")) {
1074
            contentType="text/html";
1075
          } else {
1076
            File f = new File(filename);
1077
            if ( f.isDirectory() ) {
1078
              contentType="text/html";
1079
            } else {
1080
              contentType="application/octet-stream";
1081
            }
1082
          }
1083
        }
1084
        response.setContentType(contentType);
1085
        // if we decide to use "application/octet-stream" for all data returns
1086
        // response.setContentType("application/octet-stream");
1087

    
1088
        try {
1089

    
1090
          ServletOutputStream out = response.getOutputStream();
1091
          byte[] buf = new byte[4 * 1024]; // 4K buffer
1092
          int b = fin.read(buf);
1093
          while (b != -1) {
1094
            out.write(buf, 0, b);
1095
            b = fin.read(buf);
1096
          }
1097
        } finally {
1098
          if (fin != null) fin.close();
1099
        }
1100

    
1101
      } else {
1102
        // this is metadata doc
1103
        if ( qformat.equals("xml") ) {
1104

    
1105
          // set content type first
1106
          response.setContentType("text/xml");   //MIME type
1107
          PrintWriter out = response.getWriter();
1108
          doc.toXml(out);
1109
        } else {
1110
          response.setContentType("text/html");  //MIME type
1111
          PrintWriter out = response.getWriter();
1112

    
1113
          // Look up the document type
1114
          String doctype = doc.getDoctype();
1115
          // Transform the document to the new doctype
1116
          DBTransform dbt = new DBTransform();
1117
          dbt.transformXMLDocument(doc.toString(),
1118
                                   doctype,"-//W3C//HTML//EN", qformat, out);
1119
        }
1120

    
1121
      }
1122
    }
1123
    catch (Exception except)
1124
    {
1125
      throw except;
1126

    
1127
    }
1128

    
1129
  }
1130

    
1131
  // read data from URLConnection
1132
  private void readFromURLConnection(HttpServletResponse response, String docid)
1133
               throws IOException, MalformedURLException
1134
  {
1135
    ServletOutputStream out = response.getOutputStream();
1136
    String contentType = getServletContext().getMimeType(docid); //MIME type
1137
    if (contentType == null) {
1138
      if (docid.endsWith(".xml")) {
1139
        contentType="text/xml";
1140
      } else if (docid.endsWith(".css")) {
1141
        contentType="text/css";
1142
      } else if (docid.endsWith(".dtd")) {
1143
        contentType="text/plain";
1144
      } else if (docid.endsWith(".xsd")) {
1145
        contentType="text/xml";
1146
      } else if (docid.endsWith("/")) {
1147
        contentType="text/html";
1148
      } else {
1149
        File f = new File(docid);
1150
        if ( f.isDirectory() ) {
1151
          contentType="text/html";
1152
        } else {
1153
          contentType="application/octet-stream";
1154
        }
1155
      }
1156
    }
1157
    response.setContentType(contentType);
1158
    // if we decide to use "application/octet-stream" for all data returns
1159
    // response.setContentType("application/octet-stream");
1160

    
1161
    // this is http url
1162
    URL url = new URL(docid);
1163
    BufferedInputStream bis = null;
1164
    try {
1165
      bis = new BufferedInputStream(url.openStream());
1166
      byte[] buf = new byte[4 * 1024]; // 4K buffer
1167
      int b = bis.read(buf);
1168
      while (b != -1) {
1169
        out.write(buf, 0, b);
1170
        b = bis.read(buf);
1171
      }
1172
    } finally {
1173
      if (bis != null) bis.close();
1174
    }
1175

    
1176
  }
1177

    
1178
  // read file/doc and write to ZipOutputStream
1179
  private void addDocToZip(String docid, ZipOutputStream zout,
1180
                              String user, String[] groups)
1181
               throws ClassNotFoundException, IOException, SQLException,
1182
                      McdbException, Exception
1183
  {
1184
    byte[] bytestring = null;
1185
    ZipEntry zentry = null;
1186

    
1187
    try {
1188
      URL url = new URL(docid);
1189

    
1190
      // this http url; read from URLConnection; add to zip
1191
      zentry = new ZipEntry(docid);
1192
      zout.putNextEntry(zentry);
1193
      BufferedInputStream bis = null;
1194
      try {
1195
        bis = new BufferedInputStream(url.openStream());
1196
        byte[] buf = new byte[4 * 1024]; // 4K buffer
1197
        int b = bis.read(buf);
1198
        while(b != -1) {
1199
          zout.write(buf, 0, b);
1200
          b = bis.read(buf);
1201
        }
1202
      } finally {
1203
        if (bis != null) bis.close();
1204
      }
1205
      zout.closeEntry();
1206

    
1207
    } catch (MalformedURLException mue) {
1208

    
1209
      // this is metacat doc (data file or metadata doc)
1210

    
1211
      try {
1212

    
1213
        DocumentImpl doc = new DocumentImpl(docid);
1214

    
1215
        //check the permission for read
1216
        if (!doc.hasReadPermission(user, groups, docid))
1217
        {
1218
          Exception e = new Exception("User " + user + " does not have "
1219
                    +"permission to read the document with the docid " + docid);
1220

    
1221
          throw e;
1222
        }
1223

    
1224
        if ( doc.getRootNodeID() == 0 ) {
1225
          // this is data file; add file to zip
1226
          String filepath = util.getOption("datafilepath");
1227
          if(!filepath.endsWith("/")) {
1228
            filepath += "/";
1229
          }
1230
          String filename = filepath + docid;
1231
          FileInputStream fin = null;
1232
          fin = new FileInputStream(filename);
1233
          try {
1234

    
1235
            zentry = new ZipEntry(docid);
1236
            zout.putNextEntry(zentry);
1237
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1238
            int b = fin.read(buf);
1239
            while (b != -1) {
1240
              zout.write(buf, 0, b);
1241
              b = fin.read(buf);
1242
            }
1243
          } finally {
1244
            if (fin != null) fin.close();
1245
          }
1246
          zout.closeEntry();
1247

    
1248
        } else {
1249
          // this is metadata doc; add doc to zip
1250
          bytestring = doc.toString().getBytes();
1251
          zentry = new ZipEntry(docid + ".xml");
1252
          zentry.setSize(bytestring.length);
1253
          zout.putNextEntry(zentry);
1254
          zout.write(bytestring, 0, bytestring.length);
1255
          zout.closeEntry();
1256
        }
1257
      } catch (Exception except) {
1258
        throw except;
1259

    
1260
      }
1261

    
1262
    }
1263

    
1264
  }
1265

    
1266
  // view abstract within document
1267
  private void viewAbstract(HttpServletResponse response,
1268
                            String abstractpath, String docid)
1269
               throws ClassNotFoundException, IOException, SQLException,
1270
                      McdbException, Exception
1271
  {
1272

    
1273
    PrintWriter out =null;
1274
    try {
1275

    
1276
      response.setContentType("text/html");  //MIME type
1277
      out = response.getWriter();
1278
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid);
1279
      out.println("<html><head><title>Abstract</title></head>");
1280
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
1281
      for (int i=0; i<abstracts.length; i++) {
1282
        out.println("<p>" + (String)abstracts[i] + "</p>");
1283
      }
1284
      out.println("</body></html>");
1285

    
1286
    } catch (Exception e) {
1287
       out.println("<?xml version=\"1.0\"?>");
1288
       out.println("<error>");
1289
       out.println(e.getMessage());
1290
       out.println("</error>");
1291

    
1292

    
1293
    }
1294
  }
1295
  /**
1296
   * If metacat couldn't find a data file or document locally, it will read this
1297
   * docid from its home server. This is for the replication feature
1298
   */
1299
  private void readFromRemoteMetaCat(HttpServletResponse response, String docid,
1300
                     String rev, String user, String password,
1301
                     ServletOutputStream out, boolean zip, ZipOutputStream zout)
1302
                        throws Exception
1303
 {
1304
   // Create a object of RemoteDocument, "" is for zipEntryPath
1305
   RemoteDocument remoteDoc =
1306
                        new RemoteDocument (docid, rev,user, password, "");
1307
   String docType = remoteDoc.getDocType();
1308
   // Only read data file
1309
   if (docType.equals("BIN"))
1310
   {
1311
    // If it is zip format
1312
    if (zip)
1313
    {
1314
      remoteDoc.readDocumentFromRemoteServerByZip(zout);
1315
    }//if
1316
    else
1317
    {
1318
      if (out == null)
1319
      {
1320
        out = response.getOutputStream();
1321
      }//if
1322
      response.setContentType("application/octet-stream");
1323
      remoteDoc.readDocumentFromRemoteServer(out);
1324
    }//else (not zip)
1325
   }//if doctype=bin
1326
   else
1327
   {
1328
     throw new Exception("Docid: "+docid+"."+rev+" couldn't find");
1329
   }//else
1330
 }//readFromRemoteMetaCat
1331

    
1332
  // END OF READ SECTION
1333
  
1334
 
1335
  
1336
  // INSERT/UPDATE SECTION
1337
  /**
1338
   * Handle the database putdocument request and write an XML document
1339
   * to the database connection
1340
   */
1341
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params,
1342
               String user, String[] groups) {
1343

    
1344
    DBConnection dbConn = null;
1345
    int serialNumber = -1;
1346

    
1347
    try {
1348
      // Get the document indicated
1349
      String[] doctext = (String[])params.get("doctext");
1350

    
1351
      String pub = null;
1352
      if (params.containsKey("public")) {
1353
        pub = ((String[])params.get("public"))[0];
1354
      }
1355

    
1356
      StringReader dtd = null;
1357
      if (params.containsKey("dtdtext")) {
1358
        String[] dtdtext = (String[])params.get("dtdtext");
1359
        try {
1360
          if ( !dtdtext[0].equals("") ) {
1361
            dtd = new StringReader(dtdtext[0]);
1362
          }
1363
        } catch (NullPointerException npe) {}
1364
      }
1365

    
1366
      StringReader xml = null;
1367
      boolean validate = false;
1368
      DocumentImplWrapper documentWrapper = null;
1369
      try {
1370
        // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ... >
1371
        // in order to decide whether to use validation parser
1372
        validate = needDTDValidation(doctext[0]);
1373
        if (validate)
1374
        {
1375
          // set a dtd base validation parser
1376
          String rule = DocumentImpl.DTD;
1377
          documentWrapper = new DocumentImplWrapper(rule, validate);
1378
        }
1379
        else if (needSchemaValidation(doctext[0]))
1380
        {
1381
          // set schema base validation parser
1382
          String rule = DocumentImpl.SCHEMA;
1383
          documentWrapper = new DocumentImplWrapper(rule, true);
1384
        }
1385
        else
1386
        {
1387
          documentWrapper = new DocumentImplWrapper("", false);
1388
        }
1389
        
1390
        xml = new StringReader(doctext[0]);
1391

    
1392
        String[] action = (String[])params.get("action");
1393
        String[] docid = (String[])params.get("docid");
1394
        String newdocid = null;
1395

    
1396
        String doAction = null;
1397
        if (action[0].equals("insert")) {
1398
          doAction = "INSERT";
1399
        } else if (action[0].equals("update")) {
1400
          doAction = "UPDATE";
1401
        }
1402

    
1403
        try
1404
        {
1405
          // get a connection from the pool
1406
          dbConn=DBConnectionPool.
1407
                  getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1408
          serialNumber=dbConn.getCheckOutSerialNumber();
1409

    
1410

    
1411
          // write the document to the database
1412
          try
1413
          {
1414
            String accNumber = docid[0];
1415
            MetaCatUtil.debugMessage(""+ doAction + " " + accNumber +"...", 10);
1416
            if (accNumber.equals(""))
1417
            {
1418
              accNumber = null;
1419
            }//if
1420
            newdocid = documentWrapper.write(dbConn, xml, pub, dtd, doAction,
1421
                                          accNumber, user, groups);
1422

    
1423
          }//try
1424
          catch (NullPointerException npe)
1425
          {
1426
            newdocid = documentWrapper.write(dbConn, xml, pub, dtd, doAction,
1427
                                          null, user, groups);
1428
          }//catch
1429
        }//try
1430
        finally
1431
        {
1432
          // Return db connection
1433
          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1434
        }
1435

    
1436
        // set content type and other response header fields first
1437
        //response.setContentType("text/xml");
1438
        out.println("<?xml version=\"1.0\"?>");
1439
        out.println("<success>");
1440
        out.println("<docid>" + newdocid + "</docid>");
1441
        out.println("</success>");
1442

    
1443
      } catch (NullPointerException npe) {
1444
        //response.setContentType("text/xml");
1445
        out.println("<?xml version=\"1.0\"?>");
1446
        out.println("<error>");
1447
        out.println(npe.getMessage());
1448
        out.println("</error>");
1449
      }
1450
    } catch (Exception e) {
1451
      //response.setContentType("text/xml");
1452
      out.println("<?xml version=\"1.0\"?>");
1453
      out.println("<error>");
1454
      out.println(e.getMessage());
1455
      if (e instanceof SAXException) {
1456
        Exception e2 = ((SAXException)e).getException();
1457
        out.println("<error>");
1458
        try
1459
        {
1460
          out.println(e2.getMessage());
1461
        }
1462
        catch(NullPointerException npe)
1463
        {
1464
          out.println(e.getMessage());
1465
        }
1466
        out.println("</error>");
1467
      }
1468
      //e.printStackTrace(out);
1469
      out.println("</error>");
1470
    }
1471
  }
1472

    
1473
  /**
1474
   * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... >
1475
   * in order to decide whether to use validation parser
1476
   */
1477
  private static boolean needDTDValidation(String xmltext) throws IOException {
1478

    
1479
    StringReader xmlreader = new StringReader(xmltext);
1480
    StringBuffer cbuff = new StringBuffer();
1481
    java.util.Stack st = new java.util.Stack();
1482
    boolean validate = false;
1483
    int c;
1484
    int inx;
1485

    
1486
    // read from the stream until find the keywords
1487
    while ( (st.empty() || st.size()<4) && ((c = xmlreader.read()) != -1) ) {
1488
      cbuff.append((char)c);
1489

    
1490
      // "<!DOCTYPE" keyword is found; put it in the stack
1491
      if ( (inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1 ) {
1492
        cbuff = new StringBuffer();
1493
        st.push("<!DOCTYPE");
1494
      }
1495
      // "PUBLIC" keyword is found; put it in the stack
1496
      if ( (inx = cbuff.toString().indexOf("PUBLIC")) != -1 ) {
1497
        cbuff = new StringBuffer();
1498
        st.push("PUBLIC");
1499
      }
1500
      // "SYSTEM" keyword is found; put it in the stack
1501
      if ( (inx = cbuff.toString().indexOf("SYSTEM")) != -1 ) {
1502
        cbuff = new StringBuffer();
1503
        st.push("SYSTEM");
1504
      }
1505
      // ">" character is found; put it in the stack
1506
      // ">" is found twice: fisrt from <?xml ...?>
1507
      // and second from <!DOCTYPE ... >
1508
      if ( (inx = cbuff.toString().indexOf(">")) != -1 ) {
1509
        cbuff = new StringBuffer();
1510
        st.push(">");
1511
      }
1512
    }
1513

    
1514
    // close the stream
1515
    xmlreader.close();
1516

    
1517
    // check the stack whether it contains the keywords:
1518
    // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1519
    if ( st.size() == 4 ) {
1520
      if ( ((String)st.pop()).equals(">") &&
1521
           ( ((String)st.peek()).equals("PUBLIC") |
1522
             ((String)st.pop()).equals("SYSTEM") ) &&
1523
           ((String)st.pop()).equals("<!DOCTYPE") )  {
1524
        validate = true;
1525
      }
1526
    }
1527

    
1528
    MetaCatUtil.debugMessage("Validation for dtd is " + validate, 10);
1529
    return validate;
1530
  }
1531
  // END OF INSERT/UPDATE SECTION
1532
  
1533
  /* check if the xml string contains key words to specify schema loocation*/
1534
  private boolean needSchemaValidation(String xml)
1535
  {
1536
    boolean needSchemaValidate =false;
1537
    if (xml == null)
1538
    {
1539
      MetaCatUtil.debugMessage("Validation for schema is " +
1540
                               needSchemaValidate, 10);
1541
      return needSchemaValidate;
1542
    }
1543
    else if (xml.indexOf(SCHEMALOCATIONKEYWORD) != -1)
1544
    {
1545
      // if contains schema location key word, should be validate
1546
      needSchemaValidate = true;
1547
    }
1548
    
1549
    MetaCatUtil.debugMessage("Validation for schema is " + 
1550
                             needSchemaValidate, 10);
1551
    return needSchemaValidate;
1552
   
1553
  }
1554
  
1555
  // DELETE SECTION
1556
  /**
1557
   * Handle the database delete request and delete an XML document
1558
   * from the database connection
1559
   */
1560
  private void handleDeleteAction(PrintWriter out, Hashtable params,
1561
               HttpServletResponse response, String user, String[] groups) {
1562

    
1563
    String[] docid = (String[])params.get("docid");
1564

    
1565
    // delete the document from the database
1566
    try {
1567

    
1568
                                      // NOTE -- NEED TO TEST HERE
1569
                                      // FOR EXISTENCE OF DOCID PARAM
1570
                                      // BEFORE ACCESSING ARRAY
1571
      try {
1572
        DocumentImpl.delete(docid[0], user, groups);
1573
        response.setContentType("text/xml");
1574
        out.println("<?xml version=\"1.0\"?>");
1575
        out.println("<success>");
1576
        out.println("Document deleted.");
1577
        out.println("</success>");
1578
      } catch (AccessionNumberException ane) {
1579
        response.setContentType("text/xml");
1580
        out.println("<?xml version=\"1.0\"?>");
1581
        out.println("<error>");
1582
        out.println("Error deleting document!!!");
1583
        out.println(ane.getMessage());
1584
        out.println("</error>");
1585
      }
1586
    } catch (Exception e) {
1587
      response.setContentType("text/xml");
1588
      out.println("<?xml version=\"1.0\"?>");
1589
      out.println("<error>");
1590
      out.println(e.getMessage());
1591
      out.println("</error>");
1592
    }
1593
  }
1594
  // END OF DELETE SECTION
1595

    
1596
  // VALIDATE SECTION
1597
  /**
1598
   * Handle the validation request and return the results to the requestor
1599
   */
1600
  private void handleValidateAction(PrintWriter out, Hashtable params) {
1601

    
1602
    // Get the document indicated
1603
    String valtext = null;
1604
    DBConnection dbConn = null;
1605
    int serialNumber = -1;
1606

    
1607
    try {
1608
      valtext = ((String[])params.get("valtext"))[0];
1609
    } catch (Exception nullpe) {
1610

    
1611

    
1612
      String docid = null;
1613
      try {
1614
        // Find the document id number
1615
        docid = ((String[])params.get("docid"))[0];
1616

    
1617

    
1618
        // Get the document indicated from the db
1619
        DocumentImpl xmldoc = new DocumentImpl(docid);
1620
        valtext = xmldoc.toString();
1621

    
1622
      } catch (NullPointerException npe) {
1623

    
1624
        out.println("<error>Error getting document ID: " + docid + "</error>");
1625
        //if ( conn != null ) { util.returnConnection(conn); }
1626
        return;
1627
      } catch (Exception e) {
1628

    
1629
        out.println(e.getMessage());
1630
      }
1631
    }
1632

    
1633

    
1634
    try {
1635
      // get a connection from the pool
1636
      dbConn=DBConnectionPool.
1637
                  getDBConnection("MetaCatServlet.handleValidateAction");
1638
      serialNumber=dbConn.getCheckOutSerialNumber();
1639
      DBValidate valobj = new DBValidate(saxparser,dbConn);
1640
      boolean valid = valobj.validateString(valtext);
1641

    
1642
      // set content type and other response header fields first
1643

    
1644
      out.println(valobj.returnErrors());
1645

    
1646
    } catch (NullPointerException npe2) {
1647
      // set content type and other response header fields first
1648

    
1649
      out.println("<error>Error validating document.</error>");
1650
    } catch (Exception e) {
1651

    
1652
      out.println(e.getMessage());
1653
    } finally {
1654
      // Return db connection
1655
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1656
    }
1657
  }
1658
  // END OF VALIDATE SECTION
1659

    
1660
  // OTHER ACTION HANDLERS
1661

    
1662
  /**
1663
   * Handle "getrevsionanddoctype" action
1664
   * Given a docid, return it's current revision and doctype from data base
1665
   * The output is String look like "rev;doctype"
1666
   */
1667
  private void handleGetRevisionAndDocTypeAction(PrintWriter out,
1668
                                                              Hashtable params)
1669
  {
1670
    // To store doc parameter
1671
    String [] docs = new String[10];
1672
    // Store a single doc id
1673
    String givenDocId = null;
1674
    // Get docid from parameters
1675
    if (params.containsKey("docid"))
1676
    {
1677
      docs = (String[])params.get("docid");
1678
    }
1679
    // Get first docid form string array
1680
    givenDocId = docs[0];
1681

    
1682
    try
1683
    {
1684
      // Make sure there is a docid
1685
      if (givenDocId == null || givenDocId.equals(""))
1686
      {
1687
        throw new Exception("User didn't specify docid!");
1688
      }//if
1689

    
1690
      // Create a DBUtil object
1691
      DBUtil dbutil = new DBUtil();
1692
      // Get a rev and doctype
1693
      String revAndDocType =
1694
                dbutil.getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
1695
      out.println(revAndDocType);
1696

    
1697
    }//try
1698
    catch (Exception e)
1699
    {
1700
      // Handle exception
1701
      out.println("<?xml version=\"1.0\"?>");
1702
      out.println("<error>");
1703
      out.println(e.getMessage());
1704
      out.println("</error>");
1705
    }//catch
1706

    
1707
  }//handleGetRevisionAndDocTypeAction
1708

    
1709
  /**
1710
   * Handle "getaccesscontrol" action.
1711
   * Read Access Control List from db connection in XML format
1712
   */
1713
  private void handleGetAccessControlAction(PrintWriter out, Hashtable params,
1714
                                       HttpServletResponse response,
1715
                                       String username, String[] groupnames) {
1716

    
1717
    DBConnection dbConn = null;
1718
    int serialNumber = -1;
1719
    String docid = ((String[])params.get("docid"))[0];
1720

    
1721
    try {
1722

    
1723
        // get connection from the pool
1724
        dbConn=DBConnectionPool.
1725
                 getDBConnection("MetaCatServlet.handleGetAccessControlAction");
1726
        serialNumber=dbConn.getCheckOutSerialNumber();
1727
        AccessControlList aclobj = new AccessControlList(dbConn);
1728
        String acltext = aclobj.getACL(docid, username, groupnames);
1729
        out.println(acltext);
1730

    
1731
    } catch (Exception e) {
1732
      out.println("<?xml version=\"1.0\"?>");
1733
      out.println("<error>");
1734
      out.println(e.getMessage());
1735
      out.println("</error>");
1736
    } finally {
1737
      // Retrun db connection to pool
1738
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1739
    }
1740

    
1741
  }
1742

    
1743
  /**
1744
   * Handle the "getprincipals" action.
1745
   * Read all principals from authentication scheme in XML format
1746
   */
1747
  private void handleGetPrincipalsAction(PrintWriter out, String user,
1748
                                         String password) {
1749

    
1750

    
1751
    try {
1752

    
1753

    
1754
        AuthSession auth = new AuthSession();
1755
        String principals = auth.getPrincipals(user, password);
1756
        out.println(principals);
1757

    
1758
    } catch (Exception e) {
1759
      out.println("<?xml version=\"1.0\"?>");
1760
      out.println("<error>");
1761
      out.println(e.getMessage());
1762
      out.println("</error>");
1763
    }
1764

    
1765
  }
1766

    
1767
  /**
1768
   * Handle "getdoctypes" action.
1769
   * Read all doctypes from db connection in XML format
1770
   */
1771
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
1772
                                       HttpServletResponse response) {
1773

    
1774

    
1775
    try {
1776

    
1777

    
1778
        DBUtil dbutil = new DBUtil();
1779
        String doctypes = dbutil.readDoctypes();
1780
        out.println(doctypes);
1781

    
1782
    } catch (Exception e) {
1783
      out.println("<?xml version=\"1.0\"?>");
1784
      out.println("<error>");
1785
      out.println(e.getMessage());
1786
      out.println("</error>");
1787
    }
1788

    
1789
  }
1790

    
1791
  /**
1792
   * Handle the "getdtdschema" action.
1793
   * Read DTD or Schema file for a given doctype from Metacat catalog system
1794
   */
1795
  private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
1796
                                        HttpServletResponse response) {
1797

    
1798

    
1799
    String doctype = null;
1800
    String[] doctypeArr = (String[])params.get("doctype");
1801

    
1802
    // get only the first doctype specified in the list of doctypes
1803
    // it could be done for all doctypes in that list
1804
    if (doctypeArr != null) {
1805
        doctype = ((String[])params.get("doctype"))[0];
1806
    }
1807

    
1808
    try {
1809

    
1810

    
1811
        DBUtil dbutil = new DBUtil();
1812
        String dtdschema = dbutil.readDTDSchema(doctype);
1813
        out.println(dtdschema);
1814

    
1815
    } catch (Exception e) {
1816
      out.println("<?xml version=\"1.0\"?>");
1817
      out.println("<error>");
1818
      out.println(e.getMessage());
1819
      out.println("</error>");
1820
    }
1821

    
1822
  }
1823

    
1824
  /**
1825
   * Handle the "getdataguide" action.
1826
   * Read Data Guide for a given doctype from db connection in XML format
1827
   */
1828
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params,
1829
                                        HttpServletResponse response) {
1830

    
1831

    
1832
    String doctype = null;
1833
    String[] doctypeArr = (String[])params.get("doctype");
1834

    
1835
    // get only the first doctype specified in the list of doctypes
1836
    // it could be done for all doctypes in that list
1837
    if (doctypeArr != null) {
1838
        doctype = ((String[])params.get("doctype"))[0];
1839
    }
1840

    
1841
    try {
1842

    
1843

    
1844
        DBUtil dbutil = new DBUtil();
1845
        String dataguide = dbutil.readDataGuide(doctype);
1846
        out.println(dataguide);
1847

    
1848
    } catch (Exception e) {
1849
      out.println("<?xml version=\"1.0\"?>");
1850
      out.println("<error>");
1851
      out.println(e.getMessage());
1852
      out.println("</error>");
1853
    }
1854

    
1855
  }
1856

    
1857
  /**
1858
   * Handle the "getlastdocid" action.
1859
   * Get the latest docid with rev number from db connection in XML format
1860
   */
1861
  private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
1862
                                        HttpServletResponse response) {
1863

    
1864

    
1865
    String scope = ((String[])params.get("scope"))[0];
1866
    if (scope == null) {
1867
        scope = ((String[])params.get("username"))[0];
1868
    }
1869

    
1870
    try {
1871

    
1872

    
1873
        DBUtil dbutil = new DBUtil();
1874
        String lastDocid = dbutil.getMaxDocid(scope);
1875
        out.println("<?xml version=\"1.0\"?>");
1876
        out.println("<lastDocid>");
1877
        out.println("  <scope>" + scope + "</scope>");
1878
        out.println("  <docid>" + lastDocid + "</docid>");
1879
        out.println("</lastDocid>");
1880

    
1881
    } catch (Exception e) {
1882
      out.println("<?xml version=\"1.0\"?>");
1883
      out.println("<error>");
1884
      out.println(e.getMessage());
1885
      out.println("</error>");
1886
    }
1887

    
1888
  }
1889

    
1890
  /**
1891
   * Handle documents passed to metacat that are encoded using the
1892
   * "multipart/form-data" mime type.  This is typically used for uploading
1893
   * data files which may be binary and large.
1894
   */
1895
  private void handleMultipartForm(HttpServletRequest request,
1896
                                   HttpServletResponse response)
1897
  {
1898
    PrintWriter out = null;
1899
    String action = null;
1900

    
1901
    // Parse the multipart form, and save the parameters in a Hashtable and
1902
    // save the FileParts in a hashtable
1903

    
1904
    Hashtable params = new Hashtable();
1905
    Hashtable fileList = new Hashtable();
1906

    
1907
    try {
1908
      // MBJ: need to put filesize limit in Metacat config (metacat.properties)
1909
      MultipartParser mp = new MultipartParser(request, 200*1024*1024); //200MB
1910
      Part part;
1911
      while ((part = mp.readNextPart()) != null) {
1912
        String name = part.getName();
1913

    
1914
        if (part.isParam()) {
1915
          // it's a parameter part
1916
          ParamPart paramPart = (ParamPart) part;
1917
          String value = paramPart.getStringValue();
1918
          params.put(name, value);
1919
          if (name.equals("action")) {
1920
            action = value;
1921
          }
1922
        } else if (part.isFile()) {
1923
          // it's a file part
1924
          FilePart filePart = (FilePart) part;
1925
          fileList.put(name, filePart);
1926

    
1927
          // Stop once the first file part is found, otherwise going onto the
1928
          // next part prevents access to the file contents.  So...for upload
1929
          // to work, the datafile must be the last part
1930
          break;
1931
        }
1932
      }
1933
    } catch (IOException ioe) {
1934
      try {
1935
        out = response.getWriter();
1936
      } catch (IOException ioe2) {
1937
        System.err.println("Fatal Error: couldn't get response output stream.");
1938
      }
1939
      out.println("<?xml version=\"1.0\"?>");
1940
      out.println("<error>");
1941
      out.println("Error: problem reading multipart data.");
1942
      out.println("</error>");
1943
    }
1944

    
1945
    // Get the session information
1946
    String username = null;
1947
    String password = null;
1948
    String[] groupnames = null;
1949
    String sess_id = null;
1950

    
1951
    // be aware of session expiration on every request
1952
    HttpSession sess = request.getSession(true);
1953
    if (sess.isNew()) {
1954
      // session expired or has not been stored b/w user requests
1955
      username = "public";
1956
      sess.setAttribute("username", username);
1957
    } else {
1958
      username = (String)sess.getAttribute("username");
1959
      password = (String)sess.getAttribute("password");
1960
      groupnames = (String[])sess.getAttribute("groupnames");
1961
      try {
1962
        sess_id = (String)sess.getId();
1963
      } catch(IllegalStateException ise) {
1964
        System.out.println("error in  handleMultipartForm: this shouldn't " +
1965
                           "happen: the session should be valid: " +
1966
                           ise.getMessage());
1967
      }
1968
    }
1969

    
1970
    // Get the out stream
1971
    try {
1972
          out = response.getWriter();
1973
        } catch (IOException ioe2) {
1974
          util.debugMessage("Fatal Error: couldn't get response "+
1975
                                                              "output stream.");
1976
        }
1977

    
1978
    if ( action.equals("upload")) {
1979
      if (username != null &&  !username.equals("public")) {
1980
        handleUploadAction(request, out, params, fileList,
1981
                           username, groupnames);
1982
      } else {
1983

    
1984
        out.println("<?xml version=\"1.0\"?>");
1985
        out.println("<error>");
1986
        out.println("Permission denied for " + action);
1987
        out.println("</error>");
1988
      }
1989
    } else {
1990
      /*try {
1991
        out = response.getWriter();
1992
      } catch (IOException ioe2) {
1993
        System.err.println("Fatal Error: couldn't get response output stream.");
1994
      }*/
1995
      out.println("<?xml version=\"1.0\"?>");
1996
      out.println("<error>");
1997
      out.println("Error: action not registered.  Please report this error.");
1998
      out.println("</error>");
1999
    }
2000
    out.close();
2001
  }
2002

    
2003
  /**
2004
   * Handle the upload action by saving the attached file to disk and
2005
   * registering it in the Metacat db
2006
   */
2007
  private void handleUploadAction(HttpServletRequest request,
2008
                                  PrintWriter out,
2009
                                  Hashtable params, Hashtable fileList,
2010
                                  String username, String[] groupnames)
2011
  {
2012
    //PrintWriter out = null;
2013
    //Connection conn = null;
2014
    String action = null;
2015
    String docid = null;
2016

    
2017
    /*response.setContentType("text/xml");
2018
    try
2019
    {
2020
      out = response.getWriter();
2021
    }
2022
    catch (IOException ioe2)
2023
    {
2024
      System.err.println("Fatal Error: couldn't get response output stream.");
2025
    }*/
2026

    
2027
    if (params.containsKey("docid"))
2028
    {
2029
      docid = (String)params.get("docid");
2030
    }
2031

    
2032
    // Make sure we have a docid and datafile
2033
    if (docid != null && fileList.containsKey("datafile")) {
2034

    
2035
      // Get a reference to the file part of the form
2036
      FilePart filePart = (FilePart)fileList.get("datafile");
2037
      String fileName = filePart.getFileName();
2038
      MetaCatUtil.debugMessage("Uploading filename: " + fileName, 10);
2039

    
2040
      // Check if the right file existed in the uploaded data
2041
      if (fileName != null) {
2042

    
2043
        try
2044
        {
2045
           //MetaCatUtil.debugMessage("Upload datafile " + docid +"...", 10);
2046
           //If document get lock data file grant
2047
           if (DocumentImpl.getDataFileLockGrant(docid))
2048
           {
2049
              // register the file in the database (which generates an exception
2050
              //if the docid is not acceptable or other untoward things happen
2051
              DocumentImpl.registerDocument(fileName, "BIN", docid, username);
2052

    
2053
              // Save the data file to disk using "docid" as the name
2054
              dataDirectory.mkdirs();
2055
              File newFile = new File(dataDirectory, docid);
2056
              long size = filePart.writeTo(newFile);
2057

    
2058
              // Force replication this data file
2059
              // To data file, "insert" and update is same
2060
              // The fourth parameter is null. Because it is notification server
2061
              // and this method is in MetaCatServerlet. It is original command,
2062
              // not get force replication info from another metacat
2063
              ForceReplicationHandler frh = new ForceReplicationHandler
2064
                                                (docid, "insert", false, null);
2065

    
2066
              // set content type and other response header fields first
2067
              out.println("<?xml version=\"1.0\"?>");
2068
              out.println("<success>");
2069
              out.println("<docid>" + docid + "</docid>");
2070
              out.println("<size>" + size + "</size>");
2071
              out.println("</success>");
2072
          }//if
2073

    
2074
        } //try
2075
        catch (Exception e)
2076
        {
2077
          out.println("<?xml version=\"1.0\"?>");
2078
          out.println("<error>");
2079
          out.println(e.getMessage());
2080
          out.println("</error>");
2081
        }
2082

    
2083
      }
2084
      else
2085
      {
2086
        // the field did not contain a file
2087
        out.println("<?xml version=\"1.0\"?>");
2088
        out.println("<error>");
2089
        out.println("The uploaded data did not contain a valid file.");
2090
        out.println("</error>");
2091
      }
2092
    }
2093
    else
2094
    {
2095
      // Error bcse docid missing or file missing
2096
      out.println("<?xml version=\"1.0\"?>");
2097
      out.println("<error>");
2098
      out.println("The uploaded data did not contain a valid docid " +
2099
                  "or valid file.");
2100
      out.println("</error>");
2101
    }
2102
  }
2103
  
2104
  /*
2105
   * A method to handle set access action
2106
   */
2107
  private void handleSetAccessAction(PrintWriter out,
2108
                                   Hashtable params,
2109
                                   String username)
2110
  {
2111
    String [] docList        = null;
2112
    String [] principalList  = null;
2113
    String [] permissionList = null;
2114
    String [] permTypeList   = null;
2115
    String [] permOrderList  = null;
2116
    String permission = null;
2117
    String permType   = null;
2118
    String permOrder  = null;
2119
    Vector errorList  = new Vector();
2120
    String error      = null;
2121
    Vector successList = new Vector();
2122
    String success    = null;
2123
   
2124
    
2125
    // Get parameters
2126
    if (params.containsKey("docid")) 
2127
    {
2128
      docList = (String[])params.get("docid");
2129
    }
2130
    if (params.containsKey("principal"))
2131
    {
2132
      principalList = (String[])params.get("principal"); 
2133
    }
2134
    if (params.containsKey("permission"))
2135
    {
2136
      permissionList = (String[])params.get("permission");
2137
      
2138
    }
2139
    if (params.containsKey("permType"))
2140
    {
2141
      permTypeList = (String[])params.get("permType");
2142
    
2143
    }
2144
    if (params.containsKey("permOrder"))
2145
    {
2146
      permOrderList = (String[])params.get("permOrder");
2147
     
2148
    }
2149
   
2150
    // Make sure the parameter is not null
2151
    if (docList == null || principalList == null || permTypeList == null ||
2152
        permissionList == null)
2153
    {
2154
      error = "Please check your parameter list, it should look like: "+
2155
              "?action=setaccess&docid=pipeline.1.1&principal=public" +
2156
              "&permission=read&permType=allow&permOrder=allowFirst";
2157
      errorList.addElement(error);
2158
      outputResponse(successList, errorList, out);
2159
      return;
2160
    }
2161
    
2162
    // Only select first element for permission, type and order
2163
    permission = permissionList[0];
2164
    permType = permTypeList[0];
2165
    if (permOrderList != null)
2166
    {
2167
       permOrder = permOrderList[0];
2168
    }
2169
    
2170
    // Get package doctype set
2171
    Vector packageSet =MetaCatUtil.getOptionList(
2172
                                    MetaCatUtil.getOption("packagedoctypeset"));
2173
    //debug
2174
    if (packageSet != null)
2175
    {
2176
      for (int i = 0; i<packageSet.size(); i++)
2177
      {
2178
        MetaCatUtil.debugMessage("doctype in package set: " + 
2179
                              (String)packageSet.elementAt(i), 34);
2180
      }
2181
    }//if
2182
    
2183
    // handle every accessionNumber
2184
    for (int i=0; i <docList.length; i++)
2185
    {
2186
      String accessionNumber = docList[i];
2187
      String owner = null;
2188
      String publicId = null;
2189
      // Get document owner and public id
2190
      try
2191
      {
2192
        owner = getFieldValueForDoc(accessionNumber, "user_owner");
2193
        publicId = getFieldValueForDoc(accessionNumber, "doctype");
2194
      }//try
2195
      catch (Exception e)
2196
      {
2197
        MetaCatUtil.debugMessage("Error in handleSetAccessAction: " +
2198
                                  e.getMessage(), 30);
2199
        error = "Error in set access control for document - " + accessionNumber+
2200
                 e.getMessage();
2201
        errorList.addElement(error);
2202
        continue;
2203
      }
2204
      //check if user is the owner. Only owner can do owner                            
2205
      if (username == null || owner == null || !username.equals(owner))
2206
      {
2207
        error = "User - " + username + " does not have permission to set " +
2208
                "access control for docid - " + accessionNumber;
2209
        errorList.addElement(error);
2210
        continue;
2211
      }
2212
      
2213
      // If docid publicid is BIN data file or other beta4, 6 package document
2214
      // we could not do set access control. Because we don't want inconsistent
2215
      // to its access docuemnt
2216
      if (publicId!=null && packageSet!=null && packageSet.contains(publicId))
2217
      {
2218
        error = "Could not set access control to document "+ accessionNumber +
2219
                "because it is in a pakcage and it has a access file for it";
2220
        errorList.addElement(error);
2221
        continue;
2222
      }
2223
      
2224
      // for every principle
2225
      for (int j = 0; j<principalList.length; j++)
2226
      {
2227
        String principal = principalList[j];
2228
        try
2229
        {
2230
          //insert permission
2231
          AccessControlForSingleFile accessControl = new 
2232
                           AccessControlForSingleFile(accessionNumber,
2233
                                    principal, permission, permType, permOrder);
2234
          accessControl.insertPermissions();
2235
          success = "Set access control to document "+ accessionNumber +
2236
                    " successfully";
2237
          successList.addElement(success);
2238
        }
2239
        catch (Exception ee)
2240
        {
2241
          MetaCatUtil.debugMessage("Erorr in handleSetAccessAction2: " +
2242
                                   ee.getMessage(), 30);
2243
          error = "Faild to set access control for document " + 
2244
                  accessionNumber + " because " + ee.getMessage();
2245
          errorList.addElement(error);
2246
          continue;
2247
        }
2248
      }//for every principle
2249
    }//for every document 
2250
    outputResponse(successList, errorList, out);
2251
  }//handleSetAccessAction
2252
  
2253
 
2254
  /*
2255
   * A method try to determin a docid's public id, if couldn't find null
2256
   * will be returned.
2257
   */
2258
  private String getFieldValueForDoc(String accessionNumber, String fieldName) 
2259
                                      throws Exception
2260
  {
2261
    if (accessionNumber==null || accessionNumber.equals("") ||fieldName == null
2262
        || fieldName.equals(""))
2263
    {
2264
      throw new Exception("Docid or field name was not specified");
2265
    }
2266
    
2267
    PreparedStatement pstmt = null;
2268
    ResultSet rs = null;
2269
    String fieldValue = null;
2270
    String docId = null;
2271
    DBConnection conn = null;
2272
    int serialNumber = -1;
2273
    
2274
    // get rid of revision if access number has
2275
    docId = MetaCatUtil.getDocIdFromString(accessionNumber);
2276
    try
2277
    {
2278
      //check out DBConnection
2279
      conn=DBConnectionPool.getDBConnection("MetaCatServlet.getPublicIdForDoc");
2280
      serialNumber=conn.getCheckOutSerialNumber();
2281
      pstmt = conn.prepareStatement(
2282
            "SELECT " + fieldName + " FROM xml_documents " +
2283
            "WHERE docid = ? ");
2284
          
2285
      pstmt.setString(1, docId);
2286
      pstmt.execute();
2287
      rs = pstmt.getResultSet();
2288
      boolean hasRow = rs.next();
2289
      int perm = 0;
2290
      if ( hasRow ) 
2291
      {
2292
        fieldValue = rs.getString(1);
2293
      }
2294
      else
2295
      {
2296
        throw new Exception("Could not find document: "+accessionNumber);
2297
      }
2298
    }//try
2299
    catch (Exception e)
2300
    {
2301
      MetaCatUtil.debugMessage("Exception in MetacatServlet.getPublicIdForDoc: "
2302
                               + e.getMessage(), 30);
2303
      throw e;
2304
    }
2305
    finally
2306
    {
2307
      try
2308
      {
2309
        rs.close();
2310
        pstmt.close();
2311
        
2312
      }
2313
      finally
2314
      {
2315
        DBConnectionPool.returnDBConnection(conn, serialNumber);
2316
      }
2317
    }
2318
    return fieldValue;
2319
  }//getFieldValueForDoc
2320
  
2321
  /*
2322
   * A method to output setAccess action result
2323
   */
2324
  private void outputResponse(Vector successList, 
2325
                              Vector errorList,
2326
                              PrintWriter out)
2327
  {
2328
    boolean error = false;
2329
    boolean success = false;
2330
    // Output prolog
2331
    out.println(PROLOG);
2332
    // output success message
2333
    if ( successList != null)
2334
    {
2335
      for (int i = 0; i<successList.size(); i++)
2336
      {
2337
        out.println(SUCCESS);
2338
        out.println((String)successList.elementAt(i));
2339
        out.println(SUCCESSCLOSE);
2340
        success = true;
2341
      }//for
2342
    }//if
2343
    // output error message
2344
    if (errorList != null)
2345
    {
2346
      for (int i = 0; i<errorList.size(); i++)
2347
      {
2348
        out.println(ERROR);
2349
        out.println((String)errorList.elementAt(i));
2350
        out.println(ERRORCLOSE);
2351
        error = true;
2352
      }//for
2353
    }//if
2354
    
2355
    // if no error and no success info, send a error that nothing happened
2356
    if( !error && !success)
2357
    {
2358
      out.println(ERROR);
2359
      out.println("Nothing happend for setaccess action");
2360
      out.println(ERRORCLOSE);
2361
    }
2362
    
2363
  }//outputResponse
2364
}
(34-34/49)