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-18 17:30:55 -0800 (Tue, 18 Mar 2003) $'
11
 * '$Revision: 1483 $'
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.ecoinformatics.eml.EMLParser;
69

    
70
import org.xml.sax.SAXException;
71

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

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

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

    
140
      util = new MetaCatUtil();
141

    
142
      //initial DBConnection pool
143
      connPool = DBConnectionPool.getInstance();
144

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

    
154

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

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

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

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

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

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

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

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

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

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

    
216

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

    
223

    
224
      while (paramlist.hasMoreElements()) {
225

    
226
        name = (String)paramlist.nextElement();
227
        value = request.getParameterValues(name);
228

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

    
239
        params.put(name,value);
240
      }
241

    
242

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

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

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

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

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

    
293
      // aware of session expiration on every request
294
      } else {
295

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

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

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

    
441
      //util.closeConnections();
442
      // Close the stream to the client
443
      //out.close();
444
    }
445
  }
446

    
447
  // LOGIN & LOGOUT SECTION
448
  /**
449
   * Handle the login request. Create a new session object.
450
   * Do user authentication through the session.
451
   */
452
  private void handleLoginAction(PrintWriter out, Hashtable params,
453
               HttpServletRequest request, HttpServletResponse response) {
454

    
455
    AuthSession sess = null;
456
    String un = ((String[])params.get("username"))[0];
457
    String pw = ((String[])params.get("password"))[0];
458
    String action = ((String[])params.get("action"))[0];
459
    String qformat = ((String[])params.get("qformat"))[0];
460

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

    
476
      try {
477

    
478
        DBTransform trans = new DBTransform();
479
        response.setContentType("text/html");
480
        trans.transformXMLDocument(sess.getMessage(), "-//NCEAS//login//EN",
481
                                   "-//W3C//HTML//EN", qformat, out);
482

    
483
      } catch(Exception e) {
484

    
485
        MetaCatUtil.debugMessage("Error in MetaCatServlet.handleLoginAction: "
486
                                +e.getMessage(), 30);
487
      }
488

    
489
    // any output is returned
490
    }
491
  }
492

    
493
  /**
494
   * Handle the logout request. Close the connection.
495
   */
496
  private void handleLogoutAction(PrintWriter out, Hashtable params,
497
               HttpServletRequest request, HttpServletResponse response) {
498

    
499
    String qformat = ((String[])params.get("qformat"))[0];
500

    
501
    // close the connection
502
    HttpSession sess = request.getSession(false);
503
    if (sess != null) { sess.invalidate();  }
504

    
505
    // produce output
506
    StringBuffer output = new StringBuffer();
507
    output.append("<?xml version=\"1.0\"?>");
508
    output.append("<logout>");
509
    output.append("User logged out");
510
    output.append("</logout>");
511

    
512
    //format and transform the output
513
    if (qformat.equals("xml")) {
514
      response.setContentType("text/xml");
515
      out.println(output.toString());
516
    } else {
517

    
518
      try {
519

    
520
        DBTransform trans = new DBTransform();
521
        response.setContentType("text/html");
522
        trans.transformXMLDocument(output.toString(), "-//NCEAS//login//EN",
523
                                   "-//W3C//HTML//EN", qformat, out);
524

    
525
      } catch(Exception e) {
526

    
527
        MetaCatUtil.debugMessage("Error in MetaCatServlet.handleLogoutAction"
528
                                  +e.getMessage(), 30);
529
      }
530
    }
531
  }
532
  // END OF LOGIN & LOGOUT SECTION
533

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

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

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

    
592
    resultdoc = createResultDocument(doclist, transformQuery(params));
593

    
594
    //format and transform the results
595
    if(qformat.equals("xml")) {
596
      response.setContentType("text/xml");
597
      out.println(resultdoc);
598
    } else {
599
      transformResultset(resultdoc, response, out, qformat);
600
    }
601
  }
602

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

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

    
636
  /**
637
   * Run the query and return a hashtable of results.
638
   *
639
   * @param xmlquery the query to run
640
   */
641
  private Hashtable runQuery(String xmlquery, String user, String[] groups)
642
  {
643
    Hashtable doclist=null;
644

    
645
    try
646
    {
647

    
648
      DBQuery queryobj = new DBQuery(saxparser);
649
      doclist = queryobj.findDocuments(new StringReader(xmlquery),user,groups);
650

    
651
      return doclist;
652
    }
653
    catch (Exception e)
654
    {
655

    
656
      MetaCatUtil.debugMessage("Error in MetacatServlet.runQuery: "
657
                                                      + e.getMessage(), 30);
658
      doclist = null;
659
      return doclist;
660
    }
661
  }
662

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

    
677
    try {
678

    
679
      DBTransform trans = new DBTransform();
680
      response.setContentType("text/html");
681
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN",
682
                                 "-//W3C//HTML//EN", qformat, out);
683

    
684
    }
685
    catch(Exception e)
686
    {
687

    
688
      MetaCatUtil.debugMessage("Error in MetaCatServlet.transformResultset:"
689
                                +e.getMessage(), 30);
690
    }
691
  }
692

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

    
704
    // Print the resulting root nodes
705
    String docid = null;
706
    String document = null;
707
    resultset.append("<?xml version=\"1.0\"?>\n");
708
    resultset.append("<resultset>\n");
709

    
710
    resultset.append("  <query>" + xmlquery + "</query>");
711

    
712
    if(doclist != null)
713
    {
714
      Enumeration doclistkeys = doclist.keys();
715
      while (doclistkeys.hasMoreElements())
716
      {
717
        docid = (String)doclistkeys.nextElement();
718
        document = (String)doclist.get(docid);
719
        resultset.append("  <document>" + document + "</document>");
720
      }
721
    }
722

    
723
    resultset.append("</resultset>");
724
    return resultset.toString();
725
  }
726
  // END OF SQUERY & QUERY SECTION
727

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

    
746
    String[] docs = new String[10];
747
    String docId = "";
748

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

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

    
815
      MetaCatUtil.debugMessage("Error in MetacatServlet.handleExportAction: " +
816
                         e.getMessage(), 30);
817
      e.printStackTrace(System.out);
818

    
819
    }//catch
820

    
821
  }//handleExportAction
822

    
823
  
824
   //read inline data section
825
 /**
826
   * In eml2 document, the xml can have inline data and data was stripped off 
827
   * and store in file system. This action can be used to read inline data only
828
   * @param params the Hashtable of HTTP request parameters
829
   * @param response the HTTP response object linked to the client
830
   * @param user the username sent the request
831
   * @param groups the user's groupnames
832
   */
833
  private void handleReadInlineDataAction(Hashtable params,
834
                                          HttpServletResponse response,
835
                                          String user, String passWord,
836
                                          String[] groups)
837
  {
838
    String[] docs = new String[10];
839
    String inlineDataId = null;
840
    String docId = "";
841
    ServletOutputStream out = null;
842

    
843
    try
844
    {
845
      // read the params
846
      if (params.containsKey("dataid"))
847
      {
848
        docs = (String[])params.get("dataid");
849
      }//if
850
      // Get the docid
851
      inlineDataId=docs[0];
852
      // Make sure the client specify docid
853
      if (inlineDataId == null || inlineDataId.equals(""))
854
      {
855
        // Get a printwriter
856
        PrintWriter pw = response.getWriter();
857
        // Send back message
858
        pw.println("<?xml version=\"1.0\"?>");
859
        pw.println("<error>");
860
        pw.println("You didn't specify requested docid");
861
        pw.println("</error>");
862
        // Close printwriter
863
        pw.close();
864
        return;
865
      }//if
866
      
867
      // check for permission
868
      docId = MetaCatUtil.getDocIdWithRevFromInlineDataID(inlineDataId);
869
      
870
      // Get output stream
871
      out = response.getOutputStream();
872
      // read the inline data from the file
873
      String inlinePath = MetaCatUtil.getOption("inlinedatafilepath");
874
      File lineData = new File(inlinePath, inlineDataId);
875
      FileInputStream input = new FileInputStream(lineData);
876
      byte [] buffer = new byte[4*1024];
877
      int bytes = input.read(buffer);
878
      while (bytes != -1)
879
      {
880
        out.write(buffer, 0, bytes);
881
        bytes = input.read(buffer);
882
      }
883
      out.close();
884

    
885
    }//try
886
    catch (Exception e)
887
    {
888
      try
889
      {
890
        // Send error message back
891
        if (out != null)
892
        {
893
            PrintWriter pw = new PrintWriter(out);
894
            pw.println("<?xml version=\"1.0\"?>");
895
            pw.println("<error>");
896
            pw.println(e.getMessage());
897
            pw.println("</error>");
898
            // Close printwriter
899
            pw.close();
900
            // Close output stream
901
            out.close();
902
        }//if
903
     }//try
904
     catch (IOException ioe)
905
     {
906
        MetaCatUtil.debugMessage("Problem with the servlet output " +
907
                           "in MetacatServlet.handleExportAction: " +
908
                           ioe.getMessage(), 30);
909
     }//catch
910

    
911
      MetaCatUtil.debugMessage("Error in MetacatServlet.handleReadInlineDataAction: " 
912
                                + e.getMessage(), 30);
913
   
914
    }//catch
915

    
916
  }//handleReadInlineDataAction
