Project

General

Profile

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