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-03-10 11:59:34 -0800 (Mon, 10 Mar 2003) $'
11
 * '$Revision: 1466 $'
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 = ":schemaLocation";
125
  public static final String NONAMESPACELOCATION = ":noNamespaceSchemaLocation";
126
  public static final String EML2KEYWORD ="<eml:eml";
127

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

    
138
      util = new MetaCatUtil();
139

    
140
      //initial DBConnection pool
141
      connPool = DBConnectionPool.getInstance();
142

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

    
152

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

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

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

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

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

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

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

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

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

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

    
214

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

    
221

    
222
      while (paramlist.hasMoreElements()) {
223

    
224
        name = (String)paramlist.nextElement();
225
        value = request.getParameterValues(name);
226

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

    
237
        params.put(name,value);
238
      }
239

    
240

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

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

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

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

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

    
291
      // aware of session expiration on every request
292
      } else {
293

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

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

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

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

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

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

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

    
471
      try {
472

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

    
478
      } catch(Exception e) {
479

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

    
484
    // any output is returned
485
    }
486
  }
487

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

    
494
    String qformat = ((String[])params.get("qformat"))[0];
495

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

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

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

    
513
      try {
514

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

    
520
      } catch(Exception e) {
521

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

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

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

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

    
587
    resultdoc = createResultDocument(doclist, transformQuery(params));
588

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

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

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

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

    
640
    try
641
    {
642

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

    
646
      return doclist;
647
    }
648
    catch (Exception e)
649
    {
650

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

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

    
672
    try {
673

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

    
679
    }
680
    catch(Exception e)
681
    {
682

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

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

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

    
705
    resultset.append("  <query>" + xmlquery + "</query>");
706

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

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

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

    
741
    String[] docs = new String[10];
742
    String docId = "";
743

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

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

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

    
814
    }//catch
815

    
816
  }//handleExportAction
817

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

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

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

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

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

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

    
903
      } /* end for */
904

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

    
910

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

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

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

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

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

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

    
1023
      }
1024

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

    
1030
  }
1031

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

    
1040
    try {
1041

    
1042

    
1043
      DocumentImpl doc = new DocumentImpl(docid);
1044

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

    
1051
        throw e;
1052
      }
1053

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

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

    
1090
        try {
1091

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

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

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

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

    
1123
      }
1124
    }
1125
    catch (Exception except)
1126
    {
1127
      throw except;
1128

    
1129
    }
1130

    
1131
  }
1132

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

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

    
1178
  }
1179

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

    
1189
    try {
1190
      URL url = new URL(docid);
1191

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

    
1209
    } catch (MalformedURLException mue) {
1210

    
1211
      // this is metacat doc (data file or metadata doc)
1212

    
1213
      try {
1214

    
1215
        DocumentImpl doc = new DocumentImpl(docid);
1216

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

    
1223
          throw e;
1224
        }
1225

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

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

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

    
1262
      }
1263

    
1264
    }
1265

    
1266
  }
1267

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

    
1275
    PrintWriter out =null;
1276
    try {
1277

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

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

    
1294

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

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

    
1346
    DBConnection dbConn = null;
1347
    int serialNumber = -1;
1348

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

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

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

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

    
1404
        String[] action = (String[])params.get("action");
1405
        String[] docid = (String[])params.get("docid");
1406
        String newdocid = null;
1407

    
1408
        String doAction = null;
1409
        if (action[0].equals("insert")) {
1410
          doAction = "INSERT";
1411
        } else if (action[0].equals("update")) {
1412
          doAction = "UPDATE";
1413
        }
1414

    
1415
        try
1416
        {
1417
          // get a connection from the pool
1418
          dbConn=DBConnectionPool.
1419
                  getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1420
          serialNumber=dbConn.getCheckOutSerialNumber();
1421

    
1422

    
1423
          // write the document to the database
1424
          try
1425
          {
1426
            String accNumber = docid[0];
1427
            MetaCatUtil.debugMessage(""+ doAction + " " + accNumber +"...", 10);
1428
            if (accNumber.equals(""))
1429
            {
1430
              accNumber = null;
1431
            }//if
1432
            newdocid = documentWrapper.write(dbConn, xml, pub, dtd, doAction,
1433
                                          accNumber, user, groups);
1434

    
1435
          }//try
1436
          catch (NullPointerException npe)
1437
          {
1438
            newdocid = documentWrapper.write(dbConn, xml, pub, dtd, doAction,
1439
                                          null, user, groups);
1440
          }//catch
1441
        
1442
        }//try
1443
        finally
1444
        {
1445
          // Return db connection
1446
          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1447
        }
1448

    
1449
        // set content type and other response header fields first
1450
        //response.setContentType("text/xml");
1451
        out.println("<?xml version=\"1.0\"?>");
1452
        out.println("<success>");
1453
        out.println("<docid>" + newdocid + "</docid>");
1454
        out.println("</success>");
1455

    
1456
      } 
