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-01-28 12:29:26 -0800 (Tue, 28 Jan 2003) $'
11
 * '$Revision: 1377 $'
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

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

    
135
      util = new MetaCatUtil();
136

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

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

    
149

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

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

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

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

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

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

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

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

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

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

    
211

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

    
218

    
219
      while (paramlist.hasMoreElements()) {
220

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

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

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

    
237

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

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

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

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

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

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

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

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

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

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

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

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

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

    
468
      try {
469

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

    
475
      } catch(Exception e) {
476

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

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

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

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

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

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

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

    
510
      try {
511

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

    
517
      } catch(Exception e) {
518

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

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

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

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

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

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

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

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

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

    
637
    try
638
    {
639

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

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

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

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

    
669
    try {
670

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

    
676
    }
677
    catch(Exception e)
678
    {
679

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

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

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

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

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

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

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

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

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

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

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

    
811
    }//catch
812

    
813
  }//handleExportAction
814

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

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

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

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

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

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

    
900
      } /* end for */
901

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

    
907

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

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

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

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

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

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

    
1020
      }
1021

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

    
1027
  }
1028

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

    
1037
    try {
1038

    
1039

    
1040
      DocumentImpl doc = new DocumentImpl(docid);
1041

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

    
1048
        throw e;
1049
      }
1050

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

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

    
1087
        try {
1088

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

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

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

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

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

    
1126
    }
1127

    
1128
  }
1129

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

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

    
1175
  }
1176

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

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

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

    
1206
    } catch (MalformedURLException mue) {
1207

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

    
1210
      try {
1211

    
1212
        DocumentImpl doc = new DocumentImpl(docid);
1213

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

    
1220
          throw e;
1221
        }
1222

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

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

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

    
1259
      }
1260

    
1261
    }
1262

    
1263
  }
1264

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

    
1272
    PrintWriter out =null;
1273
    try {
1274

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

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

    
1291

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

    
1331
  // END OF READ SECTION
1332

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

    
1341
    DBConnection dbConn = null;
1342
    int serialNumber = -1;
1343

    
1344
    try {
1345
      // Get the document indicated
1346
      String[] doctext = (String[])params.get("doctext");
1347

    
1348
      String pub = null;
1349
      if (params.containsKey("public")) {
1350
        pub = ((String[])params.get("public"))[0];
1351
      }
1352

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

    
1363
      StringReader xml = null;
1364
      boolean validate = false;
1365
      try {
1366
        // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ... >
1367
        // in order to decide whether to use validation parser
1368
        validate = validateXML(doctext[0]);
1369
        xml = new StringReader(doctext[0]);
1370

    
1371
        String[] action = (String[])params.get("action");
1372
        String[] docid = (String[])params.get("docid");
1373
        String newdocid = null;
1374

    
1375
        String doAction = null;
1376
        if (action[0].equals("insert")) {
1377
          doAction = "INSERT";
1378
        } else if (action[0].equals("update")) {
1379
          doAction = "UPDATE";
1380
        }
1381

    
1382
        try
1383
        {
1384
          // get a connection from the pool
1385
          dbConn=DBConnectionPool.
1386
                  getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1387
          serialNumber=dbConn.getCheckOutSerialNumber();
1388

    
1389

    
1390
          // write the document to the database
1391
          try
1392
          {
1393
            String accNumber = docid[0];
1394
            MetaCatUtil.debugMessage(""+ doAction + " " + accNumber +"...", 10);
1395
            if (accNumber.equals(""))
1396
            {
1397
              accNumber = null;
1398
            }//if
1399
            newdocid = DocumentImpl.write(dbConn, xml, pub, dtd, doAction,
1400
                                          accNumber, user, groups, validate);
1401

    
1402
          }//try
1403
          catch (NullPointerException npe)
1404
          {
1405
            newdocid = DocumentImpl.write(dbConn, xml, pub, dtd, doAction,
1406
                                          null, user, groups, validate);
1407
          }//catch
1408
        }//try
1409
        finally
1410
        {
1411
          // Return db connection
1412
          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1413
        }
1414

    
1415
        // set content type and other response header fields first
1416
        //response.setContentType("text/xml");
1417
        out.println("<?xml version=\"1.0\"?>");
1418
        out.println("<success>");
1419
        out.println("<docid>" + newdocid + "</docid>");
1420
        out.println("</success>");
1421

    
1422
      } catch (NullPointerException npe) {
1423
        //response.setContentType("text/xml");
1424
        out.println("<?xml version=\"1.0\"?>");
1425
        out.println("<error>");
1426
        out.println(npe.getMessage());
1427
        out.println("</error>");
1428
      }
1429
    } catch (Exception e) {
1430
      //response.setContentType("text/xml");
1431
      out.println("<?xml version=\"1.0\"?>");
1432
      out.println("<error>");
1433
      out.println(e.getMessage());
1434
      if (e instanceof SAXException) {
1435
        Exception e2 = ((SAXException)e).getException();
1436
        out.println("<error>");
1437
        try
1438
        {
1439
          out.println(e2.getMessage());
1440
        }
1441
        catch(NullPointerException npe)
1442
        {
1443
          out.println(e.getMessage());
1444
        }
1445
        out.println("</error>");
1446
      }
1447
      //e.printStackTrace(out);
1448
      out.println("</error>");
1449
    }
1450
  }