917
  
918
  
919
  
920
  
921
  // READ SECTION
922
  /**
923
   * Handle the "read" request of metadata/data files from Metacat
924
   * or any files from Internet;
925
   * transformed metadata XML document into HTML presentation if requested;
926
   * zip files when more than one were requested.
927
   *
928
   * @param params the Hashtable of HTTP request parameters
929
   * @param response the HTTP response object linked to the client
930
   * @param user the username sent the request
931
   * @param groups the user's groupnames
932
   */
933
  private void handleReadAction(Hashtable params, HttpServletResponse response,
934
                                String user, String passWord, String[] groups)
935
  {
936
    ServletOutputStream out = null;
937
    ZipOutputStream zout = null;
938
    PrintWriter pw = null;
939
    boolean zip = false;
940
    boolean withInlineData = true;
941

    
942
    try {
943
      String[] docs = new String[0];
944
      String docid = "";
945
      String qformat = "";
946
      String abstrpath = null;
947

    
948
      // read the params
949
      if (params.containsKey("docid")) {
950
        docs = (String[])params.get("docid");
951
      }
952
      if (params.containsKey("qformat")) {
953
        qformat = ((String[])params.get("qformat"))[0];
954
      }
955
      // the param for only metadata (eml)
956
      if (params.containsKey("inlinedata"))
957
      {
958
        
959
        String inlineData = ((String[])params.get("inlinedata"))[0];
960
        if (inlineData.equalsIgnoreCase("false"))
961
        {
962
          withInlineData = false;
963
        }
964
      } 
965
      if (params.containsKey("abstractpath")) {
966
        abstrpath = ((String[])params.get("abstractpath"))[0];
967
        if ( !abstrpath.equals("") && (abstrpath != null) ) {
968
          viewAbstract(response, abstrpath, docs[0]);
969
          return;
970
        }
971
      }
972
      if ( (docs.length > 1) || qformat.equals("zip") ) {
973
        zip = true;
974
        out = response.getOutputStream();
975
        response.setContentType("application/zip"); //MIME type
976
        zout = new ZipOutputStream(out);
977
      }
978
      // go through the list of docs to read
979
      for (int i=0; i < docs.length; i++ ) {
980
        try {
981

    
982
          URL murl = new URL(docs[i]);
983
          Hashtable murlQueryStr = util.parseQuery(murl.getQuery());
984
          // case docid="http://.../?docid=aaa"
985
          // or docid="metacat://.../?docid=bbb"
986
          if (murlQueryStr.containsKey("docid")) {
987
            // get only docid, eliminate the rest
988
            docid = (String)murlQueryStr.get("docid");
989
            if ( zip ) {
990
              addDocToZip(docid, zout, user, groups);
991
            } else {
992
              readFromMetacat(response, docid, qformat, abstrpath,
993
                              user, groups, zip, zout, withInlineData);
994
            }
995

    
996
          // case docid="http://.../filename"
997
          } else {
998
            docid = docs[i];
999
            if ( zip ) {
1000
              addDocToZip(docid, zout, user, groups);
1001
            } else {
1002
              readFromURLConnection(response, docid);
1003
            }
1004
          }
1005

    
1006
        // case docid="ccc"
1007
        } catch (MalformedURLException mue) {
1008
          docid = docs[i];
1009
          if ( zip ) {
1010
            addDocToZip(docid, zout, user, groups);
1011
          } else {
1012
            readFromMetacat(response, docid, qformat, abstrpath,
1013
                            user, groups, zip, zout, withInlineData);
1014
          }
1015
        }
1016

    
1017
      } /* end for */
1018

    
1019
      if ( zip ) {
1020
        zout.finish(); //terminate the zip file
1021
        zout.close();  //close the zip stream
1022
      }
1023

    
1024

    
1025
    }
1026
    // To handle doc not found exception
1027
    catch (McdbDocNotFoundException notFoundE)
1028
    {
1029
      // the docid which didn't be found
1030
      String notFoundDocId = notFoundE.getUnfoundDocId();
1031
      String notFoundRevision = notFoundE.getUnfoundRevision();
1032
      MetaCatUtil.debugMessage("Missed id: "+ notFoundDocId, 30);
1033
      MetaCatUtil.debugMessage("Missed rev: "+ notFoundRevision, 30);
1034
      try
1035
      {
1036
        // read docid from remote server
1037
        readFromRemoteMetaCat(response, notFoundDocId, notFoundRevision,
1038
                                              user, passWord, out, zip, zout);
1039
        // Close zout outputstream
1040
        if ( zout != null)
1041
        {
1042
          zout.close();
1043
        }
1044
        // close output stream
1045
        if (out != null)
1046
        {
1047
          out.close();
1048
        }
1049

    
1050
      }//try
1051
      catch ( Exception exc)
1052
      {
1053
        MetaCatUtil.debugMessage("Erorr in MetacatServlet.hanldReadAction: "+
1054
                                      exc.getMessage(), 30);
1055
        try
1056
        {
1057
          if (out != null)
1058
          {
1059
            response.setContentType("text/xml");
1060
            // Send back error message by printWriter
1061
            pw = new PrintWriter(out);
1062
            pw.println("<?xml version=\"1.0\"?>");
1063
            pw.println("<error>");
1064
            pw.println(notFoundE.getMessage());
1065
            pw.println("</error>");
1066
            pw.close();
1067
            out.close();
1068

    
1069
          }
1070
          else
1071
          {
1072
           response.setContentType("text/xml"); //MIME type
1073
           // Send back error message if out = null
1074
           if (pw == null)
1075
           {
1076
             // If pw is null, open the respnose
1077
            pw = response.getWriter();
1078
           }
1079
           pw.println("<?xml version=\"1.0\"?>");
1080
           pw.println("<error>");
1081
           pw.println(notFoundE.getMessage());
1082
           pw.println("</error>");
1083
           pw.close();
1084
        }
1085
        // close zout
1086
        if ( zout != null )
1087
        {
1088
          zout.close();
1089
        }
1090
        }//try
1091
        catch (IOException ie)
1092
        {
1093
          MetaCatUtil.debugMessage("Problem with the servlet output " +
1094
                           "in MetacatServlet.handleReadAction: " +
1095
                           ie.getMessage(), 30);
1096
        }//cathch
1097
      }//catch
1098
    }// catch McdbDocNotFoundException
1099
    catch (Exception e)
1100
    {
1101
      try {
1102

    
1103
        if (out != null) {
1104
            response.setContentType("text/xml"); //MIME type
1105
            pw = new PrintWriter(out);
1106
            pw.println("<?xml version=\"1.0\"?>");
1107
            pw.println("<error>");
1108
            pw.println(e.getMessage());
1109
            pw.println("</error>");
1110
            pw.close();
1111
            out.close();
1112
        }
1113
        else
1114
        {
1115
           response.setContentType("text/xml"); //MIME type
1116
           // Send back error message if out = null
1117
           if ( pw == null)
1118
           {
1119
            pw = response.getWriter();
1120
           }
1121
           pw.println("<?xml version=\"1.0\"?>");
1122
           pw.println("<error>");
1123
           pw.println(e.getMessage());
1124
           pw.println("</error>");
1125
           pw.close();
1126

    
1127
        }
1128
        // Close zip output stream
1129
        if ( zout != null ) { zout.close(); }
1130

    
1131
      } catch (IOException ioe) {
1132
        MetaCatUtil.debugMessage("Problem with the servlet output " +
1133
                           "in MetacatServlet.handleReadAction: " +
1134
                           ioe.getMessage(), 30);
1135
        ioe.printStackTrace(System.out);
1136

    
1137
      }
1138

    
1139
      MetaCatUtil.debugMessage("Error in MetacatServlet.handleReadAction: " +
1140
                               e.getMessage(), 30);
1141
      //e.printStackTrace(System.out);
1142
    }
1143

    
1144
  }