1457
      catch (NullPointerException npe) 
1458
      {
1459
        //response.setContentType("text/xml");
1460
        out.println("<?xml version=\"1.0\"?>");
1461
        out.println("<error>");
1462
        out.println(npe.getMessage());
1463
        out.println("</error>");
1464
      }
1465
    } 
1466
    catch (Exception e) 
1467
    {
1468
      //response.setContentType("text/xml");
1469
      out.println("<?xml version=\"1.0\"?>");
1470
      out.println("<error>");
1471
      out.println(e.getMessage());
1472
      out.println("</error>");
1473
    }
1474
  }
1475

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

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

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

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

    
1517
    // close the stream
1518
    xmlreader.close();
1519

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

    
1531
    MetaCatUtil.debugMessage("Validation for dtd is " + validate, 10);
1532
    return validate;
1533
  }
1534
  // END OF INSERT/UPDATE SECTION
1535
  
1536
  /* check if the xml string contains key words to specify schema loocation*/
1537
  private boolean needSchemaValidation(String xml)
1538
  {
1539
    boolean needSchemaValidate =false;
1540
    if (xml == null)
1541
    {
1542
      MetaCatUtil.debugMessage("Validation for schema is " +
1543
                               needSchemaValidate, 10);
1544
      return needSchemaValidate;
1545
    }
1546
    else if (xml.indexOf(SCHEMALOCATIONKEYWORD) != -1 ||
1547
             xml.indexOf(NONAMESPACELOCATION) != -1 )
1548
    {
1549
      // if contains schema location key word, should be validate
1550
      needSchemaValidate = true;
1551
    }
1552
    
1553
    MetaCatUtil.debugMessage("Validation for schema is " + 
1554
                             needSchemaValidate, 10);
1555
    return needSchemaValidate;
1556
   
1557
  }
1558
  
1559
   /* check if the xml string contains key words to specify schema loocation*/
1560
  private boolean needEml2Validation(String xml)
1561
  {
1562
    boolean needEml2Validate =false;
1563
    if (xml == null)
1564
    {
1565
      MetaCatUtil.debugMessage("Validation for schema is " +
1566
                               needEml2Validate, 10);
1567
      return needEml2Validate;
1568
    }
1569
    else if (xml.indexOf(EML2KEYWORD) != -1)
1570
    {
1571
      // if contains schema location key word, should be validate
1572
      needEml2Validate = true;
1573
    }
1574
    
1575
    MetaCatUtil.debugMessage("Validation for eml is " + 
1576
                             needEml2Validate, 10);
1577
    return needEml2Validate;
1578
   
1579
  }
1580
  
1581
  // DELETE SECTION
1582
  /**
1583
   * Handle the database delete request and delete an XML document
1584
   * from the database connection
1585
   */
1586
  private void handleDeleteAction(PrintWriter out, Hashtable params,
1587
               HttpServletResponse response, String user, String[] groups) {
1588

    
1589
    String[] docid = (String[])params.get("docid");
1590

    
1591
    // delete the document from the database
1592
    try {
1593

    
1594
                                      // NOTE -- NEED TO TEST HERE
1595
                                      // FOR EXISTENCE OF DOCID PARAM
1596
                                      // BEFORE ACCESSING ARRAY
1597
      try {
1598
        DocumentImpl.delete(docid[0], user, groups);
1599
        response.setContentType("text/xml");
1600
        out.println("<?xml version=\"1.0\"?>");
1601
        out.println("<success>");
1602
        out.println("Document deleted.");
1603
        out.println("</success>");
1604
      } catch (AccessionNumberException ane) {
1605
        response.setContentType("text/xml");
1606
        out.println("<?xml version=\"1.0\"?>");
1607
        out.println("<error>");
1608
        out.println("Error deleting document!!!");
1609
        out.println(ane.getMessage());
1610
        out.println("</error>");
1611
      }
1612
    } catch (Exception e) {
1613
      response.setContentType("text/xml");
1614
      out.println("<?xml version=\"1.0\"?>");
1615
      out.println("<error>");
1616
      out.println(e.getMessage());
1617
      out.println("</error>");
1618
    }
1619
  }
