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: bojilova $'
10
 *     '$Date: 2001-05-01 16:42:22 -0700 (Tue, 01 May 2001) $'
11
 * '$Revision: 731 $'
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 java.io.PrintWriter;
31
import java.io.IOException;
32
import java.io.StringReader;
33
import java.io.FileInputStream;
34
import java.io.BufferedInputStream;
35
import java.util.Enumeration;
36
import java.util.Hashtable;
37
import java.util.ResourceBundle; 
38
import java.util.Random;
39
import java.util.PropertyResourceBundle;
40
import java.net.URL;
41
import java.net.MalformedURLException;
42
import java.sql.PreparedStatement;
43
import java.sql.ResultSet;
44
import java.sql.Connection;
45
import java.sql.SQLException;
46
import java.lang.reflect.*;
47
import java.net.*;
48
import java.util.zip.*;
49

    
50
import javax.servlet.ServletConfig;
51
import javax.servlet.ServletContext;
52
import javax.servlet.ServletException;
53
import javax.servlet.ServletInputStream;
54
import javax.servlet.http.HttpServlet;
55
import javax.servlet.http.HttpServletRequest;
56
import javax.servlet.http.HttpServletResponse;
57
import javax.servlet.http.HttpSession;
58
import javax.servlet.http.HttpUtils;
59
import javax.servlet.ServletOutputStream;
60

    
61
import oracle.xml.parser.v2.XSLStylesheet;
62
import oracle.xml.parser.v2.XSLException;
63
import oracle.xml.parser.v2.XMLDocumentFragment;
64
import oracle.xml.parser.v2.XSLProcessor;
65

    
66
import org.xml.sax.SAXException;
67

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

    
104
  private ServletConfig config = null;
105
  private ServletContext context = null;
106
  private Hashtable connectionPool = new Hashtable();
107
  private String resultStyleURL = null;
108
  private String xmlcatalogfile = null;
109
  private String saxparser = null;
110
  private String defaultdatapath = null; 
111
  private String servletpath = null; 
112
  private PropertyResourceBundle options = null;
113
  private MetaCatUtil util = null;
114

    
115
  // path to directory where data files 
116
  // that can be downloaded will be stored
117
  private String htmlpath = null; 
118
  // script to get data file and put it 
119
  // in defaultdocpath dir
120
  private String executescript  = null;  
121

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

    
132
      util = new MetaCatUtil();
133

    
134
      // Get the configuration file information
135
      resultStyleURL = util.getOption("resultStyleURL");
136
      xmlcatalogfile = util.getOption("xmlcatalogfile");
137
      saxparser = util.getOption("saxparser");
138
      defaultdatapath = util.getOption("defaultdatapath");
139
      executescript = util.getOption("executescript"); 
140
      servletpath = util.getOption("servletpath");
141
      htmlpath = util.getOption("htmlpath");
142

    
143
// MOVED IT TO doGet() & doPost()
144
//      try {
145
//        // Open a pool of db connections
146
//        connectionPool = util.getConnectionPool();
147
//      } catch (Exception e) {
148
//        System.err.println("Error creating pool of database connections");
149
//        System.err.println(e.getMessage());
150
//      }
151
    } catch ( ServletException ex ) {
152
      throw ex;
153
    }
154
  }
155

    
156
  /**
157
   * Close all db connections from the pool
158
   */
159
  public void destroy() {
160
    
161
    if (util != null) {
162
        util.closeConnections();
163
    }
164
  }
165

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

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

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

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

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

    
190
    if ( util == null ) {
191
        util = new MetaCatUtil(); 
192
    }
193
    if ( connectionPool.isEmpty() ) {
194
      try {
195
        // Open a pool of db connections
196
        connectionPool = util.getConnectionPool();
197
      } catch (Exception e) {
198
        System.err.println("Error creating pool of database connections in " +
199
                            " MetaCatServlet.handleGetOrPost");
200
        System.err.println(e.getMessage());
201
      }
202
    }    
203
    // Get a handle to the output stream back to the client
204
    //PrintWriter pwout = response.getWriter();
205
    //response.setContentType("text/html");
206
  
207
    String name = null;
208
    String[] value = null;
209
    String[] docid = new String[3];
210
    Hashtable params = new Hashtable();
211
    Enumeration paramlist = request.getParameterNames();
212
    while (paramlist.hasMoreElements()) {
213
      name = (String)paramlist.nextElement();
214
      value = request.getParameterValues(name);
215

    
216
      // Decode the docid and mouse click information
217
      if (name.endsWith(".y")) {
218
        docid[0] = name.substring(0,name.length()-2);
219
        params.put("docid", docid);
220
        name = "ypos";
221
      }
222
      if (name.endsWith(".x")) {
223
        name = "xpos";
224
      } 
225

    
226
      params.put(name,value); 
227
    }  
228
    
229
    //if the user clicked on the input images, decode which image
230
    //was clicked then set the action.
231
    String action = ((String[])params.get("action"))[0];  
232
    util.debugMessage("Line 213: Action is: " + action);
233

    
234
    // This block handles session management for the servlet
235
    // by looking up the current session information for all actions
236
    // other than "login" and "logout"
237
    String username = null;
238
    String password = null;
239
    String groupname = null;
240
    String sess_id = null;
241

    
242
    // handle login action
243
    if (action.equals("login")) {
244

    
245
      handleLoginAction(response.getWriter(), params, request, response);
246

    
247
    // handle logout action  
248
    } else if (action.equals("logout")) {
249

    
250
      handleLogoutAction(response.getWriter(), params, request, response);
251

    
252
    // aware of session expiration on every request  
253
    } else {   
254

    
255
      HttpSession sess = request.getSession(true);
256
      if (sess.isNew()) { 
257
        // session expired or has not been stored b/w user requests
258
        username = "public";
259
        sess.setAttribute("username", username);
260
      } else {
261
        username = (String)sess.getAttribute("username");
262
        password = (String)sess.getAttribute("password");
263
        groupname = (String)sess.getAttribute("groupname");
264
        try {
265
          sess_id = (String)sess.getId();
266
        } catch(IllegalStateException ise) {
267
          System.out.println("error in handleGetOrPost: this shouldn't " +
268
                             "happen: the session should be valid: " + 
269
                             ise.getMessage());
270
        }
271
      }  
272
    }    