1451

    
1452
  /**
1453
   * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... >
1454
   * in order to decide whether to use validation parser
1455
   */
1456
  private static boolean validateXML(String xmltext) throws IOException {
1457

    
1458
    StringReader xmlreader = new StringReader(xmltext);
1459
    StringBuffer cbuff = new StringBuffer();
1460
    java.util.Stack st = new java.util.Stack();
1461
    boolean validate = false;
1462
    int c;
1463
    int inx;
1464

    
1465
    // read from the stream until find the keywords
1466
    while ( (st.empty() || st.size()<4) && ((c = xmlreader.read()) != -1) ) {
1467
      cbuff.append((char)c);
1468

    
1469
      // "<!DOCTYPE" keyword is found; put it in the stack
1470
      if ( (inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1 ) {
1471
        cbuff = new StringBuffer();
1472
        st.push("<!DOCTYPE");
1473
      }
1474
      // "PUBLIC" keyword is found; put it in the stack
1475
      if ( (inx = cbuff.toString().indexOf("PUBLIC")) != -1 ) {
1476
        cbuff = new StringBuffer();
1477
        st.push("PUBLIC");
1478
      }
1479
      // "SYSTEM" keyword is found; put it in the stack
1480
      if ( (inx = cbuff.toString().indexOf("SYSTEM")) != -1 ) {
1481
        cbuff = new StringBuffer();
1482
        st.push("SYSTEM");
1483
      }
1484
      // ">" character is found; put it in the stack
1485
      // ">" is found twice: fisrt from <?xml ...?>
1486
      // and second from <!DOCTYPE ... >
1487
      if ( (inx = cbuff.toString().indexOf(">")) != -1 ) {
1488
        cbuff = new StringBuffer();
1489
        st.push(">");
1490
      }
1491
    }
1492

    
1493
    // close the stream
1494
    xmlreader.close();
1495

    
1496
    // check the stack whether it contains the keywords:
1497
    // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1498
    if ( st.size() == 4 ) {
1499
      if ( ((String)st.pop()).equals(">") &&
1500
           ( ((String)st.peek()).equals("PUBLIC") |
1501
             ((String)st.pop()).equals("SYSTEM") ) &&
1502
           ((String)st.pop()).equals("<!DOCTYPE") )  {
1503
        validate = true;
1504
      }
1505
    }
1506

    
1507
System.out.println("Validation is " + validate);
1508
    return validate;
1509
  }
1510
  // END OF INSERT/UPDATE SECTION
1511

    
1512
  // DELETE SECTION
1513
  /**
1514
   * Handle the database delete request and delete an XML document
1515
   * from the database connection
1516
   */
1517
  private void handleDeleteAction(PrintWriter out, Hashtable params,
1518
               HttpServletResponse response, String user, String[] groups) {
1519

    
1520
    String[] docid = (String[])params.get("docid");
1521

    
1522
    // delete the document from the database
1523
    try {
1524

    
1525
                                      // NOTE -- NEED TO TEST HERE
1526
                                      // FOR EXISTENCE OF DOCID PARAM
1527
                                      // BEFORE ACCESSING ARRAY
1528
      try {
1529
        DocumentImpl.delete(docid[0], user, groups);
1530
        response.setContentType("text/xml");
1531
        out.println("<?xml version=\"1.0\"?>");
1532
        out.println("<success>");
1533
        out.println("Document deleted.");
1534
        out.println("</success>");
1535
      } catch (AccessionNumberException ane) {
1536
        response.setContentType("text/xml");
1537
        out.println("<?xml version=\"1.0\"?>");
1538
        out.println("<error>");
1539
        out.println("Error deleting document!!!");
1540
        out.println(ane.getMessage());
1541
        out.println("</error>");
1542
      }
1543
    } catch (Exception e) {
1544
      response.setContentType("text/xml");
1545
      out.println("<?xml version=\"1.0\"?>");
1546
      out.println("<error>");
1547
      out.println(e.getMessage());
1548
      out.println("</error>");
1549
    }
1550
  }
1551
  // END OF DELETE SECTION
1552

    
1553
  // VALIDATE SECTION
1554
  /**
1555
   * Handle the validation request and return the results to the requestor
1556
   */
1557
  private void handleValidateAction(PrintWriter out, Hashtable params) {
1558

    
1559
    // Get the document indicated
1560
    String valtext = null;
1561
    DBConnection dbConn = null;
1562
    int serialNumber = -1;
1563

    
1564
    try {
1565
      valtext = ((String[])params.get("valtext"))[0];
1566
    } catch (Exception nullpe) {
1567

    
1568

    
1569
      String docid = null;
1570
      try {
1571
        // Find the document id number
1572
        docid = ((String[])params.get("docid"))[0];
1573

    
1574

    
1575
        // Get the document indicated from the db
1576
        DocumentImpl xmldoc = new DocumentImpl(docid);
1577
        valtext = xmldoc.toString();
1578

    
1579
      } catch (NullPointerException npe) {
1580

    
1581
        out.println("<error>Error getting document ID: " + docid + "</error>");
1582
        //if ( conn != null ) { util.returnConnection(conn); }
1583
        return;
1584
      } catch (Exception e) {
1585

    
1586
        out.println(e.getMessage());
1587
      }
1588
    }
1589

    
1590

    
1591
    try {
1592
      // get a connection from the pool
1593
      dbConn=DBConnectionPool.
1594
                  getDBConnection("MetaCatServlet.handleValidateAction");
1595
      serialNumber=dbConn.getCheckOutSerialNumber();
1596
      DBValidate valobj = new DBValidate(saxparser,dbConn);
1597
      boolean valid = valobj.validateString(valtext);
1598

    
1599
      // set content type and other response header fields first
1600

    
1601
      out.println(valobj.returnErrors());
1602

    
1603
    } catch (NullPointerException npe2) {
1604
      // set content type and other response header fields first
1605

    
1606
      out.println("<error>Error validating document.</error>");
1607
    } catch (Exception e) {
1608

    
1609
      out.println(e.getMessage());
1610
    } finally {
1611
      // Return db connection
1612
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1613
    }
1614
  }
1615
  // END OF VALIDATE SECTION
1616

    
1617
  // OTHER ACTION HANDLERS
1618

    
1619
  /**
1620
   * Handle "getrevsionanddoctype" action
1621
   * Given a docid, return it's current revision and doctype from data base
1622
   * The output is String look like "rev;doctype"
1623
   */
1624
  private void handleGetRevisionAndDocTypeAction(PrintWriter out,
1625
                                                              Hashtable params)
1626
  {
1627
    // To store doc parameter
1628
    String [] docs = new String[10];
1629
    // Store a single doc id
1630
    String givenDocId = null;
1631
    // Get docid from parameters
1632
    if (params.containsKey("docid"))
1633
    {
1634
      docs = (String[])params.get("docid");
1635
    }
1636
    // Get first docid form string array
1637
    givenDocId = docs[0];
1638

    
1639
    try
1640
    {
1641
      // Make sure there is a docid
1642
      if (givenDocId == null || givenDocId.equals(""))
1643
      {
1644
        throw new Exception("User didn't specify docid!");
1645
      }//if
1646

    
1647
      // Create a DBUtil object
1648
      DBUtil dbutil = new DBUtil();
1649
      // Get a rev and doctype
1650
      String revAndDocType =
1651
                dbutil.getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
1652
      out.println(revAndDocType);
1653

    
1654
    }//try
1655
    catch (Exception e)
1656
    {
1657
      // Handle exception
1658
      out.println("<?xml version=\"1.0\"?>");
1659
      out.println("<error>");
1660
      out.println(e.getMessage());
1661
      out.println("</error>");
1662
    }//catch
1663

    
1664
  }//handleGetRevisionAndDocTypeAction
1665

    
1666
  /**
1667
   * Handle "getaccesscontrol" action.
1668
   * Read Access Control List from db connection in XML format
1669
   */
1670
  private void handleGetAccessControlAction(PrintWriter out, Hashtable params,
1671
                                       HttpServletResponse response,
1672
                                       String username, String[] groupnames) {
1673

    
1674
    DBConnection dbConn = null;
1675
    int serialNumber = -1;
1676
    String docid = ((String[])params.get("docid"))[0];
1677

    
1678
    try {
1679

    
1680
        // get connection from the pool
1681
        dbConn=DBConnectionPool.
1682
                 getDBConnection("MetaCatServlet.handleGetAccessControlAction");
1683
        serialNumber=dbConn.getCheckOutSerialNumber();
1684
        AccessControlList aclobj = new AccessControlList(dbConn);
1685
        String acltext = aclobj.getACL(docid, username, groupnames);
1686
        out.println(acltext);
1687

    
1688
    } catch (Exception e) {
1689
      out.println("<?xml version=\"1.0\"?>");
1690
      out.println("<error>");
1691
      out.println(e.getMessage());
1692
      out.println("</error>");
1693
    } finally {
1694
      // Retrun db connection to pool
1695
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1696
    }
1697

    
1698
  }
1699

    
1700
  /**
1701
   * Handle the "getprincipals" action.
1702
   * Read all principals from authentication scheme in XML format
1703
   */
1704
  private void handleGetPrincipalsAction(PrintWriter out, String user,
1705
                                         String password) {
1706

    
1707

    
1708
    try {
1709

    
1710

    
1711
        AuthSession auth = new AuthSession();
1712
        String principals = auth.getPrincipals(user, password);
1713
        out.println(principals);
1714

    
1715
    } catch (Exception e) {
1716
      out.println("<?xml version=\"1.0\"?>");
1717
      out.println("<error>");
1718
      out.println(e.getMessage());
1719
      out.println("</error>");
1720
    }
1721

    
1722
  }
1723

    
1724
  /**
1725
   * Handle "getdoctypes" action.
1726
   * Read all doctypes from db connection in XML format
1727
   */
1728
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
1729
                                       HttpServletResponse response) {
1730

    
1731

    
1732
    try {
1733

    
1734

    
1735
        DBUtil dbutil = new DBUtil();
1736
        String doctypes = dbutil.readDoctypes();
1737
        out.println(doctypes);
1738

    
1739
    } catch (Exception e) {
1740
      out.println("<?xml version=\"1.0\"?>");
1741
      out.println("<error>");
1742
      out.println(e.getMessage());
1743
      out.println("</error>");
1744
    }
1745

    
1746
  }
