Project

General

Profile

1
/**
2
 *      Name: MetaCatServlet.java
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
7
 *
8
 *   Version: '$Id: MetaCatServlet.java 184 2000-06-21 02:57:19Z jones $'
9
 */
10

    
11
package edu.ucsb.nceas.metacat;
12

    
13
import java.io.PrintWriter;
14
import java.io.IOException;
15
import java.io.Reader;
16
import java.io.StringReader;
17
import java.io.BufferedReader;
18
import java.util.Enumeration;
19
import java.util.Hashtable;
20
import java.util.ResourceBundle;
21
import java.util.PropertyResourceBundle;
22
import java.net.URL;
23
import java.net.MalformedURLException;
24
import java.sql.PreparedStatement;
25
import java.sql.ResultSet;
26
import java.sql.Connection;
27
import java.sql.SQLException;
28

    
29
import javax.servlet.ServletConfig;
30
import javax.servlet.ServletContext;
31
import javax.servlet.ServletException;
32
import javax.servlet.ServletInputStream;
33
import javax.servlet.http.HttpServlet;
34
import javax.servlet.http.HttpServletRequest;
35
import javax.servlet.http.HttpServletResponse;
36
import javax.servlet.http.HttpUtils;
37

    
38
import oracle.xml.parser.v2.XSLStylesheet;
39
import oracle.xml.parser.v2.XSLException;
40
import oracle.xml.parser.v2.XMLDocumentFragment;
41
import oracle.xml.parser.v2.XSLProcessor;
42
import oracle.xml.parser.v2.*;    
43
import java.io.File;
44
import java.io.FileInputStream;
45

    
46
/**
47
 * A metadata catalog server implemented as a Java Servlet
48
 *
49
 * <p>Valid parameters are:<br>
50
 * action=query -- query the values of all elements and attributes
51
 *                     and return a result set of nodes<br>
52
 * action=squery -- structured query (@see pathquery.dtd)
53
 * doctype -- document type list returned by the query (publicID)
54
 * qformat=xml -- display resultset from query in XML<br>
55
 * qformat=html -- display resultset from query in HTML<br>
56
 * action=getdocument -- display an XML document in XML or HTML<br>
57
 * docid=34 -- display the document with the document ID number 34<br>
58
 * action=putdocument -- load an XML document into the database store<br>
59
 * doctext -- XML text ofthe document to load into the database<br>
60
 * query -- actual query text (to go with 'action=query' or 'action=squery')<br>
61
 * action=validate -- vallidate the xml contained in validatetext<br>
62
 * valtext -- XML text to be validated
63
 * action=getdatadoc -- retreive a stored datadocument
64
 * datadoc -- data document name (id)
65
 */