273

    
274
    // Now that we know the session is valid, we can delegate the request
275
    // to a particular action handler
276
    if(action.equals("query")) {
277
      handleQuery(response.getWriter(), params, response, username, groupname); 
278
    } else if(action.equals("squery")) {
279
      if(params.containsKey("query")) {
280
        handleSQuery(response.getWriter(), params, response, username, groupname); 
281
      } else {
282
        PrintWriter out = response.getWriter();
283
        out.println("Illegal action squery without \"query\" parameter");
284
      }
285
    } else if (action.equals("read")) {
286
      handleReadAction(params, response, username, groupname);
287
    } else if (action.equals("insert") || action.equals("update")) {
288
      PrintWriter out = response.getWriter();
289
      if ( (username != null) &&  !username.equals("public") ) {
290
        handleInsertOrUpdateAction(out, params, response, username, groupname);
291
      } else {  
292
        out.println("Permission denied for " + action);
293
      }  
294
    } else if (action.equals("delete")) {
295
      PrintWriter out = response.getWriter();
296
      if ( (username != null) &&  !username.equals("public") ) {
297
        handleDeleteAction(out, params, response, username, groupname);
298
      } else {  
299
        out.println("Permission denied for " + action);
300
      }  
301
    } else if (action.equals("validate")) {
302
      PrintWriter out = response.getWriter();
303
      handleValidateAction(out, params, response); 
304
    } else if (action.equals("getdataport")) {
305
      PrintWriter out = response.getWriter();
306
      if ( (username != null) &&  !username.equals("public") ) {
307
      handleGetDataPortAction(out, params, response, username, groupname, 
308
                              sess_id);
309
      } else {
310
        out.println("You must be authenticated to perform the getdataport " +
311
                    "action!");
312
      }
313
    } else if (action.equals("getaccesscontrol")) {
314
      PrintWriter out = response.getWriter();
315
      handleGetAccessControlAction(out, params, response, username, groupname);
316
    } else if (action.equals("getprincipals")) {
317
      PrintWriter out = response.getWriter();
318
      handleGetPrincipalsAction(out, username, password);  
319
    } else if (action.equals("getdoctypes")) {
320
      PrintWriter out = response.getWriter();
321
      handleGetDoctypesAction(out, params, response);  
322
    } else if (action.equals("getdtdschema")) {
323
      PrintWriter out = response.getWriter();
324
      handleGetDTDSchemaAction(out, params, response);  
325
    } else if (action.equals("getdataguide")) {
326
      PrintWriter out = response.getWriter();
327
      handleGetDataGuideAction(out, params, response);  
328
    } else if (action.equals("login") || action.equals("logout")) {
329
    } else if (action.equals("protocoltest")) {
330
      String testURL = "metacat://dev.nceas.ucsb.edu/NCEAS.897766.9";
331
      try {
332
        testURL = ((String[])params.get("url"))[0];
333
      } catch (Throwable t) {
334
      }
335
      String phandler = System.getProperty("java.protocol.handler.pkgs");
336
      response.setContentType("text/html");
337
      PrintWriter out = response.getWriter();
338
      out.println("<body bgcolor=\"white\">");
339
      out.println("<p>Handler property: <code>" + phandler + "</code></p>");
340
      out.println("<p>Starting test for:<br>");
341
      out.println("    " + testURL + "</p>");
342
      try {
343
        URL u = new URL(testURL);
344
        out.println("<pre>");
345
        out.println("Protocol: " + u.getProtocol());
346
        out.println("    Host: " + u.getHost());
347
        out.println("    Port: " + u.getPort());
348
        out.println("    Path: " + u.getPath());
349
        out.println("     Ref: " + u.getRef());
350
        String pquery = u.getQuery();
351
        out.println("   Query: " + pquery);
352
        out.println("  Params: ");
353
        if (pquery != null) {
354
          Hashtable qparams = util.parseQuery(u.getQuery());
355
          for (Enumeration en = qparams.keys(); en.hasMoreElements(); ) {
356
            String pname = (String)en.nextElement();
357
            String pvalue = (String)qparams.get(pname);
358
            out.println("    " + pname + ": " + pvalue);
359
          }
360
        }
361
        out.println("</pre>");
362
        out.println("</body>");
363
        out.close();
364
      } catch (MalformedURLException mue) {
365
        System.out.println("bad url from MetacatServlet.handleGetOrPost");
366
        out.println(mue.getMessage());
367
        mue.printStackTrace(out);
368
        out.close();
369
      }
370
    } else {
371
      PrintWriter out = response.getWriter();
372
      out.println("Error: action not registered.  Please report this error.");
373
    }
374
    
375
    util.closeConnections();
376
    // Close the stream to the client
377
    // out.close();
378
  }
379
  
380
  // LOGIN & LOGOUT SECTION
381
  /** 
382
   * Handle the login request. Create a new session object.
383
   * Do user authentication through the session.
384
   */
385
  private void handleLoginAction(PrintWriter out, Hashtable params, 
386
               HttpServletRequest request, HttpServletResponse response) {
387

    
388
    AuthSession sess = null;
389
    String un = ((String[])params.get("username"))[0];
390
    String pw = ((String[])params.get("password"))[0];
391
    String action = ((String[])params.get("action"))[0];
392
    String qformat = ((String[])params.get("qformat"))[0];
393
    
394
    try {
395
      sess = new AuthSession();
396
    } catch (Exception e) {
397
      System.out.println("error in MetacatServlet.handleLoginAction: " +
398
                          e.getMessage());
399
      out.println(e.getMessage());
400
      return;
401
    }
402
    
403
    boolean isValid = sess.authenticate(request, un, pw);
404

    
405
    // format and transform the output
406
    if (qformat.equals("html")) {
407
      Connection conn = null;
408
      try {
409
        conn = util.getConnection();
410
        DBTransform trans = new DBTransform(conn);
411
        response.setContentType("text/html");
412
        trans.transformXMLDocument(sess.getMessage(), "-//NCEAS//login//EN",
413
                                   "-//W3C//HTML//EN", out);
414
        util.returnConnection(conn); 
415
      } catch(Exception e) {
416
        util.returnConnection(conn); 
417
      } 
418
      
419
    // any output is returned  
420
    } else {
421
      response.setContentType("text/xml");
422
      out.println(sess.getMessage()); 
423
    }
424
  }    
