Project

General

Profile

1 51 jones
/**
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 91 higgins
 *     Authors: Matt Jones, Dan Higgins
7 51 jones
 *
8
 *     Version: '$Id$'
9
 */
10
11
package edu.ucsb.nceas.metacat;
12
13 46 jones
import java.io.PrintWriter;
14
import java.io.IOException;
15 50 jones
import java.io.Reader;
16
import java.io.StringReader;
17 59 jones
import java.io.BufferedReader;
18 46 jones
import java.util.Enumeration;
19
import java.util.Hashtable;
20 82 jones
import java.util.ResourceBundle;
21
import java.util.PropertyResourceBundle;
22 50 jones
import java.net.URL;
23
import java.net.MalformedURLException;
24 85 jones
import java.sql.PreparedStatement;
25
import java.sql.ResultSet;
26 50 jones
import java.sql.Connection;
27 55 jones
import java.sql.SQLException;
28 46 jones
29
import javax.servlet.ServletConfig;
30
import javax.servlet.ServletContext;
31
import javax.servlet.ServletException;
32 48 jones
import javax.servlet.ServletInputStream;
33 46 jones
import javax.servlet.http.HttpServlet;
34
import javax.servlet.http.HttpServletRequest;
35
import javax.servlet.http.HttpServletResponse;
36 47 jones
import javax.servlet.http.HttpUtils;
37 46 jones
38 50 jones
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 68 higgins
import oracle.xml.parser.v2.*;    //Oracle parser - DFH
43 91 higgins
import java.io.File;  //DFH
44
import java.io.FileInputStream; //DFH
45 50 jones
46 46 jones
/**
47
 * A metadata catalog server implemented as a Java Servlet
48 50 jones
   *
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=getdocument -- display an XML document in XML or HTML<br>
53
   * qformat=xml -- display resultset from query in XML<br>
54
   * qformat=html -- display resultset from query in HTML<br>
55
   * action=getdocument -- display an XML document in XML or HTML<br>
56
   * docid=34 -- display the document with the document ID number 34<br>
57 60 jones
   * action=putdocument -- load an XML document into the database store<br>
58
   * doctext -- XML text ofthe document to load into the database<br>
59 68 higgins
   * query -- actual query text (to go with 'action=query')<br>
60
   * action=validate -- vallidate the xml contained in validatetext<br>
61
   * valtext -- XML text to be validated
62 91 higgins
   * action=getdatadoc -- retreive a stored datadocument  //DFH
63
   * datadoc -- data document name (id)                   //DFH
64 46 jones
 */