1747

    
1748
  /**
1749
   * Handle the "getdtdschema" action.
1750
   * Read DTD or Schema file for a given doctype from Metacat catalog system
1751
   */
1752
  private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
1753
                                        HttpServletResponse response) {
1754

    
1755

    
1756
    String doctype = null;
1757
    String[] doctypeArr = (String[])params.get("doctype");
1758

    
1759
    // get only the first doctype specified in the list of doctypes
1760
    // it could be done for all doctypes in that list
1761
    if (doctypeArr != null) {
1762
        doctype = ((String[])params.get("doctype"))[0];
1763
    }
1764

    
1765
    try {
1766

    
1767

    
1768
        DBUtil dbutil = new DBUtil();
1769
        String dtdschema = dbutil.readDTDSchema(doctype);
1770
        out.println(dtdschema);
1771

    
1772
    } catch (Exception e) {
1773
      out.println("<?xml version=\"1.0\"?>");
1774
      out.println("<error>");
1775
      out.println(e.getMessage());
1776
      out.println("</error>");
1777
    }
1778

    
1779
  }
1780

    
1781
  /**
1782
   * Handle the "getdataguide" action.
1783
   * Read Data Guide for a given doctype from db connection in XML format
1784
   */
1785
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params,
1786
                                        HttpServletResponse response) {
1787

    
1788

    
1789
    String doctype = null;
1790
    String[] doctypeArr = (String[])params.get("doctype");
1791

    
1792
    // get only the first doctype specified in the list of doctypes
1793
    // it could be done for all doctypes in that list
1794
    if (doctypeArr != null) {
1795
        doctype = ((String[])params.get("doctype"))[0];
1796
    }
1797

    
1798
    try {
1799

    
1800

    
1801
        DBUtil dbutil = new DBUtil();
1802
        String dataguide = dbutil.readDataGuide(doctype);
1803
        out.println(dataguide);
1804

    
1805
    } catch (Exception e) {
1806
      out.println("<?xml version=\"1.0\"?>");
1807
      out.println("<error>");
1808
      out.println(e.getMessage());
1809
      out.println("</error>");
1810
    }
1811

    
1812
  }