425

    
426
  /** 
427
   * Handle the logout request. Close the connection.
428
   */
429
  private void handleLogoutAction(PrintWriter out, Hashtable params, 
430
               HttpServletRequest request, HttpServletResponse response) {
431

    
432
    String qformat = ((String[])params.get("qformat"))[0];
433

    
434
    // close the connection
435
    HttpSession sess = request.getSession(false);
436
    if (sess != null) { sess.invalidate();  }    
437

    
438
    // produce output
439
    StringBuffer output = new StringBuffer();
440
    output.append("<?xml version=\"1.0\"?>");
441
    output.append("<logout>");
442
    output.append("User logged out");
443
    output.append("</logout>");
444

    
445
    //format and transform the output
446
    if (qformat.equals("html")) {
447
      Connection conn = null;
448
      try {
449
        conn = util.getConnection();
450
        DBTransform trans = new DBTransform(conn);
451
        response.setContentType("text/html");
452
        trans.transformXMLDocument(output.toString(), "-//NCEAS//login//EN", 
453
                                   "-//W3C//HTML//EN", out);
454
        util.returnConnection(conn); 
455
      } catch(Exception e) {
456
        util.returnConnection(conn); 
457
      } 
458
    // any output is returned  
459
    } else {
460
      response.setContentType("text/xml");
461
      out.println(output.toString()); 
462
    }
463
  }
464
  // END OF LOGIN & LOGOUT SECTION
465
  
466
  // SQUERY & QUERY SECTION
467
  /**      
468
   * Retreive the squery xml, execute it and display it
469
   *
470
   * @param out the output stream to the client
471
   * @param params the Hashtable of parameters that should be included
472
   * in the squery.
473
   * @param response the response object linked to the client
474
   * @param conn the database connection 
475
   */
476
  protected void handleSQuery(PrintWriter out, Hashtable params, 
477
                 HttpServletResponse response, String user, String group)
478
  { 
479
    String xmlquery = ((String[])params.get("query"))[0];
480
    String qformat = ((String[])params.get("qformat"))[0];
481
    String resultdoc = null;
482
    String[] returndoc = null;
483
    if(params.contains("returndoc"))
484
    {
485
      returndoc = (String[])params.get("returndoc");
486
    }
487
    
488
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
489
    //String resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
490

    
491
    resultdoc = createResultDocument(doclist, transformQuery(xmlquery));
492
    
493
    //format and transform the results                                        
494
    if(qformat.equals("html")) {
495
      transformResultset(resultdoc, response, out);
496
    } else if(qformat.equals("xml")) {
497
      response.setContentType("text/xml");
498
      out.println(resultdoc);
499
    } else {
500
      out.println("invalid qformat: " + qformat); 
501
    }
502
  }
503
  
504
   /**
505
    * Create the xml query, execute it and display the results.
506
    *
507
    * @param out the output stream to the client
508
    * @param params the Hashtable of parameters that should be included
509
    * in the squery.
510
    * @param response the response object linked to the client
511
    */ 
512
  protected void handleQuery(PrintWriter out, Hashtable params, 
513
                 HttpServletResponse response, String user, String group)
514
  {
515
    //create the query and run it
516
    String[] returndoc = null;
517
    if(params.containsKey("returndoc"))
518
    {
519
      returndoc = (String[])params.get("returndoc");
520
    }
521
    String xmlquery = DBQuery.createSQuery(params);
522
    Hashtable doclist = runQuery(xmlquery, user, group, returndoc);
523
    String qformat = ((String[])params.get("qformat"))[0];
524
    String resultdoc = null;
525
    
526
    resultdoc = createResultDocument(doclist, transformQuery(params));
527

    
528
    //format and transform the results                                        
529
    if(qformat.equals("html")) {
530
      transformResultset(resultdoc, response, out);
531
    } else if(qformat.equals("xml")) {
532
      response.setContentType("text/xml");
533
      out.println(resultdoc);
534
    } else { 
535
      out.println("invalid qformat: " + qformat); 
536
    }
537
  }
538
  
539
  /**
540
   * Removes the <?xml version="x"?> tag from the beginning of xmlquery
541
   * so it can properly be placed in the <query> tag of the resultset.
542
   * This method is overwritable so that other applications can customize
543
   * the structure of what is in the <query> tag.
544
   * 
545
   * @param xmlquery is the query to remove the <?xml version="x"?> tag from.
546
   */
547
  protected String transformQuery(Hashtable params)
548
  {
549
    //DBQuery.createSQuery is a re-calling of a previously called 
550
    //function but it is necessary
551
    //so that overriding methods have access to the params hashtable
552
    String xmlquery = DBQuery.createSQuery(params);
553
    //the <?xml version="1.0"?> tag is the first 22 characters of the
554
    xmlquery = xmlquery.trim();
555
    int index = xmlquery.indexOf("?>");
556
    return xmlquery.substring(index + 2, xmlquery.length());
557
  }
558
  
559
  /**
560
   * removes the <?xml version="1.0"?> tag from the beginning.  This takes a
561
   * string as a param instead of a hashtable.
562
   * 
563
   * @param xmlquery a string representing a query.
564
   */
565
  protected String transformQuery(String xmlquery)
566
  {
567
    xmlquery = xmlquery.trim();
568
    int index = xmlquery.indexOf("?>");
569
    return xmlquery.substring(index + 2, xmlquery.length());
570
  }
571
  
572
  /**
573
   * Run the query and return a hashtable of results.
574
   *
575
   * @param xmlquery the query to run
576
   */
577
  private Hashtable runQuery(String xmlquery, String user, String group, 
578
                             String[] returndoc)
579
  {
580
    Hashtable doclist=null;
581
    Connection conn = null;
582
    try
583
    {
584
      conn = util.getConnection();
585
      DBQuery queryobj = new DBQuery(conn, saxparser);
586
      doclist = queryobj.findDocuments(new StringReader(xmlquery),user,group,
587
                                       returndoc);
588
      util.returnConnection(conn);
589
      return doclist;
590
    } 
591
    catch (Exception e) 
592
    {
593
      util.returnConnection(conn); 
594
      util.debugMessage("Error in MetacatServlet.runQuery: " + e.getMessage());
595
      doclist = null;
596
      return doclist;
597
    }    
598
  }