1620
  // END OF DELETE SECTION
1621

    
1622
  // VALIDATE SECTION
1623
  /**
1624
   * Handle the validation request and return the results to the requestor
1625
   */
1626
  private void handleValidateAction(PrintWriter out, Hashtable params) {
1627

    
1628
    // Get the document indicated
1629
    String valtext = null;
1630
    DBConnection dbConn = null;
1631
    int serialNumber = -1;
1632

    
1633
    try {
1634
      valtext = ((String[])params.get("valtext"))[0];
1635
    } catch (Exception nullpe) {
1636

    
1637

    
1638
      String docid = null;
1639
      try {
1640
        // Find the document id number
1641
        docid = ((String[])params.get("docid"))[0];
1642

    
1643

    
1644
        // Get the document indicated from the db
1645
        DocumentImpl xmldoc = new DocumentImpl(docid);
1646
        valtext = xmldoc.toString();
1647

    
1648
      } catch (NullPointerException npe) {
1649

    
1650
        out.println("<error>Error getting document ID: " + docid + "</error>");
1651
        //if ( conn != null ) { util.returnConnection(conn); }
1652
        return;
1653
      } catch (Exception e) {
1654

    
1655
        out.println(e.getMessage());
1656
      }
1657
    }
1658

    
1659

    
1660
    try {
1661
      // get a connection from the pool
1662
      dbConn=DBConnectionPool.
1663
                  getDBConnection("MetaCatServlet.handleValidateAction");
1664
      serialNumber=dbConn.getCheckOutSerialNumber();
1665
      DBValidate valobj = new DBValidate(saxparser,dbConn);
1666
      boolean valid = valobj.validateString(valtext);
1667

    
1668
      // set content type and other response header fields first
1669

    
1670
      out.println(valobj.returnErrors());
1671

    
1672
    } catch (NullPointerException npe2) {
1673
      // set content type and other response header fields first
1674

    
1675
      out.println("<error>Error validating document.</error>");
1676
    } catch (Exception e) {
1677

    
1678
      out.println(e.getMessage());
1679
    } finally {
1680
      // Return db connection
1681
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1682
    }
1683
  }
1684
  // END OF VALIDATE SECTION
1685

    
1686
  // OTHER ACTION HANDLERS
1687

    
1688
  /**
1689
   * Handle "getrevsionanddoctype" action
1690
   * Given a docid, return it's current revision and doctype from data base
1691
   * The output is String look like "rev;doctype"
1692
   */
1693
  private void handleGetRevisionAndDocTypeAction(PrintWriter out,
1694
                                                              Hashtable params)
1695
  {
1696
    // To store doc parameter
1697
    String [] docs = new String[10];
1698
    // Store a single doc id
1699
    String givenDocId = null;
1700
    // Get docid from parameters
1701
    if (params.containsKey("docid"))
1702
    {
1703
      docs = (String[])params.get("docid");
1704
    }
1705
    // Get first docid form string array
1706
    givenDocId = docs[0];
1707

    
1708
    try
1709
    {
1710
      // Make sure there is a docid
1711
      if (givenDocId == null || givenDocId.equals(""))
1712
      {
1713
        throw new Exception("User didn't specify docid!");
1714
      }//if
1715

    
1716
      // Create a DBUtil object
1717
      DBUtil dbutil = new DBUtil();
1718
      // Get a rev and doctype
1719
      String revAndDocType =
1720
                dbutil.getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
1721
      out.println(revAndDocType);
1722

    
1723
    }//try
1724
    catch (Exception e)
1725
    {
1726
      // Handle exception
1727
      out.println("<?xml version=\"1.0\"?>");
1728
      out.println("<error>");
1729
      out.println(e.getMessage());
1730
      out.println("</error>");
1731
    }//catch
1732

    
1733
  }//handleGetRevisionAndDocTypeAction