1145

    
1146
  // read metadata or data from Metacat
1147
  private void readFromMetacat(HttpServletResponse response, String docid,
1148
                               String qformat, String abstrpath, String user,
1149
                               String[] groups, boolean zip, 
1150
                               ZipOutputStream zout, boolean withInlineData)
1151
               throws ClassNotFoundException, IOException, SQLException,
1152
                      McdbException, Exception
1153
  {
1154

    
1155
    try {
1156

    
1157

    
1158
      DocumentImpl doc = new DocumentImpl(docid);
1159

    
1160
      //check the permission for read
1161
      if (!doc.hasReadPermission(user, groups, docid))
1162
      {
1163
        Exception e = new Exception("User " + user + " does not have permission"
1164
                       +" to read the document with the docid " + docid);
1165

    
1166
        throw e;
1167
      }
1168

    
1169
      if ( doc.getRootNodeID() == 0 ) {
1170
        // this is data file
1171
        String filepath = util.getOption("datafilepath");
1172
        if(!filepath.endsWith("/")) {
1173
          filepath += "/";
1174
        }
1175
        String filename = filepath + docid;
1176
        FileInputStream fin = null;
1177
        fin = new FileInputStream(filename);
1178

    
1179
        //MIME type
1180
        String contentType = getServletContext().getMimeType(filename);
1181
        if (contentType == null) {
1182
          if (filename.endsWith(".xml")) {
1183
            contentType="text/xml";
1184
          } else if (filename.endsWith(".css")) {
1185
            contentType="text/css";
1186
          } else if (filename.endsWith(".dtd")) {
1187
            contentType="text/plain";
1188
          } else if (filename.endsWith(".xsd")) {
1189
            contentType="text/xml";
1190
          } else if (filename.endsWith("/")) {
1191
            contentType="text/html";
1192
          } else {
1193
            File f = new File(filename);
1194
            if ( f.isDirectory() ) {
1195
              contentType="text/html";
1196
            } else {
1197
              contentType="application/octet-stream";
1198
            }
1199
          }
1200
        }
1201
        response.setContentType(contentType);
1202
        // if we decide to use "application/octet-stream" for all data returns
1203
        // response.setContentType("application/octet-stream");
1204

    
1205
        try {
1206

    
1207
          ServletOutputStream out = response.getOutputStream();
1208
          byte[] buf = new byte[4 * 1024]; // 4K buffer
1209
          int b = fin.read(buf);
1210
          while (b != -1) {
1211
            out.write(buf, 0, b);
1212
            b = fin.read(buf);
1213
          }
1214
        } finally {
1215
          if (fin != null) fin.close();
1216
        }
1217

    
1218
      } else {
1219
        // this is metadata doc
1220
        if ( qformat.equals("xml") ) {
1221

    
1222
          // set content type first
1223
          response.setContentType("text/xml");   //MIME type
1224
          PrintWriter out = response.getWriter();
1225
          doc.toXml(out, user, groups, withInlineData);
1226
        } else {
1227
          response.setContentType("text/html");  //MIME type
1228
          PrintWriter out = response.getWriter();
1229

    
1230
          // Look up the document type
1231
          String doctype = doc.getDoctype();
1232
          // Transform the document to the new doctype
1233
          DBTransform dbt = new DBTransform();
1234
          dbt.transformXMLDocument(doc.toString(user, groups, withInlineData),
1235
                                   doctype,"-//W3C//HTML//EN", qformat, out);
1236
        }
1237

    
1238
      }
1239
    }
1240
    catch (Exception except)
1241
    {
1242
      throw except;
1243

    
1244
    }
1245

    
1246
  }
1247

    
1248
  // read data from URLConnection
1249
  private void readFromURLConnection(HttpServletResponse response, String docid)
1250
               throws IOException, MalformedURLException
1251
  {
1252
    ServletOutputStream out = response.getOutputStream();
1253
    String contentType = getServletContext().getMimeType(docid); //MIME type
1254
    if (contentType == null) {
1255
      if (docid.endsWith(".xml")) {
1256
        contentType="text/xml";
1257
      } else if (docid.endsWith(".css")) {
1258
        contentType="text/css";
1259
      } else if (docid.endsWith(".dtd")) {
1260
        contentType="text/plain";
1261
      } else if (docid.endsWith(".xsd")) {
1262
        contentType="text/xml";
1263
      } else if (docid.endsWith("/")) {
1264
        contentType="text/html";
1265
      } else {
1266
        File f = new File(docid);
1267
        if ( f.isDirectory() ) {
1268
          contentType="text/html";
1269
        } else {
1270
          contentType="application/octet-stream";
1271
        }
1272
      }
1273
    }
1274
    response.setContentType(contentType);
1275
    // if we decide to use "application/octet-stream" for all data returns
1276
    // response.setContentType("application/octet-stream");
1277

    
1278
    // this is http url
1279
    URL url = new URL(docid);
1280
    BufferedInputStream bis = null;
1281
    try {
1282
      bis = new BufferedInputStream(url.openStream());
1283
      byte[] buf = new byte[4 * 1024]; // 4K buffer
1284
      int b = bis.read(buf);
1285
      while (b != -1) {
1286
        out.write(buf, 0, b);
1287
        b = bis.read(buf);
1288
      }
1289
    } finally {
1290
      if (bis != null) bis.close();
1291
    }
1292

    
1293
  }
1294

    
1295
  // read file/doc and write to ZipOutputStream
1296
  private void addDocToZip(String docid, ZipOutputStream zout,
1297
                              String user, String[] groups)
1298
               throws ClassNotFoundException, IOException, SQLException,
1299
                      McdbException, Exception
1300
  {
1301
    byte[] bytestring = null;
1302
    ZipEntry zentry = null;
1303

    
1304
    try {
1305
      URL url = new URL(docid);
1306

    
1307
      // this http url; read from URLConnection; add to zip
1308
      zentry = new ZipEntry(docid);
1309
      zout.putNextEntry(zentry);
1310
      BufferedInputStream bis = null;
1311
      try {
1312
        bis = new BufferedInputStream(url.openStream());
1313
        byte[] buf = new byte[4 * 1024]; // 4K buffer
1314
        int b = bis.read(buf);
1315
        while(b != -1) {
1316
          zout.write(buf, 0, b);
1317
          b = bis.read(buf);
1318
        }
1319
      } finally {
1320
        if (bis != null) bis.close();
1321
      }
1322
      zout.closeEntry();
1323

    
1324
    } catch (MalformedURLException mue) {
1325

    
1326
      // this is metacat doc (data file or metadata doc)
1327

    
1328
      try {
1329

    
1330
        DocumentImpl doc = new DocumentImpl(docid);
1331

    
1332
        //check the permission for read
1333
        if (!doc.hasReadPermission(user, groups, docid))
1334
        {
1335
          Exception e = new Exception("User " + user + " does not have "
1336
                    +"permission to read the document with the docid " + docid);
1337

    
1338
          throw e;
1339
        }
1340

    
1341
        if ( doc.getRootNodeID() == 0 ) {
1342
          // this is data file; add file to zip
1343
          String filepath = util.getOption("datafilepath");
1344
          if(!filepath.endsWith("/")) {
1345
            filepath += "/";
1346
          }
1347
          String filename = filepath + docid;
1348
          FileInputStream fin = null;
1349
          fin = new FileInputStream(filename);
1350
          try {
1351

    
1352
            zentry = new ZipEntry(docid);
1353
            zout.putNextEntry(zentry);
1354
            byte[] buf = new byte[4 * 1024]; // 4K buffer
1355
            int b = fin.read(buf);
1356
            while (b != -1) {
1357
              zout.write(buf, 0, b);
1358
              b = fin.read(buf);
1359
            }
1360
          } finally {
1361
            if (fin != null) fin.close();
1362
          }
1363
          zout.closeEntry();
1364

    
1365
        } else {
1366
          // this is metadata doc; add doc to zip
1367
          bytestring = doc.toString().getBytes();
1368
          zentry = new ZipEntry(docid + ".xml");
1369
          zentry.setSize(bytestring.length);
1370
          zout.putNextEntry(zentry);
1371
          zout.write(bytestring, 0, bytestring.length);
1372
          zout.closeEntry();
1373
        }
1374
      } catch (Exception except) {
1375
        throw except;
1376

    
1377
      }
1378

    
1379
    }
1380

    
1381
  }