599
  
600
  /**
601
   * Transorms an xml resultset document to html and sends it to the browser
602
   *
603
   * @param resultdoc the string representation of the document that needs
604
   * to be transformed.
605
   * @param response the HttpServletResponse object bound to the client.
606
   * @param out the output stream to the client
607
   */ 
608
  protected void transformResultset(String resultdoc, 
609
                                    HttpServletResponse response,
610
                                    PrintWriter out)
611
  {
612
    Connection conn = null;
613
    try {
614
      conn = util.getConnection();
615
      DBTransform trans = new DBTransform(conn);
616
      response.setContentType("text/html");
617
      trans.transformXMLDocument(resultdoc, "-//NCEAS//resultset//EN", 
618
                                 "-//W3C//HTML//EN", out);
619
      util.returnConnection(conn); 
620
    }
621
    catch(Exception e)
622
    {
623
      util.returnConnection(conn); 
624
    } 
625
  }
626
  
627
  /**
628
   * Transforms a hashtable of documents to an xml or html result.
629
   * If there is a returndoc, then it only displays documents of
630
   * whatever type returndoc represents.  If a result is found in a document
631
   * that is not of type returndoc then this attempts to find a relation 
632
   * between this document and one that satifies the returndoc doctype.
633
   *
634
   * @param doclist- the hashtable to transform
635
   * @param xmlquery- the query that returned the dolist result
636
   * @param resultdoc- the document type to backtrack to.
637
   */
638
  protected String createResultDocument(Hashtable doclist, String xmlquery)
639
  {
640
    // Create a buffer to hold the xml result
641
    StringBuffer resultset = new StringBuffer();
642
 
643
    // Print the resulting root nodes 
644
    String docid = null;
645
    String document = null;
646
    resultset.append("<?xml version=\"1.0\"?>\n");
647
    resultset.append("<resultset>\n");
648
      
649
    resultset.append("  <query>" + xmlquery + "</query>");   
650

    
651
    if(doclist != null)
652
    {
653
      Enumeration doclistkeys = doclist.keys(); 
654
      while (doclistkeys.hasMoreElements()) 
655
      {
656
        docid = (String)doclistkeys.nextElement();
657
        document = (String)doclist.get(docid);
658
        resultset.append("  <document>" + document + "</document>");
659
      }
660
    }
661

    
662
    resultset.append("</resultset>");
663
    //System.out.println(resultset.toString());
664
    return resultset.toString();
665
  }
666
  // END OF SQUERY & QUERY SECTION
667
  
668
  // READ SECTION
669
  /** 
670
   * Handle the "read" request of metadata/data files from Metacat
671
   * or any files from Internet;
672
   * transformed metadata XML document into HTML presentation if requested;
673
   * zip files when more than one were requested.
674
   *
675
   * @param params the Hashtable of HTTP request parameters
676
   * @param response the HTTP response object linked to the client
677
   * @param user the username sent the request
678
   * @param group the user's groupname
679
   */
680
  private void handleReadAction(Hashtable params, HttpServletResponse response,
681
                                String user, String group) 
682
  {
683
    ServletOutputStream out = null;
684
    ZipOutputStream zout = null;
685
    
686
    try {
687
      String[] docs = new String[0];
688
      String docid = "";
689
      String qformat = "";
690
      String abstrpath = null;
691
      boolean zip = false;
692
      // read the params
693
      if (params.containsKey("docid")) {
694
        docs = (String[])params.get("docid");
695
      }
696
      if (params.containsKey("qformat")) {
697
        qformat = ((String[])params.get("qformat"))[0];
698
      }
699
      if (params.containsKey("abstractpath")) {
700
        abstrpath = ((String[])params.get("abstractpath"))[0];
701
        viewAbstract(response, abstrpath, docs[0]);
702
      }
703
      if ( (docs.length > 1) || qformat.equals("zip") ) {
704
        zip = true;
705
        out = response.getOutputStream();
706
        response.setContentType("application/zip"); //MIME type
707
        zout = new ZipOutputStream(out);
708
      }
709
      // go through the list of docs to read
710
      for (int i=0; i < docs.length; i++ ) {
711
        try {
712

    
713
          URL murl = new URL(docs[i]);
714
          Hashtable murlQueryStr = util.parseQuery(murl.getQuery());
715
          // case docid="http://.../?docid=aaa" 
716
          // or docid="metacat://.../?docid=bbb"
717
          if (murlQueryStr.containsKey("docid")) {
718
            // get only docid, eliminate the rest
719
            docid = (String)murlQueryStr.get("docid");
720
            if ( zip ) {
721
              addDocToZip(docid, zout);
722
            } else {
723
              readFromMetacat(response, docid, qformat, abstrpath,
724
                              user, group, zip, zout);
725
            }
726

    
727
          // case docid="http://.../filename"
728
          } else {
729
            docid = docs[i];
730
            if ( zip ) {
731
              addDocToZip(docid, zout);
732
            } else {
733
              readFromURLConnection(response, docid);
734
            }
735
          }
736

    
737
        // case docid="ccc"
738
        } catch (MalformedURLException mue) {
739
          docid = docs[i];
740
          if ( zip ) {
741
            addDocToZip(docid, zout);
742
          } else {
743
            readFromMetacat(response, docid, qformat, abstrpath,
744
                            user, group, zip, zout);
745
          }
746
        }
747
        
748
      } /* end for */
749
      
750
      if ( zip ) {
751
        zout.finish(); //terminate the zip file
752
        zout.close();  //close the zip stream
753
      }
754
      
755
    } catch (Exception e) {
756
      try {
757
        if ( out != null ) { out.close(); }
758
        if ( zout != null ) { zout.close(); }
759
        response.setContentType("text/xml"); //MIME type
760
        PrintWriter pw = response.getWriter();
761
        pw.println(e.getMessage());
762
      } catch (IOException ioe) {
763
        System.out.println("Problem with the servlet output " +
764
                           "in MetacatServlet.handleReadAction: " +
765
                           ioe.getMessage());
766
        ioe.printStackTrace(System.out);
767
        
768
      }
769

    
770
      System.out.println("Error in MetacatServlet.handleReadAction: " +
771
                         e.getMessage());
772
      e.printStackTrace(System.out);
773
    }
774
    
775
  }