1813

    
1814
  /**
1815
   * Handle the "getlastdocid" action.
1816
   * Get the latest docid with rev number from db connection in XML format
1817
   */
1818
  private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
1819
                                        HttpServletResponse response) {
1820

    
1821

    
1822
    String scope = ((String[])params.get("scope"))[0];
1823
    if (scope == null) {
1824
        scope = ((String[])params.get("username"))[0];
1825
    }
1826

    
1827
    try {
1828

    
1829

    
1830
        DBUtil dbutil = new DBUtil();
1831
        String lastDocid = dbutil.getMaxDocid(scope);
1832
        out.println("<?xml version=\"1.0\"?>");
1833
        out.println("<lastDocid>");
1834
        out.println("  <scope>" + scope + "</scope>");
1835
        out.println("  <docid>" + lastDocid + "</docid>");
1836
        out.println("</lastDocid>");
1837

    
1838
    } catch (Exception e) {
1839
      out.println("<?xml version=\"1.0\"?>");
1840
      out.println("<error>");
1841
      out.println(e.getMessage());
1842
      out.println("</error>");
1843
    }
1844

    
1845
  }
1846

    
1847
  /**
1848
   * Handle documents passed to metacat that are encoded using the
1849
   * "multipart/form-data" mime type.  This is typically used for uploading
1850
   * data files which may be binary and large.
1851
   */