1382

    
1383
  // view abstract within document
1384
  private void viewAbstract(HttpServletResponse response,
1385
                            String abstractpath, String docid)
1386
               throws ClassNotFoundException, IOException, SQLException,
1387
                      McdbException, Exception
1388
  {
1389

    
1390
    PrintWriter out =null;
1391
    try {
1392

    
1393
      response.setContentType("text/html");  //MIME type
1394
      out = response.getWriter();
1395
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid);
1396
      out.println("<html><head><title>Abstract</title></head>");
1397
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
1398
      for (int i=0; i<abstracts.length; i++) {
1399
        out.println("<p>" + (String)abstracts[i] + "</p>");
1400
      }
1401
      out.println("</body></html>");
1402

    
1403
    } catch (Exception e) {
1404
       out.println("<?xml version=\"1.0\"?>");
1405
       out.println("<error>");
1406
       out.println(e.getMessage());
1407
       out.println("</error>");
1408

    
1409

    
1410
    }
1411
  }
1412
  /**
1413
   * If metacat couldn't find a data file or document locally, it will read this
1414
   * docid from its home server. This is for the replication feature
1415
   */
1416
  private void readFromRemoteMetaCat(HttpServletResponse response, String docid,
1417
                     String rev, String user, String password,
1418
                     ServletOutputStream out, boolean zip, ZipOutputStream zout)
1419
                        throws Exception
1420
 {
1421
   // Create a object of RemoteDocument, "" is for zipEntryPath
1422
   RemoteDocument remoteDoc =
1423
                        new RemoteDocument (docid, rev,user, password, "");
1424
   String docType = remoteDoc.getDocType();
1425
   // Only read data file
1426
   if (docType.equals("BIN"))
1427
   {
1428
    // If it is zip format
1429
    if (zip)
1430
    {
1431
      remoteDoc.readDocumentFromRemoteServerByZip(zout);
1432
    }//if
1433
    else
1434
    {
1435
      if (out == null)
1436
      {
1437
        out = response.getOutputStream();
1438
      }//if
1439
      response.setContentType("application/octet-stream");
1440
      remoteDoc.readDocumentFromRemoteServer(out);
1441
    }//else (not zip)
1442
   }//if doctype=bin
1443
   else
1444
   {
1445
     throw new Exception("Docid: "+docid+"."+rev+" couldn't find");
1446
   }//else
1447
 }//readFromRemoteMetaCat
1448

    
1449
  // END OF READ SECTION
1450
  
1451
 
1452
  
1453
  // INSERT/UPDATE SECTION
1454
  /**
1455
   * Handle the database putdocument request and write an XML document
1456
   * to the database connection
1457
   */
1458
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params,
1459
               String user, String[] groups) {
1460

    
1461
    DBConnection dbConn = null;
1462
    int serialNumber = -1;
1463

    
1464
    try {
1465
      // Get the document indicated
1466
      String[] doctext = (String[])params.get("doctext");
1467

    
1468
      String pub = null;
1469
      if (params.containsKey("public")) {
1470
        pub = ((String[])params.get("public"))[0];
1471
      }
1472

    
1473
      StringReader dtd = null;
1474
      if (params.containsKey("dtdtext")) {
1475
        String[] dtdtext = (String[])params.get("dtdtext");
1476
        try {
1477
          if ( !dtdtext[0].equals("") ) {
1478
            dtd = new StringReader(dtdtext[0]);
1479
          }
1480
        } catch (NullPointerException npe) {}
1481
      }
1482

    
1483
      StringReader xml = null;
1484
      boolean validate = false;
1485
      DocumentImplWrapper documentWrapper = null;
1486
      try {
1487
        // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ... >
1488
        // in order to decide whether to use validation parser
1489
        validate = needDTDValidation(doctext[0]);
1490
        if (validate)
1491
        {
1492
          // set a dtd base validation parser
1493
          String rule = DocumentImpl.DTD;
1494
          documentWrapper = new DocumentImplWrapper(rule, validate);
1495
        }
1496
        else if (needSchemaValidation(doctext[0]))
1497
        {
1498
          // for eml2
1499
          if (needEml2Validation(doctext[0]))
1500
          {
1501
             // set eml2 base validation parser
1502
            String rule = DocumentImpl.EML2;
1503
            // using emlparser to check id validation
1504
            EMLParser parser = new EMLParser(doctext[0]);
1505
            documentWrapper = new DocumentImplWrapper(rule, true);
1506
          }
1507
          else
1508
          {
1509
            // set schema base validation parser
1510
            String rule = DocumentImpl.SCHEMA;
1511
            documentWrapper = new DocumentImplWrapper(rule, true);
1512
          }
1513
        }
1514
        else
1515
        {
1516
          documentWrapper = new DocumentImplWrapper("", false);
1517
        }
1518
        
1519
        xml = new StringReader(doctext[0]);
1520

    
1521
        String[] action = (String[])params.get("action");
1522
        String[] docid = (String[])params.get("docid");
1523
        String newdocid = null;
1524

    
1525
        String doAction = null;
1526
        if (action[0].equals("insert")) {
1527
          doAction = "INSERT";
1528
        } else if (action[0].equals("update")) {
1529
          doAction = "UPDATE";
1530
        }
1531

    
1532
        try
1533
        {
1534
          // get a connection from the pool
1535
          dbConn=DBConnectionPool.
1536
                  getDBConnection("MetaCatServlet.handleInsertOrUpdateAction");
1537
          serialNumber=dbConn.getCheckOutSerialNumber();
1538

    
1539

    
1540
          // write the document to the database
1541
          try
1542
          {
1543
            String accNumber = docid[0];
1544
            MetaCatUtil.debugMessage(""+ doAction + " " + accNumber +"...", 10);
1545
            if (accNumber.equals(""))
1546
            {
1547
              accNumber = null;
1548
            }//if
1549
            newdocid = documentWrapper.write(dbConn, xml, pub, dtd, doAction,
1550
                                          accNumber, user, groups);
1551

    
1552
          }//try
1553
          catch (NullPointerException npe)
1554
          {
1555
            newdocid = documentWrapper.write(dbConn, xml, pub, dtd, doAction,
1556
                                          null, user, groups);
1557
          }//catch
1558
        
1559
        }//try
1560
        finally
1561
        {
1562
          // Return db connection
1563
          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1564
        }
1565

    
1566
        // set content type and other response header fields first
1567
        //response.setContentType("text/xml");
1568
        out.println("<?xml version=\"1.0\"?>");
1569
        out.println("<success>");
1570
        out.println("<docid>" + newdocid + "</docid>");
1571
        out.println("</success>");
1572

    
1573
      } 
1574
      catch (NullPointerException npe) 
1575
      {
1576
        //response.setContentType("text/xml");
1577
        out.println("<?xml version=\"1.0\"?>");
1578
        out.println("<error>");
1579
        out.println(npe.getMessage());
1580
        out.println("</error>");
1581
      }
1582
    } 
1583
    catch (Exception e) 
1584
    {
1585
      //response.setContentType("text/xml");
1586
      out.println("<?xml version=\"1.0\"?>");
1587
      out.println("<error>");
1588
      out.println(e.getMessage());
1589
      out.println("</error>");
1590
    }
1591
  }