776
  
777
  // read metadata or data from Metacat
778
  private void readFromMetacat(HttpServletResponse response, String docid,
779
                               String qformat, String abstrpath, String user,
780
                               String group, boolean zip, ZipOutputStream zout)
781
               throws ClassNotFoundException, IOException, SQLException, 
782
                      McdbException, Exception
783
  {
784
    Connection conn = null;
785
    try {
786
      conn = util.getConnection();
787
      DocumentImpl doc = new DocumentImpl(conn, docid);
788
      
789
      if ( doc.getRootNodeID() == 0 ) {
790
        // this is data file
791
        // ??? look at handleGetData
792
        ServletOutputStream out = response.getOutputStream(); 
793
        String filepath = util.getOption("datafilepath");
794
        if(!filepath.endsWith("/")) {
795
          filepath += "/";
796
        }
797
        String filename = filepath + doc.getDocname();      //MIME type
798
        String contentType = getServletContext().getMimeType(filename);
799
        if (contentType == null) {
800
          if (filename.endsWith(".xml")) {
801
            contentType="text/xml";
802
          } else if (filename.endsWith(".css")) {
803
            contentType="text/css";
804
          } else if (filename.endsWith(".dtd")) {
805
            contentType="text/plain";
806
          } else if (filename.endsWith(".xsd")) {
807
            contentType="text/plain";
808
          } else if (filename.endsWith("/")) {
809
            contentType="text/directory";
810
          } else {
811
            contentType="text/plain";
812
          }
813
        }
814
        response.setContentType(contentType);
815
        FileInputStream fin = null;
816
        try {
817
          fin = new FileInputStream(filename);
818
          byte[] buf = new byte[4 * 1024]; // 4K buffer
819
          int b = fin.read(buf);
820
          while (b != -1) {
821
            out.write(buf, 0, b);
822
            b = fin.read(buf);
823
          }
824
        } finally {
825
          if (fin != null) fin.close();
826
        }
827

    
828
      } else {
829
        // this is metadata doc
830
        if ( qformat.equals("html") ) { 
831
          response.setContentType("text/html");  //MIME type
832
          PrintWriter out = response.getWriter();
833
    
834
          // Look up the document type
835
          String doctype = doc.getDoctype();
836
          // Transform the document to the new doctype
837
          DBTransform dbt = new DBTransform(conn);
838
          dbt.transformXMLDocument(doc.toString(),
839
                                   doctype,"-//W3C//HTML//EN",out);
840
        } else {
841
          // set content type first
842
          response.setContentType("text/xml");   //MIME type
843
          PrintWriter out = response.getWriter();
844
          doc.toXml(out);
845
        }
846
      
847
      }
848
    } finally {
849
      util.returnConnection(conn);
850
    }
851
    
852
  }
853
  
854
  // read data from URLConnection
855
  private void readFromURLConnection(HttpServletResponse response, String docid)
856
               throws IOException, MalformedURLException
857
  {
858
    ServletOutputStream out = response.getOutputStream(); 
859
    String contentType = getServletContext().getMimeType(docid); //MIME type
860
    if (contentType == null) {
861
      if (docid.endsWith(".xml")) {
862
        contentType="text/xml";
863
      } else if (docid.endsWith(".css")) {
864
        contentType="text/css";
865
      } else if (docid.endsWith(".dtd")) {
866
        contentType="text/plain";
867
      } else if (docid.endsWith(".xsd")) {
868
        contentType="text/plain";
869
      } else if (docid.endsWith("/")) {
870
        contentType="text/directory";
871
      } else {
872
        contentType="text/plain";
873
      }
874
    }
875
    response.setContentType(contentType);
876

    
877
    // this is http url
878
    URL url = new URL(docid);
879
    BufferedInputStream bis = null;
880
    try {
881
      bis = new BufferedInputStream(url.openStream());
882
      byte[] buf = new byte[4 * 1024]; // 4K buffer
883
      int b = bis.read(buf);
884
      while (b != -1) {
885
        out.write(buf, 0, b);
886
        b = bis.read(buf);
887
      }
888
    } finally {
889
      if (bis != null) bis.close();
890
    }
891
    
892
  }
893
  
894
  // read file/doc and write to ZipOutputStream
895
  private void addDocToZip(String docid, ZipOutputStream zout)
896
               throws ClassNotFoundException, IOException, SQLException, 
897
                      McdbException, Exception
898
  {
899
    byte[] bytestring = null;
900
    ZipEntry zentry = null;
901

    
902
    try {
903
      URL url = new URL(docid);
904

    
905
      // this http url; read from URLConnection; add to zip
906
      zentry = new ZipEntry(docid);
907
      zout.putNextEntry(zentry);
908
      BufferedInputStream bis = null;
909
      try {
910
        bis = new BufferedInputStream(url.openStream());
911
        byte[] buf = new byte[4 * 1024]; // 4K buffer
912
        int b = bis.read(buf);
913
        while(b != -1) {
914
          zout.write(buf, 0, b);
915
          b = bis.read(buf);
916
        }
917
      } finally {
918
        if (bis != null) bis.close();
919
      }
920
      zout.closeEntry();
921

    
922
    } catch (MalformedURLException mue) {
923
      
924
      // this is metacat doc (data file or metadata doc)
925
      Connection conn = null;
926
      try {
927
        conn = util.getConnection();
928
        DocumentImpl doc = new DocumentImpl(conn, docid);
929
      
930
        if ( doc.getRootNodeID() == 0 ) {
931
          // this is data file; add file to zip
932
          String filepath = util.getOption("datafilepath");
933
          if(!filepath.endsWith("/")) {
934
            filepath += "/";
935
          }
936
          String filename = filepath + doc.getDocname();
937
          zentry = new ZipEntry(filename);
938
          zout.putNextEntry(zentry);
939
          FileInputStream fin = null;
940
          try {
941
            fin = new FileInputStream(filename);
942
            byte[] buf = new byte[4 * 1024]; // 4K buffer
943
            int b = fin.read(buf);
944
            while (b != -1) {
945
              zout.write(buf, 0, b);
946
              b = fin.read(buf);
947
            }
948
          } finally {
949
            if (fin != null) fin.close();
950
          }
951
          zout.closeEntry();
952

    
953
        } else {
954
          // this is metadata doc; add doc to zip
955
          bytestring = doc.toString().getBytes();
956
          zentry = new ZipEntry(docid + ".xml");
957
          zentry.setSize(bytestring.length);
958
          zout.putNextEntry(zentry);
959
          zout.write(bytestring, 0, bytestring.length);
960
          zout.closeEntry();
961
        }
962
      } finally {
963
        util.returnConnection(conn);
964
      }
965
      
966
    }
967
      
968
  }