1734

    
1735
  /**
1736
   * Handle "getaccesscontrol" action.
1737
   * Read Access Control List from db connection in XML format
1738
   */
1739
  private void handleGetAccessControlAction(PrintWriter out, Hashtable params,
1740
                                       HttpServletResponse response,
1741
                                       String username, String[] groupnames) {
1742

    
1743
    DBConnection dbConn = null;
1744
    int serialNumber = -1;
1745
    String docid = ((String[])params.get("docid"))[0];
1746

    
1747
    try {
1748

    
1749
        // get connection from the pool
1750
        dbConn=DBConnectionPool.
1751
                 getDBConnection("MetaCatServlet.handleGetAccessControlAction");
1752
        serialNumber=dbConn.getCheckOutSerialNumber();
1753
        AccessControlList aclobj = new AccessControlList(dbConn);
1754
        String acltext = aclobj.getACL(docid, username, groupnames);
1755
        out.println(acltext);
1756

    
1757
    } catch (Exception e) {
1758
      out.println("<?xml version=\"1.0\"?>");
1759
      out.println("<error>");
1760
      out.println(e.getMessage());
1761
      out.println("</error>");
1762
    } finally {
1763
      // Retrun db connection to pool
1764
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1765
    }
1766

    
1767
  }
1768

    
1769
  /**
1770
   * Handle the "getprincipals" action.
1771
   * Read all principals from authentication scheme in XML format
1772
   */
1773
  private void handleGetPrincipalsAction(PrintWriter out, String user,
1774
                                         String password) {
1775

    
1776

    
1777
    try {
1778

    
1779

    
1780
        AuthSession auth = new AuthSession();
1781
        String principals = auth.getPrincipals(user, password);
1782
        out.println(principals);
1783

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

    
1791
  }
1792

    
1793
  /**
1794
   * Handle "getdoctypes" action.
1795
   * Read all doctypes from db connection in XML format
1796
   */
1797
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
1798
                                       HttpServletResponse response) {
1799

    
1800

    
1801
    try {
1802

    
1803

    
1804
        DBUtil dbutil = new DBUtil();
1805
        String doctypes = dbutil.readDoctypes();
1806
        out.println(doctypes);
1807

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

    
1815
  }
1816

    
1817
  /**
1818
   * Handle the "getdtdschema" action.
1819
   * Read DTD or Schema file for a given doctype from Metacat catalog system
1820
   */
1821
  private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
1822
                                        HttpServletResponse response) {
1823

    
1824

    
1825
    String doctype = null;
1826
    String[] doctypeArr = (String[])params.get("doctype");
1827

    
1828
    // get only the first doctype specified in the list of doctypes
1829
    // it could be done for all doctypes in that list
1830
    if (doctypeArr != null) {
1831
        doctype = ((String[])params.get("doctype"))[0];
1832
    }
1833

    
1834
    try {
1835

    
1836

    
1837
        DBUtil dbutil = new DBUtil();
1838
        String dtdschema = dbutil.readDTDSchema(doctype);
1839
        out.println(dtdschema);
1840

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

    
1848
  }
1849

    
1850
  /**
1851
   * Handle the "getdataguide" action.
1852
   * Read Data Guide for a given doctype from db connection in XML format
1853
   */
1854
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params,
1855
                                        HttpServletResponse response) {
1856

    
1857

    
1858
    String doctype = null;
1859
    String[] doctypeArr = (String[])params.get("doctype");
1860

    
1861
    // get only the first doctype specified in the list of doctypes
1862
    // it could be done for all doctypes in that list
1863
    if (doctypeArr != null) {
1864
        doctype = ((String[])params.get("doctype"))[0];
1865
    }
1866

    
1867
    try {
1868

    
1869

    
1870
        DBUtil dbutil = new DBUtil();
1871
        String dataguide = dbutil.readDataGuide(doctype);
1872
        out.println(dataguide);
1873

    
1874
    } catch (Exception e) {
1875
      out.println("<?xml version=\"1.0\"?>");
1876
      out.println("<error>");
1877
      out.println(e.getMessage());
1878
      out.println("</error>");
1879
    }
1880

    
1881
  }