1852
  private void handleMultipartForm(HttpServletRequest request,
1853
                                   HttpServletResponse response)
1854
  {
1855
    PrintWriter out = null;
1856
    String action = null;
1857

    
1858
    // Parse the multipart form, and save the parameters in a Hashtable and
1859
    // save the FileParts in a hashtable
1860

    
1861
    Hashtable params = new Hashtable();
1862
    Hashtable fileList = new Hashtable();
1863

    
1864
    try {
1865
      // MBJ: need to put filesize limit in Metacat config (metacat.properties)
1866
      MultipartParser mp = new MultipartParser(request, 200*1024*1024); //200MB
1867
      Part part;
1868
      while ((part = mp.readNextPart()) != null) {
1869
        String name = part.getName();
1870

    
1871
        if (part.isParam()) {
1872
          // it's a parameter part
1873
          ParamPart paramPart = (ParamPart) part;
1874
          String value = paramPart.getStringValue();
1875
          params.put(name, value);
1876
          if (name.equals("action")) {
1877
            action = value;
1878
          }
1879
        } else if (part.isFile()) {
1880
          // it's a file part
1881
          FilePart filePart = (FilePart) part;
1882
          fileList.put(name, filePart);
1883

    
1884
          // Stop once the first file part is found, otherwise going onto the
1885
          // next part prevents access to the file contents.  So...for upload
1886
          // to work, the datafile must be the last part
1887
          break;
1888
        }
1889
      }
1890
    } catch (IOException ioe) {
1891
      try {
1892
        out = response.getWriter();
1893
      } catch (IOException ioe2) {
1894
        System.err.println("Fatal Error: couldn't get response output stream.");
1895
      }
1896
      out.println("<?xml version=\"1.0\"?>");
1897
      out.println("<error>");
1898
      out.println("Error: problem reading multipart data.");
1899
      out.println("</error>");
1900
    }
1901

    
1902
    // Get the session information
1903
    String username = null;
1904
    String password = null;
1905
    String[] groupnames = null;
1906
    String sess_id = null;
1907

    
1908
    // be aware of session expiration on every request
1909
    HttpSession sess = request.getSession(true);
1910
    if (sess.isNew()) {
1911
      // session expired or has not been stored b/w user requests
1912
      username = "public";
1913
      sess.setAttribute("username", username);
1914
    } else {
1915
      username = (String)sess.getAttribute("username");
1916
      password = (String)sess.getAttribute("password");
1917
      groupnames = (String[])sess.getAttribute("groupnames");
1918
      try {
1919
        sess_id = (String)sess.getId();
1920
      } catch(IllegalStateException ise) {
1921
        System.out.println("error in  handleMultipartForm: this shouldn't " +
1922
                           "happen: the session should be valid: " +
1923
                           ise.getMessage());
1924
      }
1925
    }
1926

    
1927
    // Get the out stream
1928
    try {
1929
          out = response.getWriter();
1930
        } catch (IOException ioe2) {
1931
          util.debugMessage("Fatal Error: couldn't get response "+
1932
                                                              "output stream.");
1933
        }
1934

    
1935
    if ( action.equals("upload")) {
1936
      if (username != null &&  !username.equals("public")) {
1937
        handleUploadAction(request, out, params, fileList,
1938
                           username, groupnames);
1939
      } else {
1940

    
1941
        out.println("<?xml version=\"1.0\"?>");
1942
        out.println("<error>");
1943
        out.println("Permission denied for " + action);
1944
        out.println("</error>");
1945
      }
1946
    } else {
1947
      /*try {
1948
        out = response.getWriter();
1949
      } catch (IOException ioe2) {
1950
        System.err.println("Fatal Error: couldn't get response output stream.");
1951
      }*/
1952
      out.println("<?xml version=\"1.0\"?>");
1953
      out.println("<error>");
1954
      out.println("Error: action not registered.  Please report this error.");
1955
      out.println("</error>");
1956
    }
1957
    out.close();
1958
  }