1592

    
1593
  /**
1594
   * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... >
1595
   * in order to decide whether to use validation parser
1596
   */
1597
  private static boolean needDTDValidation(String xmltext) throws IOException {
1598

    
1599
    StringReader xmlreader = new StringReader(xmltext);
1600
    StringBuffer cbuff = new StringBuffer();
1601
    java.util.Stack st = new java.util.Stack();
1602
    boolean validate = false;
1603
    int c;
1604
    int inx;
1605

    
1606
    // read from the stream until find the keywords
1607
    while ( (st.empty() || st.size()<4) && ((c = xmlreader.read()) != -1) ) {
1608
      cbuff.append((char)c);
1609

    
1610
      // "<!DOCTYPE" keyword is found; put it in the stack
1611
      if ( (inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1 ) {
1612
        cbuff = new StringBuffer();
1613
        st.push("<!DOCTYPE");
1614
      }
1615
      // "PUBLIC" keyword is found; put it in the stack
1616
      if ( (inx = cbuff.toString().indexOf("PUBLIC")) != -1 ) {
1617
        cbuff = new StringBuffer();
1618
        st.push("PUBLIC");
1619
      }
1620
      // "SYSTEM" keyword is found; put it in the stack
1621
      if ( (inx = cbuff.toString().indexOf("SYSTEM")) != -1 ) {
1622
        cbuff = new StringBuffer();
1623
        st.push("SYSTEM");
1624
      }
1625
      // ">" character is found; put it in the stack
1626
      // ">" is found twice: fisrt from <?xml ...?>
1627
      // and second from <!DOCTYPE ... >
1628
      if ( (inx = cbuff.toString().indexOf(">")) != -1 ) {
1629
        cbuff = new StringBuffer();
1630
        st.push(">");
1631
      }
1632
    }
1633

    
1634
    // close the stream
1635
    xmlreader.close();
1636

    
1637
    // check the stack whether it contains the keywords:
1638
    // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1639
    if ( st.size() == 4 ) {
1640
      if ( ((String)st.pop()).equals(">") &&
1641
           ( ((String)st.peek()).equals("PUBLIC") |
1642
             ((String)st.pop()).equals("SYSTEM") ) &&
1643
           ((String)st.pop()).equals("<!DOCTYPE") )  {
1644
        validate = true;
1645
      }
1646
    }
1647

    
1648
    MetaCatUtil.debugMessage("Validation for dtd is " + validate, 10);
1649
    return validate;
1650
  }
1651
  // END OF INSERT/UPDATE SECTION
1652
  
1653
  /* check if the xml string contains key words to specify schema loocation*/
1654
  private boolean needSchemaValidation(String xml)
1655
  {
1656
    boolean needSchemaValidate =false;
1657
    if (xml == null)
1658
    {
1659
      MetaCatUtil.debugMessage("Validation for schema is " +
1660
                               needSchemaValidate, 10);
1661
      return needSchemaValidate;
1662
    }
1663
    else if (xml.indexOf(SCHEMALOCATIONKEYWORD) != -1 ||
1664
             xml.indexOf(NONAMESPACELOCATION) != -1 )
1665
    {
1666
      // if contains schema location key word, should be validate
1667
      needSchemaValidate = true;
1668
    }
1669
    
1670
    MetaCatUtil.debugMessage("Validation for schema is " + 
1671
                             needSchemaValidate, 10);
1672
    return needSchemaValidate;
1673
   
1674
  }
1675
  
1676
   /* check if the xml string contains key words to specify schema loocation*/
1677
  private boolean needEml2Validation(String xml)
1678
  {
1679
    boolean needEml2Validate =false;
1680
    if (xml == null)
1681
    {
1682
      MetaCatUtil.debugMessage("Validation for schema is " +
1683
                               needEml2Validate, 10);
1684
      return needEml2Validate;
1685
    }
1686
    else if (xml.indexOf(EML2KEYWORD) != -1)
1687
    {
1688
      // if contains schema location key word, should be validate
1689
      needEml2Validate = true;
1690
    }
1691
    
1692
    MetaCatUtil.debugMessage("Validation for eml is " + 
1693
                             needEml2Validate, 10);
1694
    return needEml2Validate;
1695
   
1696
  }
1697
  
1698
  // DELETE SECTION
1699
  /**
1700
   * Handle the database delete request and delete an XML document
1701
   * from the database connection
1702
   */
1703
  private void handleDeleteAction(PrintWriter out, Hashtable params,
1704
               HttpServletResponse response, String user, String[] groups) {
1705

    
1706
    String[] docid = (String[])params.get("docid");
1707

    
1708
    // delete the document from the database
1709
    try {
1710

    
1711
                                      // NOTE -- NEED TO TEST HERE
1712
                                      // FOR EXISTENCE OF DOCID PARAM
1713
                                      // BEFORE ACCESSING ARRAY
1714
      try {
1715
        DocumentImpl.delete(docid[0], user, groups);
1716
        response.setContentType("text/xml");
1717
        out.println("<?xml version=\"1.0\"?>");
1718
        out.println("<success>");
1719
        out.println("Document deleted.");
1720
        out.println("</success>");
1721
      } catch (AccessionNumberException ane) {
1722
        response.setContentType("text/xml");
1723
        out.println("<?xml version=\"1.0\"?>");
1724
        out.println("<error>");
1725
        out.println("Error deleting document!!!");
1726
        out.println(ane.getMessage());
1727
        out.println("</error>");
1728
      }
1729
    } catch (Exception e) {
1730
      response.setContentType("text/xml");
1731
      out.println("<?xml version=\"1.0\"?>");
1732
      out.println("<error>");
1733
      out.println(e.getMessage());
1734
      out.println("</error>");
1735
    }
1736
  }
1737
  // END OF DELETE SECTION
1738

    
1739
  // VALIDATE SECTION
1740
  /**
1741
   * Handle the validation request and return the results to the requestor
1742
   */
1743
  private void handleValidateAction(PrintWriter out, Hashtable params) {
1744

    
1745
    // Get the document indicated
1746
    String valtext = null;
1747
    DBConnection dbConn = null;
1748
    int serialNumber = -1;
1749

    
1750
    try {
1751
      valtext = ((String[])params.get("valtext"))[0];
1752
    } catch (Exception nullpe) {
1753

    
1754

    
1755
      String docid = null;
1756
      try {
1757
        // Find the document id number
1758
        docid = ((String[])params.get("docid"))[0];
1759

    
1760

    
1761
        // Get the document indicated from the db
1762
        DocumentImpl xmldoc = new DocumentImpl(docid);
1763
        valtext = xmldoc.toString();
1764

    
1765
      } catch (NullPointerException npe) {
1766

    
1767
        out.println("<error>Error getting document ID: " + docid + "</error>");
1768
        //if ( conn != null ) { util.returnConnection(conn); }
1769
        return;
1770
      } catch (Exception e) {
1771

    
1772
        out.println(e.getMessage());
1773
      }
1774
    }
1775

    
1776

    
1777
    try {
1778
      // get a connection from the pool
1779
      dbConn=DBConnectionPool.
1780
                  getDBConnection("MetaCatServlet.handleValidateAction");
1781
      serialNumber=dbConn.getCheckOutSerialNumber();
1782
      DBValidate valobj = new DBValidate(saxparser,dbConn);
1783
      boolean valid = valobj.validateString(valtext);
1784

    
1785
      // set content type and other response header fields first
1786

    
1787
      out.println(valobj.returnErrors());
1788

    
1789
    } catch (NullPointerException npe2) {
1790
      // set content type and other response header fields first
1791

    
1792
      out.println("<error>Error validating document.</error>");
1793
    } catch (Exception e) {
1794

    
1795
      out.println(e.getMessage());
1796
    } finally {
1797
      // Return db connection
1798
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1799
    }
1800
  }
1801
  // END OF VALIDATE SECTION
1802

    
1803
  // OTHER ACTION HANDLERS
1804

    
1805
  /**
1806
   * Handle "getrevsionanddoctype" action
1807
   * Given a docid, return it's current revision and doctype from data base
1808
   * The output is String look like "rev;doctype"
1809
   */
1810
  private void handleGetRevisionAndDocTypeAction(PrintWriter out,
1811
                                                              Hashtable params)
1812
  {
1813
    // To store doc parameter
1814
    String [] docs = new String[10];
1815
    // Store a single doc id
1816
    String givenDocId = null;
1817
    // Get docid from parameters
1818
    if (params.containsKey("docid"))
1819
    {
1820
      docs = (String[])params.get("docid");
1821
    }
1822
    // Get first docid form string array
1823
    givenDocId = docs[0];
1824

    
1825
    try
1826
    {
1827
      // Make sure there is a docid
1828
      if (givenDocId == null || givenDocId.equals(""))
1829
      {
1830
        throw new Exception("User didn't specify docid!");
1831
      }//if
1832

    
1833
      // Create a DBUtil object
1834
      DBUtil dbutil = new DBUtil();
1835
      // Get a rev and doctype
1836
      String revAndDocType =
1837
                dbutil.getCurrentRevisionAndDocTypeForGivenDocument(givenDocId);
1838
      out.println(revAndDocType);
1839

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

    
1850
  }//handleGetRevisionAndDocTypeAction
1851

    
1852
  /**
1853
   * Handle "getaccesscontrol" action.
1854
   * Read Access Control List from db connection in XML format
1855
   */
1856
  private void handleGetAccessControlAction(PrintWriter out, Hashtable params,
1857
                                       HttpServletResponse response,
1858
                                       String username, String[] groupnames) {
1859

    
1860
    DBConnection dbConn = null;
1861
    int serialNumber = -1;
1862
    String docid = ((String[])params.get("docid"))[0];
1863

    
1864
    try {
1865

    
1866
        // get connection from the pool
1867
        dbConn=DBConnectionPool.
1868
                 getDBConnection("MetaCatServlet.handleGetAccessControlAction");
1869
        serialNumber=dbConn.getCheckOutSerialNumber();
1870
        AccessControlList aclobj = new AccessControlList(dbConn);
1871
        String acltext = aclobj.getACL(docid, username, groupnames);
1872
        out.println(acltext);
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
    } finally {
1880
      // Retrun db connection to pool
1881
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
1882
    }
1883

    
1884
  }
1885

    
1886
  /**
1887
   * Handle the "getprincipals" action.
1888
   * Read all principals from authentication scheme in XML format
1889
   */
1890
  private void handleGetPrincipalsAction(PrintWriter out, String user,
1891
                                         String password) {
1892

    
1893

    
1894
    try {
1895

    
1896

    
1897
        AuthSession auth = new AuthSession();
1898
        String principals = auth.getPrincipals(user, password);
1899
        out.println(principals);
1900

    
1901
    } catch (Exception e) {
1902
      out.println("<?xml version=\"1.0\"?>");
1903
      out.println("<error>");
1904
      out.println(e.getMessage());
1905
      out.println("</error>");
1906
    }
1907

    
1908
  }
1909

    
1910
  /**
1911
   * Handle "getdoctypes" action.
1912
   * Read all doctypes from db connection in XML format
1913
   */
1914
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params,
1915
                                       HttpServletResponse response) {
1916

    
1917

    
1918
    try {
1919

    
1920

    
1921
        DBUtil dbutil = new DBUtil();
1922
        String doctypes = dbutil.readDoctypes();
1923
        out.println(doctypes);
1924

    
1925
    } catch (Exception e) {
1926
      out.println("<?xml version=\"1.0\"?>");
1927
      out.println("<error>");
1928
      out.println(e.getMessage());
1929
      out.println("</error>");
1930
    }
1931

    
1932
  }
1933

    
1934
  /**
1935
   * Handle the "getdtdschema" action.
1936
   * Read DTD or Schema file for a given doctype from Metacat catalog system
1937
   */
1938
  private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
1939
                                        HttpServletResponse response) {
1940

    
1941

    
1942
    String doctype = null;
1943
    String[] doctypeArr = (String[])params.get("doctype");
1944

    
1945
    // get only the first doctype specified in the list of doctypes
1946
    // it could be done for all doctypes in that list
1947
    if (doctypeArr != null) {
1948
        doctype = ((String[])params.get("doctype"))[0];
1949
    }
1950

    
1951
    try {
1952

    
1953

    
1954
        DBUtil dbutil = new DBUtil();
1955
        String dtdschema = dbutil.readDTDSchema(doctype);
1956
        out.println(dtdschema);
1957

    
1958
    } catch (Exception e) {
1959
      out.println("<?xml version=\"1.0\"?>");
1960
      out.println("<error>");
1961
      out.println(e.getMessage());
1962
      out.println("</error>");
1963
    }
1964

    
1965
  }