1882

    
1883
  /**
1884
   * Handle the "getlastdocid" action.
1885
   * Get the latest docid with rev number from db connection in XML format
1886
   */
1887
  private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
1888
                                        HttpServletResponse response) {
1889

    
1890

    
1891
    String scope = ((String[])params.get("scope"))[0];
1892
    if (scope == null) {
1893
        scope = ((String[])params.get("username"))[0];
1894
    }
1895

    
1896
    try {
1897

    
1898

    
1899
        DBUtil dbutil = new DBUtil();
1900
        String lastDocid = dbutil.getMaxDocid(scope);
1901
        out.println("<?xml version=\"1.0\"?>");
1902
        out.println("<lastDocid>");
1903
        out.println("  <scope>" + scope + "</scope>");
1904
        out.println("  <docid>" + lastDocid + "</docid>");
1905
        out.println("</lastDocid>");
1906

    
1907
    } catch (Exception e) {
1908
      out.println("<?xml version=\"1.0\"?>");
1909
      out.println("<error>");
1910
      out.println(e.getMessage());
1911
      out.println("</error>");
1912
    }
1913

    
1914
  }
1915

    
1916
  /**
1917
   * Handle documents passed to metacat that are encoded using the
1918
   * "multipart/form-data" mime type.  This is typically used for uploading
1919
   * data files which may be binary and large.
1920
   */
1921
  private void handleMultipartForm(HttpServletRequest request,
1922
                                   HttpServletResponse response)
1923
  {
1924
    PrintWriter out = null;
1925
    String action = null;
1926

    
1927
    // Parse the multipart form, and save the parameters in a Hashtable and
1928
    // save the FileParts in a hashtable
1929

    
1930
    Hashtable params = new Hashtable();
1931
    Hashtable fileList = new Hashtable();
1932

    
1933
    try {
1934
      // MBJ: need to put filesize limit in Metacat config (metacat.properties)
1935
      MultipartParser mp = new MultipartParser(request, 200*1024*1024); //200MB
1936
      Part part;
1937
      while ((part = mp.readNextPart()) != null) {
1938
        String name = part.getName();
1939

    
1940
        if (part.isParam()) {
1941
          // it's a parameter part
1942
          ParamPart paramPart = (ParamPart) part;
1943
          String value = paramPart.getStringValue();
1944
          params.put(name, value);
1945
          if (name.equals("action")) {
1946
            action = value;
1947
          }
1948
        } else if (part.isFile()) {
1949
          // it's a file part
1950
          FilePart filePart = (FilePart) part;
1951
          fileList.put(name, filePart);
1952

    
1953
          // Stop once the first file part is found, otherwise going onto the
1954
          // next part prevents access to the file contents.  So...for upload
1955
          // to work, the datafile must be the last part
1956
          break;
1957
        }
1958
      }
1959
    } catch (IOException ioe) {
1960
      try {
1961
        out = response.getWriter();
1962
      } catch (IOException ioe2) {
1963
        System.err.println("Fatal Error: couldn't get response output stream.");
1964
      }
1965
      out.println("<?xml version=\"1.0\"?>");
1966
      out.println("<error>");
1967
      out.println("Error: problem reading multipart data.");
1968
      out.println("</error>");
1969
    }
1970

    
1971
    // Get the session information
1972
    String username = null;
1973
    String password = null;
1974
    String[] groupnames = null;
1975
    String sess_id = null;
1976

    
1977
    // be aware of session expiration on every request
1978
    HttpSession sess = request.getSession(true);
1979
    if (sess.isNew()) {
1980
      // session expired or has not been stored b/w user requests
1981
      username = "public";
1982
      sess.setAttribute("username", username);
1983
    } else {
1984
      username = (String)sess.getAttribute("username");
1985
      password = (String)sess.getAttribute("password");
1986
      groupnames = (String[])sess.getAttribute("groupnames");
1987
      try {
1988
        sess_id = (String)sess.getId();
1989
      } catch(IllegalStateException ise) {
1990
        System.out.println("error in  handleMultipartForm: this shouldn't " +
1991
                           "happen: the session should be valid: " +
1992
                           ise.getMessage());
1993
      }
1994
    }
1995

    
1996
    // Get the out stream
1997
    try {
1998
          out = response.getWriter();
1999
        } catch (IOException ioe2) {
2000
          util.debugMessage("Fatal Error: couldn't get response "+
2001
                                                              "output stream.");
2002
        }
2003

    
2004
    if ( action.equals("upload")) {
2005
      if (username != null &&  !username.equals("public")) {
2006
        handleUploadAction(request, out, params, fileList,
2007
                           username, groupnames);
2008
      } else {
2009

    
2010
        out.println("<?xml version=\"1.0\"?>");
2011
        out.println("<error>");
2012
        out.println("Permission denied for " + action);
2013
        out.println("</error>");
2014
      }
2015
    } else {
2016
      /*try {
2017
        out = response.getWriter();
2018
      } catch (IOException ioe2) {
2019
        System.err.println("Fatal Error: couldn't get response output stream.");
2020
      }*/
2021
      out.println("<?xml version=\"1.0\"?>");
2022
      out.println("<error>");
2023
      out.println("Error: action not registered.  Please report this error.");
2024
      out.println("</error>");
2025
    }
2026
    out.close();
2027
  }