1959

    
1960
  /**
1961
   * Handle the upload action by saving the attached file to disk and
1962
   * registering it in the Metacat db
1963
   */
1964
  private void handleUploadAction(HttpServletRequest request,
1965
                                  PrintWriter out,
1966
                                  Hashtable params, Hashtable fileList,
1967
                                  String username, String[] groupnames)
1968
  {
1969
    //PrintWriter out = null;
1970
    //Connection conn = null;
1971
    String action = null;
1972
    String docid = null;
1973

    
1974
    /*response.setContentType("text/xml");
1975
    try
1976
    {
1977
      out = response.getWriter();
1978
    }
1979
    catch (IOException ioe2)
1980
    {
1981
      System.err.println("Fatal Error: couldn't get response output stream.");
1982
    }*/
1983

    
1984
    if (params.containsKey("docid"))
1985
    {
1986
      docid = (String)params.get("docid");
1987
    }
1988

    
1989
    // Make sure we have a docid and datafile
1990
    if (docid != null && fileList.containsKey("datafile")) {
1991

    
1992
      // Get a reference to the file part of the form
1993
      FilePart filePart = (FilePart)fileList.get("datafile");
1994
      String fileName = filePart.getFileName();
1995
      MetaCatUtil.debugMessage("Uploading filename: " + fileName, 10);
1996

    
1997
      // Check if the right file existed in the uploaded data
1998
      if (fileName != null) {
1999

    
2000
        try
2001
        {
2002
           //MetaCatUtil.debugMessage("Upload datafile " + docid +"...", 10);
2003
           //If document get lock data file grant
2004
           if (DocumentImpl.getDataFileLockGrant(docid))
2005
           {
2006
              // register the file in the database (which generates an exception
2007
              //if the docid is not acceptable or other untoward things happen
2008
              DocumentImpl.registerDocument(fileName, "BIN", docid, username);
2009

    
2010
              // Save the data file to disk using "docid" as the name
2011
              dataDirectory.mkdirs();
2012
              File newFile = new File(dataDirectory, docid);
2013
              long size = filePart.writeTo(newFile);
2014

    
2015
              // Force replication this data file
2016
              // To data file, "insert" and update is same
2017
              // The fourth parameter is null. Because it is notification server
2018
              // and this method is in MetaCatServerlet. It is original command,
2019
              // not get force replication info from another metacat
2020
              ForceReplicationHandler frh = new ForceReplicationHandler
2021
                                                (docid, "insert", false, null);
2022

    
2023
              // set content type and other response header fields first
2024
              out.println("<?xml version=\"1.0\"?>");
2025
              out.println("<success>");
2026
              out.println("<docid>" + docid + "</docid>");
2027
              out.println("<size>" + size + "</size>");
2028
              out.println("</success>");
2029
          }//if
2030

    
2031
        } //try
2032
        catch (Exception e)
2033
        {
2034
          out.println("<?xml version=\"1.0\"?>");
2035
          out.println("<error>");
2036
          out.println(e.getMessage());
2037
          out.println("</error>");
2038
        }
2039

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