1966

    
1967
  /**
1968
   * Handle the "getdataguide" action.
1969
   * Read Data Guide for a given doctype from db connection in XML format
1970
   */
1971
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params,
1972
                                        HttpServletResponse response) {
1973

    
1974

    
1975
    String doctype = null;
1976
    String[] doctypeArr = (String[])params.get("doctype");
1977

    
1978
    // get only the first doctype specified in the list of doctypes
1979
    // it could be done for all doctypes in that list
1980
    if (doctypeArr != null) {
1981
        doctype = ((String[])params.get("doctype"))[0];
1982
    }
1983

    
1984
    try {
1985

    
1986

    
1987
        DBUtil dbutil = new DBUtil();
1988
        String dataguide = dbutil.readDataGuide(doctype);
1989
        out.println(dataguide);
1990

    
1991
    } catch (Exception e) {
1992
      out.println("<?xml version=\"1.0\"?>");
1993
      out.println("<error>");
1994
      out.println(e.getMessage());
1995
      out.println("</error>");
1996
    }
1997

    
1998
  }
1999

    
2000
  /**
2001
   * Handle the "getlastdocid" action.
2002
   * Get the latest docid with rev number from db connection in XML format
2003
   */
2004
  private void handleGetMaxDocidAction(PrintWriter out, Hashtable params,
2005
                                        HttpServletResponse response) {
2006

    
2007

    
2008
    String scope = ((String[])params.get("scope"))[0];
2009
    if (scope == null) {
2010
        scope = ((String[])params.get("username"))[0];
2011
    }
2012

    
2013
    try {
2014

    
2015

    
2016
        DBUtil dbutil = new DBUtil();
2017
        String lastDocid = dbutil.getMaxDocid(scope);
2018
        out.println("<?xml version=\"1.0\"?>");
2019
        out.println("<lastDocid>");
2020
        out.println("  <scope>" + scope + "</scope>");
2021
        out.println("  <docid>" + lastDocid + "</docid>");
2022
        out.println("</lastDocid>");
2023

    
2024
    } catch (Exception e) {
2025
      out.println("<?xml version=\"1.0\"?>");
2026
      out.println("<error>");
2027
      out.println(e.getMessage());
2028
      out.println("</error>");
2029
    }
2030

    
2031
  }
2032

    
2033
  /**
2034
   * Handle documents passed to metacat that are encoded using the
2035
   * "multipart/form-data" mime type.  This is typically used for uploading
2036
   * data files which may be binary and large.
2037
   */
2038
  private void handleMultipartForm(HttpServletRequest request,
2039
                                   HttpServletResponse response)