65
public class MetaCatServlet extends HttpServlet {
66
67
  private ServletConfig		config = null;
68
  private ServletContext	context = null;
69 55 jones
  Connection 		conn = null;
70 46 jones
  DBSimpleQuery		queryobj = null;
71 49 jones
  DBReader		docreader = null;
72 87 jones
  DBTransform		dbt = null;
73 82 jones
  String 	user = null;
74
  String 	password = null;
75
  String 	defaultDB = null;
76
  String 	resultStyleURL = null;
77 83 jones
  String 	xmlcatalogfile = null;
78 91 higgins
  String    defaultdatapath = null;  // path to directory where data files that can be downloaded will be stored
79
  String    executescript  = null;  // script to get data file and put it in defaultdocpath dir
80 82 jones
  PropertyResourceBundle options = null;
81 46 jones
82 50 jones
  /**
83
   * Initialize the servlet by creating appropriate database connections
84
   */
85 46 jones
  public void init( ServletConfig config ) throws ServletException {
86
    try {
87
      super.init( config );
88
      this.config = config;
89
      this.context = config.getServletContext();
90 82 jones
      System.out.println("Servlet Initialize");
91
92 83 jones
      // Get the configuration file information
93 82 jones
      options = (PropertyResourceBundle)PropertyResourceBundle.getBundle("edu.ucsb.nceas.metacat.metacat");
94
      user = (String)options.handleGetObject("user");
95
      password = (String)options.handleGetObject("password");
96
      defaultDB = (String)options.handleGetObject("defaultDB");
97
      resultStyleURL = (String)options.handleGetObject("resultStyleURL");
98 83 jones
      xmlcatalogfile = (String)options.handleGetObject("xmlcatalogfile");
99 91 higgins
      defaultdatapath = (String)options.handleGetObject("defaultdatapath");
100
      executescript = (String)options.handleGetObject("executescript");
101 82 jones
102 46 jones
      try {
103 50 jones
        // Open a connection to the database
104 55 jones
        conn = MetaCatUtil.openDBConnection(
105 50 jones
                "oracle.jdbc.driver.OracleDriver",
106
                defaultDB, user, password);
107
108 55 jones
        queryobj = new DBSimpleQuery(conn);
109
        docreader = new DBReader(conn);
110 87 jones
        dbt = new DBTransform(conn);
111 68 higgins
112 46 jones
      } catch (Exception e) {
113 100 jones
        System.err.println("Error opening database connection");
114 46 jones
      }
115
    } catch ( ServletException ex ) {
116
      throw ex;
117
    }
118
  }
119
120 50 jones
  /** Handle "GET" method requests from HTTP clients */
121 46 jones
  public void doGet (HttpServletRequest request, HttpServletResponse response)
122
    throws ServletException, IOException {
123
124 48 jones
    // Process the data and send back the response
125 59 jones
    handleGetOrPost(request, response);
126 48 jones
  }
127
128 50 jones
  /** Handle "POST" method requests from HTTP clients */
129 48 jones
  public void doPost( HttpServletRequest request, HttpServletResponse response)
130
    throws ServletException, IOException {
131
132
    // Process the data and send back the response
133 59 jones
    handleGetOrPost(request, response);
134 48 jones
  }
135
136 49 jones
  /**
137 50 jones
   * Control servlet response depending on the action parameter specified
138 49 jones
   */
139 59 jones
  private void handleGetOrPost(HttpServletRequest request,
140
    HttpServletResponse response)
141 48 jones
    throws ServletException, IOException {
142
143 100 jones
    if (conn == null) {
144
      System.err.println("Connection to database lost.  Reopening...");
145
      try {
146
        // Open a connection to the database
147
        conn = MetaCatUtil.openDBConnection(
148
                "oracle.jdbc.driver.OracleDriver",
149
                defaultDB, user, password);
150
151
        queryobj = new DBSimpleQuery(conn);
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 49 jones
    // Get a handle to the output stream back to the client
161 48 jones
    PrintWriter out = response.getWriter();
162 102 jones
    //response.setContentType("text/html");
163 49 jones
164 59 jones
    String name = null;
165
    String[] value = null;
166 103 jones
    String[] docid = new String[3];
167 59 jones
    Hashtable params = new Hashtable();
168
    Enumeration paramlist = request.getParameterNames();
169
    while (paramlist.hasMoreElements()) {
170
      name = (String)paramlist.nextElement();
171
      value = request.getParameterValues(name);
172 103 jones
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 102 jones
      //out.println(name + " => " + value[0]);
185 59 jones
      params.put(name,value);
186
    }
187
188 103 jones
    // 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 49 jones
    String action = ((String[])params.get("action"))[0];
192 103 jones
    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 46 jones
209 49 jones
    if (action.equals("query")) {
210
      handleQueryAction(out, params, response);
211
    } else if (action.equals("getdocument")) {
212 87 jones
      try {
213
        handleGetDocumentAction(out, params, response);
214
      } catch (ClassNotFoundException e) {
215 103 jones
        out.println(e.getMessage());
216 87 jones
      } catch (SQLException se) {
217 103 jones
        out.println(se.getMessage());
218 87 jones
      }
219 55 jones
    } else if (action.equals("putdocument")) {
220
      handlePutDocumentAction(out, params, response);
221 68 higgins
    } else if (action.equals("validate")) {
222
      handleValidateAction(out, params, response);
223 91 higgins
    } else if (action.equals("getdatadoc")) {
224
      handleGetDataDocumentAction(out, params, response);
225 50 jones
    } else {
226
      out.println("Error: action not registered.  Please report this error.");
227 46 jones
    }
228
229 49 jones
    // Close the stream to the client
230 46 jones
    out.close();
231
  }
232 49 jones
233 50 jones
  /**
234
   * Handle the database query request and return a result set, possibly
235
   * transformed from XML into HTML
236
   */
237 49 jones
  private void handleQueryAction(PrintWriter out, Hashtable params,
238
               HttpServletResponse response) {
239
      // Run the query
240 82 jones
      Hashtable nodelist = null;
241 49 jones
      String query = ((String[])params.get("query"))[0];
242 82 jones
      if (queryobj != null) {
243 86 jones
        nodelist = queryobj.findDocuments(query);
244 82 jones
      } else {
245
        out.println("Query Object Init failed.");
246 83 jones
	/*
247 82 jones
        out.println(user);
248
        out.println(defaultDB);
249 83 jones
        out.println(xmlcatalogfile);
250
        */
251
        return;
252 82 jones
      }
253 50 jones
254
      // Create a buffer to hold the xml result
255
      StringBuffer resultset = new StringBuffer();
256
257 49 jones
      // Print the resulting root nodes
258 98 jones
      Long nodeid;
259
      String document = null;
260 50 jones
      resultset.append("<?xml version=\"1.0\"?>\n");
261 87 jones
      //resultset.append("<!DOCTYPE resultset PUBLIC " +
262
      //               "\"-//NCEAS//resultset//EN\" \"resultset.dtd\">\n");
263 50 jones
      resultset.append("<resultset>\n");
264
      resultset.append("  <query>" + query + "</query>");
265 49 jones
      Enumeration rootlist = nodelist.keys();
266
      while (rootlist.hasMoreElements()) {
267 98 jones
        nodeid = (Long)rootlist.nextElement();
268
        document = (String)nodelist.get(nodeid);
269
        resultset.append("  <document>" + document + "</document>");
270 49 jones
      }
271 50 jones
      resultset.append("</resultset>");
272
273
      String qformat = ((String[])params.get("qformat"))[0];
274
      if (qformat.equals("xml")) {
275
        // set content type and other response header fields first
276
        response.setContentType("text/xml");
277
        out.println(resultset.toString());
278
      } else if (qformat.equals("html")) {
279
        // set content type and other response header fields first
280
        response.setContentType("text/html");
281
        //out.println("Converting to HTML...");
282
        XMLDocumentFragment htmldoc = null;
283
        try {
284
          XSLStylesheet style = new XSLStylesheet(new URL(resultStyleURL), null);
285
          htmldoc = (new XSLProcessor()).processXSL(style,
286
                     (Reader)(new StringReader(resultset.toString())),null);
287
          htmldoc.print(out);
288
        } catch (Exception e) {
289
          out.println("Error transforming document:\n" + e.getMessage());
290
        }
291
      }
292 49 jones
  }
293
294 50 jones
  /**
295
   * Handle the database getdocument request and return a XML document,
296
   * possibly transformed from XML into HTML
297
   */
298 49 jones
  private void handleGetDocumentAction(PrintWriter out, Hashtable params,
299 87 jones
               HttpServletResponse response)
300
               throws ClassNotFoundException, IOException, SQLException {
301 102 jones
    String docidstr = null;
302
    long docid = 0;
303
    String doc = null;
304
    try {
305 87 jones
      // Find the document id number
306 102 jones
      docidstr = ((String[])params.get("docid"))[0];
307
      docid = (new Long(docidstr)).longValue();
308 49 jones
309 87 jones
      // Get the document indicated fromthe db
310 102 jones
      doc = docreader.readXMLDocument(docid);
311
    } catch (NullPointerException npe) {
312
      response.setContentType("text/html");
313
      out.println("Error getting document ID: " + docidstr +" (" + docid + ")");
314
    }
315 85 jones
316 87 jones
      // Return the document in XML or HTML format
317 85 jones
      String qformat = ((String[])params.get("qformat"))[0];
318
      if (qformat.equals("xml")) {
319
        // set content type and other response header fields first
320
        response.setContentType("text/xml");
321
        out.println(doc);
322
      } else if (qformat.equals("html")) {
323
        // set content type and other response header fields first
324
        response.setContentType("text/html");
325
326 87 jones
        // Look up the document type
327 103 jones
        String sourcetype = docreader.getDoctypeInfo(docid).getDoctype();
328 86 jones
329 87 jones
        // Transform the document to the new doctype
330
        dbt.transformXMLDocument(doc, sourcetype, "-//W3C//HTML//EN", out);
331 85 jones
      }
332 49 jones
  }
333 55 jones
334
  /**
335
   * Handle the database putdocument request and write an XML document
336
   * to the database connection
337
   */
338
  private void handlePutDocumentAction(PrintWriter out, Hashtable params,
339
               HttpServletResponse response) {
340 59 jones
341 55 jones
      // Get the document indicated
342 59 jones
      String[] doctext = (String[])params.get("doctext");
343
      StringReader xml = new StringReader(doctext[0]);
344
345
      // write the document to the database
346 55 jones
      try {
347 59 jones
        DBSAXWriter dbw = new DBSAXWriter(xml, conn);
348 55 jones
      } catch (SQLException e1) {
349 59 jones
          out.println("Error 1 loading document:<p>\n" + e1.getMessage());
350 55 jones
      }catch (IOException e2) {
351 59 jones
          out.println("Error 2 loading document:<p>\n" + e2.getMessage());
352 55 jones
      }catch (ClassNotFoundException e3) {
353 59 jones
          out.println("Error 3 loading document:<p>\n" + e3.getMessage());
354 55 jones
      }
355
356
      // set content type and other response header fields first
357 59 jones
      response.setContentType("text/xml");
358 55 jones
359 59 jones
      out.println(doctext[0]);
360 55 jones
  }
361 68 higgins
362
  /**
363
   * Handle the validtion request and return the results
364
   * to the requestor - DFH
365
   */
366
  private void handleValidateAction(PrintWriter out, Hashtable params, HttpServletResponse response) {
367
368 103 jones
    // Get the document indicated
369
    String valtext = null;
370
    try {
371
      valtext = ((String[])params.get("valtext"))[0];
372
    } catch (Exception nullpe) {
373 68 higgins
374 103 jones
      String docidstr = null;
375
      long docid = 0;
376
      try {
377
        // Find the document id number
378
        docidstr = ((String[])params.get("docid"))[0];
379
        docid = (new Long(docidstr)).longValue();
380
381
        // Get the document indicated fromthe db
382
        valtext = docreader.readXMLDocument(docid);
383
      } catch (NullPointerException npe) {
384
        response.setContentType("text/html");
385
        out.println("Error getting document ID: " +
386
                     docidstr +" (" + docid + ")");
387
      }
388
    }
389 68 higgins
390 103 jones
    SAXParser parser = new SAXParser();  // works for both Xerces and Oracle
391
    parser.setValidationMode(true);      // Oracle
392
    try {
393 83 jones
      GenericXMLValidate gxv = new GenericXMLValidate(parser, xmlcatalogfile);
394 103 jones
      boolean valid = gxv.validateString(valtext);
395 68 higgins
396
      // set content type and other response header fields first
397 105 jones
      response.setContentType("text/html");
398
      out.println("<html>");
399
      out.println("<head><link rel=\"stylesheet\" type=\"text/css\" " +
400
                  "href=\"/xmltodb/rowcol.css\" /></head>");
401
      out.println("<body class=\"emlbody\">");
402 68 higgins
403
      if (valid) {
404
        out.println("The input XML is VALID!");
405 103 jones
      } else {
406 105 jones
        out.println("The input XML is NOT VALID<br />\n<pre>\n"
407
                    + gxv.returnErrors() + "\n</pre>\n");
408 103 jones
        //response.setContentType("text/xml");
409
        //out.println(valtext);
410 68 higgins
      }
411 105 jones
      out.println("</body></html>");
412 103 jones
    } catch (NullPointerException npe2) {
413
      // set content type and other response header fields first
414
      response.setContentType("text/html");
415
      //out.println(valtext);
416
      out.println("Error validating document.");
417 68 higgins
    }
418 103 jones
  }
419 87 jones
420
  /**
421
   * Look up the document type from the database
422
   *
423 103 jones
   * @param docid the id of the document to look up
424 87 jones
   */
425 103 jones
  private String OldgetDoctype(long docid) {
426 87 jones
    PreparedStatement pstmt;
427
    String doctype = null;
428
429
    try {
430
      pstmt =
431
        conn.prepareStatement("SELECT doctype " +
432
                                "FROM xml_documents " +
433
                               "WHERE docid = ?");
434
      // Bind the values to the query
435
      pstmt.setLong(1, new Long(docid).longValue());
436
437
      pstmt.execute();
438
      try {
439
        ResultSet rs = pstmt.getResultSet();
440
        try {
441
          boolean tableHasRows = rs.next();
442
          if (tableHasRows) {
443
            try {
444
              doctype  = rs.getString(1);
445
            } catch (SQLException e) {
446
              System.out.println("Error with getString: " + e.getMessage());
447
            }
448
          }
449
        } catch (SQLException e) {
450
          System.out.println("Error with next: " + e.getMessage());
451
        }
452
      } catch (SQLException e) {
453
        System.out.println("Error with getrset: " + e.getMessage());
454
      }
455
      pstmt.close();
456
    } catch (SQLException e) {
457
      System.out.println("Error getting id: " + e.getMessage());
458
    }
459
460
    return doctype;
461
  }
462 91 higgins
463
464
  /**
465
   * Handle the document request and return the results
466
   * to the requestor - DFH
467
   */
468
  private void handleGetDataDocumentAction(PrintWriter out, Hashtable params, HttpServletResponse response) {
469
      boolean error_flag = false;
470
      String error_message = "";
471
      // Get the document indicated
472
      String[] datadoc = (String[])params.get("datadoc");
473
  //    defaultdatapath = "C:\\Temp\\";    // for testing only!!!
474
   //   executescript = "test.bat";        // for testing only!!!
475
476
      // set content type and other response header fields first
477
      response.setContentType("application/octet-stream");
478
   if (defaultdatapath!=null) {
479
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) defaultdatapath=defaultdatapath+System.getProperty("file.separator");
480
      System.out.println("Path= "+defaultdatapath+datadoc[0]);
481
      if (executescript!=null) {
482
        String command = null;
483
        File scriptfile = new File(executescript);
484
        if (scriptfile.exists()) {
485
            command=executescript+" "+datadoc[0]; }  // execute script includes path
486
        else {     // look in defaultdatapath
487
                command = defaultdatapath+executescript+" "+datadoc[0];  // on Win98 one MUST include the .bat extender
488
        }
489
      System.out.println(command);
490
      try {
491
      Process proc = Runtime.getRuntime().exec(command);
492
      proc.waitFor();
493
      }
494
      catch (Exception eee) {
495
        System.out.println("Error running process!");
496
        error_flag = true;
497
        error_message = "Error running process!";}
498
      } // end executescript not null if
499
      File datafile = new File(defaultdatapath+datadoc[0]);
500
      try {
501
      FileInputStream fw = new FileInputStream(datafile);
502
      int x;
503
     while ((x = fw.read())!=-1) {
504
        out.write(x); }
505
      fw.close();
506
507
      }
508
      catch (Exception e) {
509
        System.out.println("Error in returning file\n"+e.getMessage());
510
        error_flag=true;
511
        error_message = error_message+"\nError in returning file\n"+e.getMessage();}
512
   } // end defaultdatapath not null if
513
  }
514
515
516 46 jones
}