66
public class MetaCatServlet extends HttpServlet {
67

    
68
  private ServletConfig		config = null;
69
  private ServletContext	context = null;
70
  private Connection 		conn = null;
71
  private DBQuery		queryobj = null;
72
  private DBReader		docreader = null;
73
  private DBTransform		dbt = null;
74
  private String 		resultStyleURL = null;
75
  private String 		xmlcatalogfile = null;
76
  private String 		saxparser = null;
77
  private String    		defaultdatapath = null; 
78
					// path to directory where data files 
79
					// that can be downloaded will be stored
80
  private String    		executescript  = null;  
81
					// script to get data file and put it 
82
                                    	// in defaultdocpath dir
83
  private PropertyResourceBundle options = null;
84

    
85
  private MetaCatUtil util = null;
86

    
87
  /**
88
   * Initialize the servlet by creating appropriate database connections
89
   */
90
  public void init( ServletConfig config ) throws ServletException {
91
    try {
92
      super.init( config );
93
      this.config = config;
94
      this.context = config.getServletContext();
95
      System.out.println("MetaCatServlet Initialize");
96

    
97
      util = new MetaCatUtil();
98

    
99
      // Get the configuration file information
100
      resultStyleURL = util.getOption("resultStyleURL");
101
      xmlcatalogfile = util.getOption("xmlcatalogfile");
102
      saxparser = util.getOption("saxparser");
103
      defaultdatapath = util.getOption("defaultdatapath");
104
      executescript = util.getOption("executescript");
105

    
106
      try {
107
        // Open a connection to the database
108
        conn = util.openDBConnection();
109

    
110
        queryobj = new DBQuery(conn,saxparser);
111
        docreader = new DBReader(conn);
112
        dbt = new DBTransform(conn);
113

    
114
      } catch (Exception e) {
115
        System.err.println("Error opening database connection");
116
      }
117
    } catch ( ServletException ex ) {
118
      throw ex;
119
    }
120
  }
121

    
122
  /** Handle "GET" method requests from HTTP clients */
123
  public void doGet (HttpServletRequest request, HttpServletResponse response)
124
    throws ServletException, IOException {
125

    
126
    // Process the data and send back the response
127
    handleGetOrPost(request, response);
128
  }
129

    
130
  /** Handle "POST" method requests from HTTP clients */
131
  public void doPost( HttpServletRequest request, HttpServletResponse response)
132
    throws ServletException, IOException {
133

    
134
    // Process the data and send back the response
135
    handleGetOrPost(request, response);
136
  }
137

    
138
  /**
139
   * Control servlet response depending on the action parameter specified
140
   */
141
  private void handleGetOrPost(HttpServletRequest request, 
142
    HttpServletResponse response) 
143
    throws ServletException, IOException {
144

    
145
    if (conn == null) {
146
      System.err.println("Connection to database lost.  Reopening...");
147
      try {
148
        // Open a connection to the database
149
        conn = util.openDBConnection();
150
  
151
        queryobj = new DBQuery(conn, saxparser);
152
        docreader = new DBReader(conn);
153
        dbt = new DBTransform(conn);
154
  
155
      } catch (Exception e) {
156
        System.err.println("Error opening database connection");
157
      }
158
    }
159

    
160
    // Get a handle to the output stream back to the client
161
    PrintWriter out = response.getWriter();
162
    //response.setContentType("text/html");
163
  
164
    String name = null;
165
    String[] value = null;
166
    String[] docid = new String[3];
167
    Hashtable params = new Hashtable();
168
    Enumeration paramlist = request.getParameterNames();
169
    while (paramlist.hasMoreElements()) {
170
      name = (String)paramlist.nextElement();
171
      value = request.getParameterValues(name);
172

    
173
      // Decode the docid and mouse click information
174
      if (name.endsWith(".y")) {
175
        docid[0] = name.substring(0,name.length()-2);
176
        //out.println("docid => " + docid[0]);
177
        params.put("docid", docid);
178
        name = "ypos";
179
      }
180
      if (name.endsWith(".x")) {
181
        name = "xpos";
182
      }
183

    
184
      //out.println(name + " => " + value[0]);
185
      params.put(name,value);
186
    }
187

    
188
    // Determine what type of request the user made
189
    // if the action parameter is set, use it as a default
190
    // but if the ypos param is set, calculate the action needed
191
    String action = ((String[])params.get("action"))[0];
192
    long ypos = 0;
193
    try {
194
      ypos = (new Long(((String[])params.get("ypos"))[0]).longValue());
195
      //out.println("<P>YPOS IS " + ypos);
196
      if (ypos <= 13) {
197
        action = "getdocument";
198
      } else if (ypos > 13 && ypos <= 27) {
199
        action = "validate";
200
      } else if (ypos > 27) {
201
        action = "transform";
202
      } else {
203
        action = "";
204
      }
205
    } catch (Exception npe) {
206
      //out.println("<P>Caught exception looking for Y value.");
207
    }
208

    
209
    if (action.equals("query") || action.equals("squery")) {
210
      handleQueryAction(out, params, response);
211
    } else if (action.equals("getdocument")) {
212
      try {
213
        handleGetDocumentAction(out, params, response);
214
      } catch (ClassNotFoundException e) {
215
        out.println(e.getMessage());
216
      } catch (SQLException se) {
217
        out.println(se.getMessage());
218
      }
219
    } else if (action.equals("putdocument")) {
220
      handlePutDocumentAction(out, params, response);
221
    } else if (action.equals("validate")) {
222
      handleValidateAction(out, params, response);  
223
    } else if (action.equals("getdatadoc")) {
224
      handleGetDataDocumentAction(out, params, response);  
225
    } else {
226
      out.println("Error: action not registered.  Please report this error.");
227
    }
228

    
229
    // Close the stream to the client
230
    out.close();
231
  }
232

    
233
  /** 
234
   * Handle the database query request and return a result set, possibly
235
   * transformed from XML into HTML
236
   */
237
  private void handleQueryAction(PrintWriter out, Hashtable params, 
238
               HttpServletResponse response) {
239
      String action = ((String[])params.get("action"))[0];
240
      String query = ((String[])params.get("query"))[0]; 
241
      Hashtable doclist = null;
242
      String[] doctypeArr = null;
243
      String doctype = null;
244
      Reader xmlquery = null;
245

    
246
      // Run the query if it is a structured query
247
      // or, if it is a free-text, simple query,
248
      // format it first as a structured query and then run it
249
      if (action.equals("query")) {
250
        doctypeArr = (String[])params.get("doctype");
251
        doctype = null;
252
        if (doctypeArr != null) {
253
          doctype = ((String[])params.get("doctype"))[0]; 
254
        }
255

    
256
        if (doctype != null) {
257
          xmlquery = new StringReader(DBQuery.createQuery(query,doctype));
258
        } else {
259
          xmlquery = new StringReader(DBQuery.createQuery(query));
260
        }
261
      } else if (action.equals("squery")) {
262
        xmlquery = new StringReader(query);
263
      } else {
264
        System.err.println("Error handling query -- illegal action value");
265
      }
266

    
267
      if (queryobj != null) {
268
          doclist = queryobj.findDocuments(xmlquery);
269
      } else {
270
        out.println("Query Object Init failed.");
271
        return;
272
      }
273
 
274
      // Create a buffer to hold the xml result
275
      StringBuffer resultset = new StringBuffer();
276
 
277
      // Print the resulting root nodes
278
      String docid;
279
      String document = null;
280
      resultset.append("<?xml version=\"1.0\"?>\n");
281
      //resultset.append("<!DOCTYPE resultset PUBLIC " +
282
      //               "\"-//NCEAS//resultset//EN\" \"resultset.dtd\">\n");
283
      resultset.append("<resultset>\n");
284
      resultset.append("  <query>" + query + "</query>");
285
      Enumeration doclistkeys = doclist.keys(); 
286
      while (doclistkeys.hasMoreElements()) {
287
        docid = (String)doclistkeys.nextElement();
288
        document = (String)doclist.get(docid);
289
        resultset.append("  <document>" + document + "</document>");
290
      }
291
      resultset.append("</resultset>");
292

    
293
      String qformat = ((String[])params.get("qformat"))[0]; 
294
      if (qformat.equals("xml")) {
295
        // set content type and other response header fields first
296
        response.setContentType("text/xml");
297
        out.println(resultset.toString());
298
      } else if (qformat.equals("html")) {
299
        // set content type and other response header fields first
300
        response.setContentType("text/html");
301
        //out.println("Converting to HTML...");
302
        XMLDocumentFragment htmldoc = null;
303
        try {
304
          XSLStylesheet style = new XSLStylesheet(new URL(resultStyleURL), null);
305
          htmldoc = (new XSLProcessor()).processXSL(style, 
306
                     (Reader)(new StringReader(resultset.toString())),null);
307
          htmldoc.print(out);
308
        } catch (Exception e) {
309
          out.println("Error transforming document:\n" + e.getMessage());
310
        }
311
      }
312
  }
313

    
314
  /** 
315
   * Handle the database getdocument request and return a XML document, 
316
   * possibly transformed from XML into HTML
317
   */
318
  private void handleGetDocumentAction(PrintWriter out, Hashtable params, 
319
               HttpServletResponse response) 
320
               throws ClassNotFoundException, IOException, SQLException {
321
    String docidstr = null;
322
    String docid = null;
323
    String doc = null;
324
    try {
325
      // Find the document id number
326
      docidstr = ((String[])params.get("docid"))[0]; 
327
      //docid = (new Long(docidstr)).longValue();
328
      docid = docidstr;
329

    
330
      // Get the document indicated fromthe db
331
      doc = docreader.readXMLDocument(docid);
332
    } catch (NullPointerException npe) {
333
      response.setContentType("text/html");
334
      out.println("Error getting document ID: " + docidstr +" (" + docid + ")");
335
    }
336

    
337
      // Return the document in XML or HTML format
338
      String qformat = ((String[])params.get("qformat"))[0]; 
339
      if (qformat.equals("xml")) {
340
        // set content type and other response header fields first
341
        response.setContentType("text/xml");
342
        out.println(doc);
343
      } else if (qformat.equals("html")) {
344
        // set content type and other response header fields first
345
        response.setContentType("text/html");
346

    
347
        // Look up the document type
348
        String sourcetype = docreader.getDoctypeInfo(docid).getDoctype();
349

    
350
        // Transform the document to the new doctype
351
        dbt.transformXMLDocument(doc, sourcetype, "-//W3C//HTML//EN", out);
352
      }
353
  }
354

    
355
  /** 
356
   * Handle the database putdocument request and write an XML document 
357
   * to the database connection
358
   */
359
  private void handlePutDocumentAction(PrintWriter out, Hashtable params, 
360
               HttpServletResponse response) {
361

    
362
      // Get the document indicated
363
      String[] doctext = (String[])params.get("doctext");
364
      StringReader xml = new StringReader(doctext[0]);
365

    
366
      // write the document to the database
367
      try {
368
        DBWriter dbw = new DBWriter(xml, conn);
369
      } catch (SQLException e1) {
370
          out.println("Error 1 loading document:<p>\n" + e1.getMessage());
371
      }catch (IOException e2) {
372
          out.println("Error 2 loading document:<p>\n" + e2.getMessage());
373
      }catch (ClassNotFoundException e3) {
374
          out.println("Error 3 loading document:<p>\n" + e3.getMessage());
375
      }
376

    
377
      // set content type and other response header fields first
378
      response.setContentType("text/xml");
379
  
380
      out.println(doctext[0]);
381
  }
382
  
383
  /** 
384
   * Handle the validtion request and return the results 
385
   * to the requestor
386
   */
387
  private void handleValidateAction(PrintWriter out, Hashtable params, HttpServletResponse response) {
388

    
389
    // Get the document indicated
390
    String valtext = null;
391
    try {
392
      valtext = ((String[])params.get("valtext"))[0];
393
    } catch (Exception nullpe) {
394

    
395
      String docidstr = null;
396
      String docid = null;
397
      try {
398
        // Find the document id number
399
        docidstr = ((String[])params.get("docid"))[0]; 
400
        //docid = (new Long(docidstr)).longValue();
401
        docid = docidstr;
402
  
403
        // Get the document indicated fromthe db
404
        valtext = docreader.readXMLDocument(docid);
405
      } catch (NullPointerException npe) {
406
        response.setContentType("text/html");
407
        out.println("Error getting document ID: " + 
408
                     docidstr +" (" + docid + ")");
409
      }
410
    }
411

    
412
    SAXParser parser = new SAXParser();  // works for both Xerces and Oracle
413
    parser.setValidationMode(true);      // Oracle
414
    try {
415
      GenericXMLValidate gxv = new GenericXMLValidate(parser, xmlcatalogfile);
416
      boolean valid = gxv.validateString(valtext);
417

    
418
      // set content type and other response header fields first
419
      response.setContentType("text/html");
420
      out.println("<html>");
421
      out.println("<head><link rel=\"stylesheet\" type=\"text/css\" " +
422
                  "href=\"/xmltodb/rowcol.css\" /></head>");
423
      out.println("<body class=\"emlbody\">");
424
  
425
      if (valid) {
426
        out.println("The input XML is VALID!");
427
      } else {
428
        out.println("The input XML is NOT VALID<br />\n<pre>\n" 
429
                    + gxv.returnErrors() + "\n</pre>\n");
430
        //response.setContentType("text/xml");
431
        //out.println(valtext);
432
      } 
433
      out.println("</body></html>");
434
    } catch (NullPointerException npe2) {
435
      // set content type and other response header fields first
436
      response.setContentType("text/html");
437
      //out.println(valtext); 
438
      out.println("Error validating document."); 
439
    }
440
  }
441

    
442
  /** 
443
   * Look up the document type from the database
444
   *
445
   * @param docid the id of the document to look up
446
   */
447
  private String OldgetDoctype(long docid) {
448
    PreparedStatement pstmt;
449
    String doctype = null;
450
 
451
    try {
452
      pstmt =
453
        conn.prepareStatement("SELECT doctype " + 
454
                                "FROM xml_documents " +
455
                               "WHERE docid = ?");
456
      // Bind the values to the query
457
      pstmt.setLong(1, new Long(docid).longValue());
458

    
459
      pstmt.execute();
460
      try {
461
        ResultSet rs = pstmt.getResultSet();
462
        try {
463
          boolean tableHasRows = rs.next();
464
          if (tableHasRows) {
465
            try {
466
              doctype  = rs.getString(1);
467
            } catch (SQLException e) {
468
              System.out.println("Error with getString: " + e.getMessage());
469
            }
470
          }
471
        } catch (SQLException e) {
472
          System.out.println("Error with next: " + e.getMessage());
473
        }
474
      } catch (SQLException e) {
475
        System.out.println("Error with getrset: " + e.getMessage());
476
      }
477
      pstmt.close();
478
    } catch (SQLException e) {
479
      System.out.println("Error getting id: " + e.getMessage());
480
    }
481

    
482
    return doctype;
483
  }
484
    
485
    
486
  /** 
487
   * Handle the document request and return the results 
488
   * to the requestor
489
   */
490
  private void handleGetDataDocumentAction(PrintWriter out, Hashtable params, HttpServletResponse response) {
491
      boolean error_flag = false;
492
      String error_message = "";
493
      // Get the document indicated
494
      String[] datadoc = (String[])params.get("datadoc");
495
  //    defaultdatapath = "C:\\Temp\\";    // for testing only!!!
496
   //   executescript = "test.bat";        // for testing only!!!
497
      
498
      // set content type and other response header fields first
499
      response.setContentType("application/octet-stream");
500
   if (defaultdatapath!=null) {
501
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) defaultdatapath=defaultdatapath+System.getProperty("file.separator");
502
      System.out.println("Path= "+defaultdatapath+datadoc[0]);
503
      if (executescript!=null) {
504
        String command = null;
505
        File scriptfile = new File(executescript);
506
        if (scriptfile.exists()) {
507
            command=executescript+" "+datadoc[0]; }  // execute script includes path
508
        else {     // look in defaultdatapath
509
                command = defaultdatapath+executescript+" "+datadoc[0];  // on Win98 one MUST include the .bat extender
510
        }
511
      System.out.println(command);
512
      try {
513
      Process proc = Runtime.getRuntime().exec(command);
514
      proc.waitFor();
515
      }
516
      catch (Exception eee) {
517
        System.out.println("Error running process!");
518
        error_flag = true;
519
        error_message = "Error running process!";}
520
      } // end executescript not null if
521
      File datafile = new File(defaultdatapath+datadoc[0]);
522
      try {
523
      FileInputStream fw = new FileInputStream(datafile);
524
      int x;
525
     while ((x = fw.read())!=-1) {
526
        out.write(x); }
527
      fw.close();
528
      
529
      }
530
      catch (Exception e) {
531
        System.out.println("Error in returning file\n"+e.getMessage());
532
        error_flag=true;
533
        error_message = error_message+"\nError in returning file\n"+e.getMessage();}
534
   } // end defaultdatapath not null if
535
  }
536
    
537
    
538
}
(16-16/20)