2040
  {
2041
    PrintWriter out = null;
2042
    String action = null;
2043

    
2044
    // Parse the multipart form, and save the parameters in a Hashtable and
2045
    // save the FileParts in a hashtable
2046

    
2047
    Hashtable params = new Hashtable();
2048
    Hashtable fileList = new Hashtable();
2049

    
2050
    try {
2051
      // MBJ: need to put filesize limit in Metacat config (metacat.properties)
2052
      MultipartParser mp = new MultipartParser(request, 200*1024*1024); //200MB
2053
      Part part;
2054
      while ((part = mp.readNextPart()) != null) {
2055
        String name = part.getName();
2056

    
2057
        if (part.isParam()) {
2058
          // it's a parameter part
2059
          ParamPart paramPart = (ParamPart) part;
2060
          String value = paramPart.getStringValue();
2061
          params.put(name, value);
2062
          if (name.equals("action")) {
2063
            action = value;
2064
          }
2065
        } else if (part.isFile()) {
2066
          // it's a file part
2067
          FilePart filePart = (FilePart) part;
2068
          fileList.put(name, filePart);
2069

    
2070
          // Stop once the first file part is found, otherwise going onto the
2071
          // next part prevents access to the file contents.  So...for upload
2072
          // to work, the datafile must be the last part
2073
          break;
2074
        }
2075
      }
2076
    } catch (IOException ioe) {
2077
      try {
2078
        out = response.getWriter();
2079
      } catch (IOException ioe2) {
2080
        System.err.println("Fatal Error: couldn't get response output stream.");
2081
      }
2082
      out.println("<?xml version=\"1.0\"?>");
2083
      out.println("<error>");
2084
      out.println("Error: problem reading multipart data.");
2085
      out.println("</error>");
2086
    }
2087

    
2088
    // Get the session information
2089
    String username = null;
2090
    String password = null;
2091
    String[] groupnames = null;
2092
    String sess_id = null;
2093

    
2094
    // be aware of session expiration on every request
2095
    HttpSession sess = request.getSession(true);
2096
    if (sess.isNew()) {
2097
      // session expired or has not been stored b/w user requests
2098
      username = "public";
2099
      sess.setAttribute("username", username);
2100
    } else {
2101
      username = (String)sess.getAttribute("username");
2102
      password = (String)sess.getAttribute("password");
2103
      groupnames = (String[])sess.getAttribute("groupnames");
2104
      try {
2105
        sess_id = (String)sess.getId();
2106
      } catch(IllegalStateException ise) {
2107
        System.out.println("error in  handleMultipartForm: this shouldn't " +
2108
                           "happen: the session should be valid: " +
2109
                           ise.getMessage());
2110
      }
2111
    }
2112

    
2113
    // Get the out stream
2114
    try {
2115
          out = response.getWriter();
2116
        } catch (IOException ioe2) {
2117
          util.debugMessage("Fatal Error: couldn't get response "+
2118
                                                              "output stream.");
2119
        }
2120

    
2121
    if ( action.equals("upload")) {
2122
      if (username != null &&  !username.equals("public")) {
2123
        handleUploadAction(request, out, params, fileList,
2124
                           username, groupnames);
2125
      } else {
2126

    
2127
        out.println("<?xml version=\"1.0\"?>");
2128
        out.println("<error>");
2129
        out.println("Permission denied for " + action);
2130
        out.println("</error>");
2131
      }
2132
    } else {
2133
      /*try {
2134
        out = response.getWriter();
2135
      } catch (IOException ioe2) {
2136
        System.err.println("Fatal Error: couldn't get response output stream.");
2137
      }*/
2138
      out.println("<?xml version=\"1.0\"?>");
2139
      out.println("<error>");
2140
      out.println("Error: action not registered.  Please report this error.");
2141
      out.println("</error>");
2142
    }
2143
    out.close();
2144
  }
2145

    
2146
  /**
2147
   * Handle the upload action by saving the attached file to disk and
2148
   * registering it in the Metacat db
2149
   */
2150
  private void handleUploadAction(HttpServletRequest request,
2151
                                  PrintWriter out,
2152
                                  Hashtable params, Hashtable fileList,
2153
                                  String username, String[] groupnames)
2154
  {
2155
    //PrintWriter out = null;
2156
    //Connection conn = null;
2157
    String action = null;
2158
    String docid = null;
2159

    
2160
    /*response.setContentType("text/xml");
2161
    try
2162
    {
2163
      out = response.getWriter();
2164
    }
2165
    catch (IOException ioe2)
2166
    {
2167
      System.err.println("Fatal Error: couldn't get response output stream.");
2168
    }*/
2169

    
2170
    if (params.containsKey("docid"))
2171
    {
2172
      docid = (String)params.get("docid");
2173
    }
2174

    
2175
    // Make sure we have a docid and datafile
2176
    if (docid != null && fileList.containsKey("datafile")) {
2177

    
2178
      // Get a reference to the file part of the form
2179
      FilePart filePart = (FilePart)fileList.get("datafile");
2180
      String fileName = filePart.getFileName();
2181
      MetaCatUtil.debugMessage("Uploading filename: " + fileName, 10);
2182

    
2183
      // Check if the right file existed in the uploaded data
2184
      if (fileName != null) {
2185

    
2186
        try
2187
        {
2188
           //MetaCatUtil.debugMessage("Upload datafile " + docid +"...", 10);
2189
           //If document get lock data file grant
2190
           if (DocumentImpl.getDataFileLockGrant(docid))
2191
           {
2192
              // register the file in the database (which generates an exception
2193
              //if the docid is not acceptable or other untoward things happen
2194
              DocumentImpl.registerDocument(fileName, "BIN", docid, username);
2195

    
2196
              // Save the data file to disk using "docid" as the name
2197
              dataDirectory.mkdirs();
2198
              File newFile = new File(dataDirectory, docid);
2199
              long size = filePart.writeTo(newFile);
2200

    
2201
              // Force replication this data file
2202
              // To data file, "insert" and update is same
2203
              // The fourth parameter is null. Because it is notification server
2204
              // and this method is in MetaCatServerlet. It is original command,
2205
              // not get force replication info from another metacat
2206
              ForceReplicationHandler frh = new ForceReplicationHandler
2207
                                                (docid, "insert", false, null);
2208

    
2209
              // set content type and other response header fields first
2210
              out.println("<?xml version=\"1.0\"?>");
2211
              out.println("<success>");
2212
              out.println("<docid>" + docid + "</docid>");
2213
              out.println("<size>" + size + "</size>");
2214
              out.println("</success>");
2215
          }//if
2216

    
2217
        } //try
2218
        catch (Exception e)
2219
        {
2220
          out.println("<?xml version=\"1.0\"?>");
2221
          out.println("<error>");
2222
          out.println(e.getMessage());
2223
          out.println("</error>");
2224
        }
2225

    
2226
      }
2227
      else
2228
      {
2229
        // the field did not contain a file
2230
        out.println("<?xml version=\"1.0\"?>");
2231
        out.println("<error>");
2232
        out.println("The uploaded data did not contain a valid file.");
2233
        out.println("</error>");
2234
      }
2235
    }
2236
    else
2237
    {
2238
      // Error bcse docid missing or file missing
2239
      out.println("<?xml version=\"1.0\"?>");
2240
      out.println("<error>");
2241
      out.println("The uploaded data did not contain a valid docid " +
2242
                  "or valid file.");
2243
      out.println("</error>");
2244
    }
2245
  }
2246
  
2247
  /*
2248
   * A method to handle set access action
2249
   */
2250
  private void handleSetAccessAction(PrintWriter out,
2251
                                   Hashtable params,
2252
                                   String username)