969
  
970
  // view abstract within document
971
  private void viewAbstract(HttpServletResponse response,
972
                            String abstractpath, String docid)
973
               throws ClassNotFoundException, IOException, SQLException,
974
                      McdbException, Exception
975
  {
976
    Connection conn = null;
977
    try {
978
      conn = util.getConnection();
979
      DocumentImpl doc = new DocumentImpl(conn, docid);
980
    
981
      Object[] abstracts = DBQuery.getNodeContent(abstractpath, docid, conn);
982
    
983
      response.setContentType("text/html");  //MIME type
984
      PrintWriter out = response.getWriter();
985
      out.println("<html><head><title>Abstract</title></head>");
986
      out.println("<body bgcolor=\"white\"><h1>Abstract</h1>");
987
      for (int i=0; i<abstracts.length; i++) {
988
        out.println("<p>" + (String)abstracts[i] + "</p>");
989
      }
990
      out.println("</body></html>");
991

    
992
    } finally {
993
      util.returnConnection(conn);
994
    }
995
  }
996
  // END OF READ SECTION
997
    
998
  // INSERT/UPDATE SECTION
999
  /** 
1000
   * Handle the database putdocument request and write an XML document 
1001
   * to the database connection
1002
   */
1003
  private void handleInsertOrUpdateAction(PrintWriter out, Hashtable params, 
1004
               HttpServletResponse response, String user, String group) {
1005

    
1006
    Connection conn = null;
1007

    
1008
    try {
1009
      // Get the document indicated
1010
      String[] doctext = (String[])params.get("doctext");
1011

    
1012
      String pub = null;
1013
      if (params.containsKey("public")) {
1014
        pub = ((String[])params.get("public"))[0];
1015
      }
1016

    
1017
      StringReader dtd = null;
1018
      if (params.containsKey("dtdtext")) {
1019
        String[] dtdtext = (String[])params.get("dtdtext");
1020
        try {
1021
          if ( !dtdtext[0].equals("") ) {
1022
            dtd = new StringReader(dtdtext[0]);
1023
          }
1024
        } catch (NullPointerException npe) {}
1025
      }
1026
      
1027
      StringReader xml = null;
1028
      boolean validate = false;
1029
      try {
1030
        // look inside XML Document for <!DOCTYPE ... PUBLIC/SYSTEM ... > 
1031
        // in order to decide whether to use validation parser
1032
        validate = validateXML(doctext[0]);
1033
        xml = new StringReader(doctext[0]);
1034

    
1035
        String[] action = (String[])params.get("action");
1036
        String[] docid = (String[])params.get("docid");
1037
        String newdocid = null;
1038

    
1039
        String doAction = null;
1040
        if (action[0].equals("insert")) {
1041
          doAction = "INSERT";
1042
        } else if (action[0].equals("update")) {
1043
          doAction = "UPDATE";
1044
        }
1045

    
1046
        try {
1047
          // get a connection from the pool
1048
          conn = util.getConnection();
1049

    
1050
          // write the document to the database
1051
          try {
1052
            String accNumber = docid[0];
1053
            if (accNumber.equals("")) {
1054
              accNumber = null;
1055
            }
1056
            newdocid = DocumentImpl.write(conn, xml, pub, dtd, doAction,
1057
                                          accNumber, user, group, validate);
1058
          } catch (NullPointerException npe) {
1059
            newdocid = DocumentImpl.write(conn, xml, pub, dtd, doAction,
1060
                                          null, user, group, validate);
1061
          }
1062
        } finally {
1063
          util.returnConnection(conn);
1064
        }    
1065

    
1066
        // set content type and other response header fields first
1067
        response.setContentType("text/xml");
1068
        out.println("<?xml version=\"1.0\"?>");
1069
        out.println("<success>");
1070
        out.println("<docid>" + newdocid + "</docid>"); 
1071
        out.println("</success>");
1072

    
1073
      } catch (NullPointerException npe) {
1074
        response.setContentType("text/xml");
1075
        out.println("<?xml version=\"1.0\"?>");
1076
        out.println("<error>");
1077
        out.println(npe.getMessage()); 
1078
        out.println("</error>");
1079
      }
1080
    } catch (Exception e) {
1081
      response.setContentType("text/xml");
1082
      out.println("<?xml version=\"1.0\"?>");
1083
      out.println("<error>");
1084
      out.println(e.getMessage()); 
1085
      if (e instanceof SAXException) {
1086
        Exception e2 = ((SAXException)e).getException();
1087
        out.println("<error>");
1088
        out.println(e2.getMessage()); 
1089
        out.println("</error>");
1090
      }
1091
      //e.printStackTrace(out);
1092
      out.println("</error>");
1093
    }
1094
  }
1095

    
1096
  /** 
1097
   * Parse XML Document to look for <!DOCTYPE ... PUBLIC/SYSTEM ... > 
1098
   * in order to decide whether to use validation parser
1099
   */