2028

    
2029
  /**
2030
   * Handle the upload action by saving the attached file to disk and
2031
   * registering it in the Metacat db
2032
   */
2033
  private void handleUploadAction(HttpServletRequest request,
2034
                                  PrintWriter out,
2035
                                  Hashtable params, Hashtable fileList,
2036
                                  String username, String[] groupnames)
2037
  {
2038
    //PrintWriter out = null;
2039
    //Connection conn = null;
2040
    String action = null;
2041
    String docid = null;
2042

    
2043
    /*response.setContentType("text/xml");
2044
    try
2045
    {
2046
      out = response.getWriter();
2047
    }
2048
    catch (IOException ioe2)
2049
    {
2050
      System.err.println("Fatal Error: couldn't get response output stream.");
2051
    }*/
2052

    
2053
    if (params.containsKey("docid"))
2054
    {
2055
      docid = (String)params.get("docid");
2056
    }
2057

    
2058
    // Make sure we have a docid and datafile
2059
    if (docid != null && fileList.containsKey("datafile")) {
2060

    
2061
      // Get a reference to the file part of the form
2062
      FilePart filePart = (FilePart)fileList.get("datafile");
2063
      String fileName = filePart.getFileName();
2064
      MetaCatUtil.debugMessage("Uploading filename: " + fileName, 10);
2065

    
2066
      // Check if the right file existed in the uploaded data
2067
      if (fileName != null) {
2068

    
2069
        try
2070
        {
2071
           //MetaCatUtil.debugMessage("Upload datafile " + docid +"...", 10);
2072
           //If document get lock data file grant
2073
           if (DocumentImpl.getDataFileLockGrant(docid))
2074
           {
2075
              // register the file in the database (which generates an exception
2076
              //if the docid is not acceptable or other untoward things happen
2077
              DocumentImpl.registerDocument(fileName, "BIN", docid, username);
2078

    
2079
              // Save the data file to disk using "docid" as the name
2080
              dataDirectory.mkdirs();
2081
              File newFile = new File(dataDirectory, docid);
2082
              long size = filePart.writeTo(newFile);
2083

    
2084
              // Force replication this data file
2085
              // To data file, "insert" and update is same
2086
              // The fourth parameter is null. Because it is notification server
2087
              // and this method is in MetaCatServerlet. It is original command,
2088
              // not get force replication info from another metacat
2089
              ForceReplicationHandler frh = new ForceReplicationHandler
2090
                                                (docid, "insert", false, null);
2091

    
2092
              // set content type and other response header fields first
2093
              out.println("<?xml version=\"1.0\"?>");
2094
              out.println("<success>");
2095
              out.println("<docid>" + docid + "</docid>");
2096
              out.println("<size>" + size + "</size>");
2097
              out.println("</success>");
2098
          }//if
2099

    
2100
        } //try
2101
        catch (Exception e)
2102
        {
2103
          out.println("<?xml version=\"1.0\"?>");
2104
          out.println("<error>");
2105
          out.println(e.getMessage());
2106
          out.println("</error>");
2107
        }
2108

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