2253
  {
2254
    String [] docList        = null;
2255
    String [] principalList  = null;
2256
    String [] permissionList = null;
2257
    String [] permTypeList   = null;
2258
    String [] permOrderList  = null;
2259
    String permission = null;
2260
    String permType   = null;
2261
    String permOrder  = null;
2262
    Vector errorList  = new Vector();
2263
    String error      = null;
2264
    Vector successList = new Vector();
2265
    String success    = null;
2266
   
2267
    
2268
    // Get parameters
2269
    if (params.containsKey("docid")) 
2270
    {
2271
      docList = (String[])params.get("docid");
2272
    }
2273
    if (params.containsKey("principal"))
2274
    {
2275
      principalList = (String[])params.get("principal"); 
2276
    }
2277
    if (params.containsKey("permission"))
2278
    {
2279
      permissionList = (String[])params.get("permission");
2280
      
2281
    }
2282
    if (params.containsKey("permType"))
2283
    {
2284
      permTypeList = (String[])params.get("permType");
2285
    
2286
    }
2287
    if (params.containsKey("permOrder"))
2288
    {
2289
      permOrderList = (String[])params.get("permOrder");
2290
     
2291
    }
2292
   
2293
    // Make sure the parameter is not null
2294
    if (docList == null || principalList == null || permTypeList == null ||
2295
        permissionList == null)
2296
    {
2297
      error = "Please check your parameter list, it should look like: "+
2298
              "?action=setaccess&docid=pipeline.1.1&principal=public" +
2299
              "&permission=read&permType=allow&permOrder=allowFirst";
2300
      errorList.addElement(error);
2301
      outputResponse(successList, errorList, out);
2302
      return;
2303
    }
2304
    
2305
    // Only select first element for permission, type and order
2306
    permission = permissionList[0];
2307
    permType = permTypeList[0];
2308
    if (permOrderList != null)
2309
    {
2310
       permOrder = permOrderList[0];
2311
    }
2312
    
2313
    // Get package doctype set
2314
    Vector packageSet =MetaCatUtil.getOptionList(
2315
                                    MetaCatUtil.getOption("packagedoctypeset"));
2316
    //debug
2317
    if (packageSet != null)
2318
    {
2319
      for (int i = 0; i<packageSet.size(); i++)
2320
      {
2321
        MetaCatUtil.debugMessage("doctype in package set: " + 
2322
                              (String)packageSet.elementAt(i), 34);
2323
      }
2324
    }//if
2325
    
2326
    // handle every accessionNumber
2327
    for (int i=0; i <docList.length; i++)
2328
    {
2329
      String accessionNumber = docList[i];
2330
      String owner = null;
2331
      String publicId = null;
2332
      // Get document owner and public id
2333
      try
2334
      {
2335
        owner = getFieldValueForDoc(accessionNumber, "user_owner");
2336
        publicId = getFieldValueForDoc(accessionNumber, "doctype");
2337
      }//try
2338
      catch (Exception e)
2339
      {
2340
        MetaCatUtil.debugMessage("Error in handleSetAccessAction: " +
2341
                                  e.getMessage(), 30);
2342
        error = "Error in set access control for document - " + accessionNumber+
2343
                 e.getMessage();
2344
        errorList.addElement(error);
2345
        continue;
2346
      }
2347
      //check if user is the owner. Only owner can do owner                            
2348
      if (username == null || owner == null || !username.equals(owner))
2349
      {
2350
        error = "User - " + username + " does not have permission to set " +
2351
                "access control for docid - " + accessionNumber;
2352
        errorList.addElement(error);
2353
        continue;
2354
      }
2355
      
2356
      // If docid publicid is BIN data file or other beta4, 6 package document
2357
      // we could not do set access control. Because we don't want inconsistent
2358
      // to its access docuemnt
2359
      if (publicId!=null && packageSet!=null && packageSet.contains(publicId))
2360
      {
2361
        error = "Could not set access control to document "+ accessionNumber +
2362
                "because it is in a pakcage and it has a access file for it";
2363
        errorList.addElement(error);
2364
        continue;
2365
      }
2366
      
2367
      // for every principle
2368
      for (int j = 0; j<principalList.length; j++)
2369
      {
2370
        String principal = principalList[j];
2371
        try
2372
        {
2373
          //insert permission
2374
          AccessControlForSingleFile accessControl = new 
2375
                           AccessControlForSingleFile(accessionNumber,
2376
                                    principal, permission, permType, permOrder);
2377
          accessControl.insertPermissions();
2378
          success = "Set access control to document "+ accessionNumber +
2379
                    " successfully";
2380
          successList.addElement(success);
2381
        }
2382
        catch (Exception ee)
2383
        {
2384
          MetaCatUtil.debugMessage("Erorr in handleSetAccessAction2: " +
2385
                                   ee.getMessage(), 30);
2386
          error = "Faild to set access control for document " + 
2387
                  accessionNumber + " because " + ee.getMessage();
2388
          errorList.addElement(error);
2389
          continue;
2390
        }
2391
      }//for every principle
2392
    }//for every document 
2393
    outputResponse(successList, errorList, out);
2394
  }//handleSetAccessAction
2395
  
2396
 
2397
  /*
2398
   * A method try to determin a docid's public id, if couldn't find null
2399
   * will be returned.
2400
   */
2401
  private String getFieldValueForDoc(String accessionNumber, String fieldName) 
2402
                                      throws Exception
2403
  {
2404
    if (accessionNumber==null || accessionNumber.equals("") ||fieldName == null
2405
        || fieldName.equals(""))
2406
    {
2407
      throw new Exception("Docid or field name was not specified");
2408
    }
2409
    
2410
    PreparedStatement pstmt = null;
2411
    ResultSet rs = null;
2412
    String fieldValue = null;
2413
    String docId = null;
2414
    DBConnection conn = null;
2415
    int serialNumber = -1;
2416
    
2417
    // get rid of revision if access number has
2418
    docId = MetaCatUtil.getDocIdFromString(accessionNumber);
2419
    try
2420
    {
2421
      //check out DBConnection
2422
      conn=DBConnectionPool.getDBConnection("MetaCatServlet.getPublicIdForDoc");
2423
      serialNumber=conn.getCheckOutSerialNumber();
2424
      pstmt = conn.prepareStatement(
2425
            "SELECT " + fieldName + " FROM xml_documents " +
2426
            "WHERE docid = ? ");
2427
          
2428
      pstmt.setString(1, docId);
2429
      pstmt.execute();
2430
      rs = pstmt.getResultSet();
2431
      boolean hasRow = rs.next();
2432
      int perm = 0;
2433
      if ( hasRow ) 
2434
      {
2435
        fieldValue = rs.getString(1);
2436
      }
2437
      else
2438
      {
2439
        throw new Exception("Could not find document: "+accessionNumber);
2440
      }
2441
    }//try
2442
    catch (Exception e)
2443
    {
2444
      MetaCatUtil.debugMessage("Exception in MetacatServlet.getPublicIdForDoc: "
2445
                               + e.getMessage(), 30);
2446
      throw e;
2447
    }
2448
    finally
2449
    {
2450
      try
2451
      {
2452
        rs.close();
2453
        pstmt.close();
2454
        
2455
      }
2456
      finally
2457
      {
2458
        DBConnectionPool.returnDBConnection(conn, serialNumber);
2459
      }
2460
    }
2461
    return fieldValue;
2462
  }//getFieldValueForDoc
2463
  
2464
  /*
2465
   * A method to output setAccess action result
2466
   */
2467
  private void outputResponse(Vector successList, 
2468
                              Vector errorList,
2469
                              PrintWriter out)
2470
  {
2471
    boolean error = false;
2472
    boolean success = false;
2473
    // Output prolog
2474
    out.println(PROLOG);
2475
    // output success message
2476
    if ( successList != null)
2477
    {
2478
      for (int i = 0; i<successList.size(); i++)
2479
      {
2480
        out.println(SUCCESS);
2481
        out.println((String)successList.elementAt(i));
2482
        out.println(SUCCESSCLOSE);
2483
        success = true;
2484
      }//for
2485
    }//if
2486
    // output error message
2487
    if (errorList != null)
2488
    {
2489
      for (int i = 0; i<errorList.size(); i++)
2490
      {
2491
        out.println(ERROR);
2492
        out.println((String)errorList.elementAt(i));
2493
        out.println(ERRORCLOSE);
2494
        error = true;
2495
      }//for
2496
    }//if
2497
    
2498
    // if no error and no success info, send a error that nothing happened
2499
    if( !error && !success)
2500
    {
2501
      out.println(ERROR);
2502
      out.println("Nothing happend for setaccess action");
2503
      out.println(ERRORCLOSE);
2504
    }
2505
    
2506
  }//outputResponse
2507
}
(37-37/54)