1100
  private static boolean validateXML(String xmltext) throws IOException {
1101
    
1102
    StringReader xmlreader = new StringReader(xmltext);
1103
    StringBuffer cbuff = new StringBuffer();
1104
    java.util.Stack st = new java.util.Stack();
1105
    boolean validate = false;
1106
    int c;
1107
    int inx;
1108
    
1109
    // read from the stream until find the keywords
1110
    while ( (st.empty() || st.size()<4) && ((c = xmlreader.read()) != -1) ) {
1111
      cbuff.append((char)c);
1112

    
1113
      // "<!DOCTYPE" keyword is found; put it in the stack
1114
      if ( (inx = cbuff.toString().indexOf("<!DOCTYPE")) != -1 ) {
1115
        cbuff = new StringBuffer();
1116
        st.push("<!DOCTYPE");
1117
      }
1118
      // "PUBLIC" keyword is found; put it in the stack
1119
      if ( (inx = cbuff.toString().indexOf("PUBLIC")) != -1 ) {
1120
        cbuff = new StringBuffer();
1121
        st.push("PUBLIC");
1122
      }
1123
      // "SYSTEM" keyword is found; put it in the stack
1124
      if ( (inx = cbuff.toString().indexOf("SYSTEM")) != -1 ) {
1125
        cbuff = new StringBuffer();
1126
        st.push("SYSTEM");
1127
      }
1128
      // ">" character is found; put it in the stack
1129
      // ">" is found twice: fisrt from <?xml ...?> 
1130
      // and second from <!DOCTYPE ... >
1131
      if ( (inx = cbuff.toString().indexOf(">")) != -1 ) {
1132
        cbuff = new StringBuffer();
1133
        st.push(">");
1134
      }
1135
    }
1136

    
1137
    // close the stream
1138
    xmlreader.close();
1139

    
1140
    // check the stack whether it contains the keywords:
1141
    // "<!DOCTYPE", "PUBLIC" or "SYSTEM", and ">" in this order
1142
    if ( st.size() == 4 ) {
1143
      if ( ((String)st.pop()).equals(">") &&
1144
           ( ((String)st.peek()).equals("PUBLIC") |
1145
             ((String)st.pop()).equals("SYSTEM") ) &&
1146
           ((String)st.pop()).equals("<!DOCTYPE") )  {
1147
        validate = true;
1148
      }
1149
    }
1150

    
1151
System.out.println("Validation is " + validate);
1152
    return validate;
1153
  }
1154
  // END OF INSERT/UPDATE SECTION
1155

    
1156
  // DELETE SECTION
1157
  /** 
1158
   * Handle the database delete request and delete an XML document 
1159
   * from the database connection
1160
   */
1161
  private void handleDeleteAction(PrintWriter out, Hashtable params, 
1162
               HttpServletResponse response, String user, String group) {
1163

    
1164
    String[] docid = (String[])params.get("docid");
1165
    Connection conn = null;
1166

    
1167
    // delete the document from the database
1168
    try {
1169
      // get a connection from the pool
1170
      conn = util.getConnection();
1171
                                      // NOTE -- NEED TO TEST HERE
1172
                                      // FOR EXISTENCE OF DOCID PARAM
1173
                                      // BEFORE ACCESSING ARRAY
1174
      try { 
1175
        DocumentImpl.delete(conn, docid[0], user, group);
1176
        response.setContentType("text/xml");
1177
        out.println("<?xml version=\"1.0\"?>");
1178
        out.println("<success>");
1179
        out.println("Document deleted."); 
1180
        out.println("</success>");
1181
      } catch (AccessionNumberException ane) {
1182
        response.setContentType("text/xml");
1183
        out.println("<?xml version=\"1.0\"?>");
1184
        out.println("<error>");
1185
        out.println("Error deleting document!!!");
1186
        out.println(ane.getMessage()); 
1187
        out.println("</error>");
1188
      }
1189
    } catch (Exception e) {
1190
      response.setContentType("text/xml");
1191
      out.println("<?xml version=\"1.0\"?>");
1192
      out.println("<error>");
1193
      out.println(e.getMessage()); 
1194
      out.println("</error>");
1195
    } finally {
1196
      util.returnConnection(conn);
1197
    }  
1198
  }
1199
  // END OF DELETE SECTION
1200
  
1201
  // VALIDATE SECTION
1202
  /** 
1203
   * Handle the validation request and return the results to the requestor
1204
   */
1205
  private void handleValidateAction(PrintWriter out, Hashtable params, 
1206
               HttpServletResponse response) {
1207

    
1208
    // Get the document indicated
1209
    String valtext = null;
1210
    
1211
    try {
1212
      valtext = ((String[])params.get("valtext"))[0];
1213
    } catch (Exception nullpe) {
1214

    
1215
      Connection conn = null;
1216
      String docid = null;
1217
      try {
1218
        // Find the document id number
1219
        docid = ((String[])params.get("docid"))[0]; 
1220

    
1221
        // get a connection from the pool
1222
        conn = util.getConnection();
1223

    
1224
        // Get the document indicated from the db
1225
        DocumentImpl xmldoc = new DocumentImpl(conn, docid);
1226
        valtext = xmldoc.toString();
1227

    
1228
      } catch (NullPointerException npe) {
1229
        response.setContentType("text/xml");
1230
        out.println("<error>Error getting document ID: " + docid + "</error>");
1231
        if ( conn != null ) { util.returnConnection(conn); }
1232
        return;
1233
      } catch (Exception e) {
1234
        response.setContentType("text/html");
1235
        out.println(e.getMessage()); 
1236
      } finally {
1237
        util.returnConnection(conn);
1238
      }  
1239
    }
1240

    
1241
    Connection conn = null;
1242
    try {
1243
      // get a connection from the pool
1244
      conn = util.getConnection();
1245
      DBValidate valobj = new DBValidate(saxparser,conn);
1246
      boolean valid = valobj.validateString(valtext);
1247

    
1248
      // set content type and other response header fields first
1249
      response.setContentType("text/xml");
1250
      out.println(valobj.returnErrors());
1251

    
1252
    } catch (NullPointerException npe2) {
1253
      // set content type and other response header fields first
1254
      response.setContentType("text/xml");
1255
      out.println("<error>Error validating document.</error>"); 
1256
    } catch (Exception e) {
1257
      response.setContentType("text/html");
1258
      out.println(e.getMessage()); 
1259
    } finally {
1260
      util.returnConnection(conn);
1261
    }  
1262
  }
1263
  // END OF VALIDATE SECTION
1264
 
1265
  // OTHER ACTION HANDLERS
1266
  /**
1267
   * sends the port number that the data socket is running on.
1268
   * This is a parameter set in the metacat.properties file.
1269
   */
1270
  private void handleGetDataPortAction(PrintWriter out, Hashtable params, 
1271
                                       HttpServletResponse response, 
1272
                                       String username, String groupname,
1273
                                       String sess_id)
1274
  {
1275
    int port;
1276
    String filedir = null;
1277
    try
1278
    {
1279
      filedir = util.getOption("datafilepath");
1280
      
1281
      Random r = new Random();
1282
      port = r.nextInt(65000);  //pick a random port between 0-65000
1283
      //System.out.println("random port is: " + port);
1284
      while(!DataFileServer.portIsAvailable(port))
1285
      {
1286
        port = r.nextInt(65000);
1287
        //System.out.println("next port used: " + port);
1288
      }
1289
      DataFileServer dfs = new DataFileServer(port, username, sess_id);
1290
      dfs.start();
1291
      
1292
      //System.out.println("filedir: " + filedir);
1293
      //System.out.println("port: " + port);
1294
      response.setContentType("text/xml");
1295
      out.println("<?xml version=\"1.0\"?>");
1296
      out.println("<port>");
1297
      out.print(port);
1298
      out.print("</port>");
1299
      
1300
    }
1301
	  catch (Exception e) 
1302
    {
1303
      System.out.println("error in MetacatServlet.handleGetDataPortAction: " + 
1304
                          e.getMessage());
1305
    }
1306
  }
1307
  
1308
  /** 
1309
   * Handle "getaccesscontrol" action.
1310
   * Read Access Control List from db connection in XML format
1311
   */
1312
  private void handleGetAccessControlAction(PrintWriter out, Hashtable params, 
1313
                                       HttpServletResponse response, 
1314
                                       String username, String groupname) {
1315

    
1316
    Connection conn = null;
1317
    String docid = ((String[])params.get("docid"))[0];
1318
    
1319
    try {
1320

    
1321
        // get connection from the pool
1322
        conn = util.getConnection();
1323
        AccessControlList aclobj = new AccessControlList(conn);
1324
        String acltext = aclobj.getACL(docid, username, groupname);
1325
        out.println(acltext);
1326

    
1327
    } catch (Exception e) {
1328
      out.println("<?xml version=\"1.0\"?>");
1329
      out.println("<error>");
1330
      out.println(e.getMessage());
1331
      out.println("</error>");
1332
    } finally {
1333
      util.returnConnection(conn);
1334
    }  
1335
    
1336
  }
1337

    
1338
  /** 
1339
   * Handle the "getprincipals" action.
1340
   * Read all principals from authentication scheme in XML format
1341
   */
1342
  private void handleGetPrincipalsAction(PrintWriter out, String user,
1343
                                         String password) {
1344

    
1345
    Connection conn = null;
1346

    
1347
    try {
1348

    
1349
        // get connection from the pool
1350
        AuthSession auth = new AuthSession();
1351
        String principals = auth.getPrincipals(user, password);
1352
        out.println(principals);
1353

    
1354
    } catch (Exception e) {
1355
      out.println("<?xml version=\"1.0\"?>");
1356
      out.println("<error>");
1357
      out.println(e.getMessage());
1358
      out.println("</error>");
1359
    } finally {
1360
      util.returnConnection(conn);
1361
    }  
1362
    
1363
  }
1364

    
1365
  /** 
1366
   * Handle "getdoctypes" action.
1367
   * Read all doctypes from db connection in XML format
1368
   */
1369
  private void handleGetDoctypesAction(PrintWriter out, Hashtable params, 
1370
                                       HttpServletResponse response) {
1371

    
1372
    Connection conn = null;
1373
    
1374
    try {
1375

    
1376
        // get connection from the pool
1377
        conn = util.getConnection();
1378
        DBUtil dbutil = new DBUtil(conn);
1379
        String doctypes = dbutil.readDoctypes();
1380
        out.println(doctypes);
1381

    
1382
    } catch (Exception e) {
1383
      out.println("<?xml version=\"1.0\"?>");
1384
      out.println("<error>");
1385
      out.println(e.getMessage());
1386
      out.println("</error>");
1387
    } finally {
1388
      util.returnConnection(conn);
1389
    }  
1390
    
1391
  }
1392

    
1393
  /** 
1394
   * Handle the "getdtdschema" action.
1395
   * Read DTD or Schema file for a given doctype from Metacat catalog system
1396
   */
1397
  private void handleGetDTDSchemaAction(PrintWriter out, Hashtable params,
1398
                                        HttpServletResponse response) {
1399

    
1400
    Connection conn = null;
1401
    String doctype = null;
1402
    String[] doctypeArr = (String[])params.get("doctype");
1403

    
1404
    // get only the first doctype specified in the list of doctypes
1405
    // it could be done for all doctypes in that list
1406
    if (doctypeArr != null) {
1407
        doctype = ((String[])params.get("doctype"))[0]; 
1408
    }
1409

    
1410
    try {
1411

    
1412
        // get connection from the pool
1413
        conn = util.getConnection();
1414
        DBUtil dbutil = new DBUtil(conn);
1415
        String dtdschema = dbutil.readDTDSchema(doctype);
1416
        out.println(dtdschema);
1417

    
1418
    } catch (Exception e) {
1419
      out.println("<?xml version=\"1.0\"?>");
1420
      out.println("<error>");
1421
      out.println(e.getMessage());
1422
      out.println("</error>");
1423
    } finally {
1424
      util.returnConnection(conn);
1425
    }  
1426
    
1427
  }
1428

    
1429
  /** 
1430
   * Handle the "getdataguide" action.
1431
   * Read Data Guide for a given doctype from db connection in XML format
1432
   */
1433
  private void handleGetDataGuideAction(PrintWriter out, Hashtable params, 
1434
                                        HttpServletResponse response) {
1435

    
1436
    Connection conn = null;
1437
    String doctype = null;
1438
    String[] doctypeArr = (String[])params.get("doctype");
1439

    
1440
    // get only the first doctype specified in the list of doctypes
1441
    // it could be done for all doctypes in that list
1442
    if (doctypeArr != null) {
1443
        doctype = ((String[])params.get("doctype"))[0]; 
1444
    }
1445

    
1446
    try {
1447

    
1448
        // get connection from the pool
1449
        conn = util.getConnection();
1450
        DBUtil dbutil = new DBUtil(conn);
1451
        String dataguide = dbutil.readDataGuide(doctype);
1452
        out.println(dataguide);
1453

    
1454
    } catch (Exception e) {
1455
      out.println("<?xml version=\"1.0\"?>");
1456
      out.println("<error>");
1457
      out.println(e.getMessage());
1458
      out.println("</error>");
1459
    } finally {
1460
      util.returnConnection(conn);
1461
    }  
1462
    
1463
  }
1464

    
1465
}
(32-32/43)