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 102 2000-05-15 07:19:57Z 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.*;    //Oracle parser - DFH
43
import java.io.File;  //DFH
44
import java.io.FileInputStream; //DFH
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=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
   * action=putdocument -- load an XML document into the database store<br>
58
   * doctext -- XML text ofthe document to load into the database<br>
59
   * 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
   * action=getdatadoc -- retreive a stored datadocument  //DFH
63
   * datadoc -- data document name (id)                   //DFH
64
 */
65
public class MetaCatServlet extends HttpServlet {
66

    
67
  private ServletConfig		config = null;
68
  private ServletContext	context = null;
69
  Connection 		conn = null;
70
  DBSimpleQuery		queryobj = null;
71
  DBReader		docreader = null;
72
  DBTransform		dbt = null;
73
  String 	user = null;
74
  String 	password = null;
75
  String 	defaultDB = null;
76
  String 	resultStyleURL = null;
77
  String 	xmlcatalogfile = null;
78
  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
  PropertyResourceBundle options = null;
81

    
82
  /**
83
   * Initialize the servlet by creating appropriate database connections
84
   */
85
  public void init( ServletConfig config ) throws ServletException {
86
    try {
87
      super.init( config );
88
      this.config = config;
89
      this.context = config.getServletContext();
90
      System.out.println("Servlet Initialize");
91

    
92
      // Get the configuration file information
93
      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
      xmlcatalogfile = (String)options.handleGetObject("xmlcatalogfile");
99
      defaultdatapath = (String)options.handleGetObject("defaultdatapath");
100
      executescript = (String)options.handleGetObject("executescript");
101

    
102
      try {
103
        // Open a connection to the database
104
        conn = MetaCatUtil.openDBConnection(
105
                "oracle.jdbc.driver.OracleDriver",
106
                defaultDB, user, password);
107

    
108
        queryobj = new DBSimpleQuery(conn);
109
        docreader = new DBReader(conn);
110
        dbt = new DBTransform(conn);
111

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

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

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

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

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

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

    
143
    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
    // 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
    Hashtable params = new Hashtable();
167
    Enumeration paramlist = request.getParameterNames();
168
    while (paramlist.hasMoreElements()) {
169
      name = (String)paramlist.nextElement();
170
      value = request.getParameterValues(name);
171
      //out.println(name + " => " + value[0]);
172
      params.put(name,value);
173
    }
174

    
175
    String action = ((String[])params.get("action"))[0];
176

    
177
    if (action.equals("query")) {
178
      handleQueryAction(out, params, response);
179
    } else if (action.equals("getdocument")) {
180
      try {
181
        handleGetDocumentAction(out, params, response);
182
      } catch (ClassNotFoundException e) {
183
        System.out.println(e.getMessage());
184
      } catch (SQLException se) {
185
        System.out.println(se.getMessage());
186
      }
187
    } else if (action.equals("putdocument")) {
188
      handlePutDocumentAction(out, params, response);
189
    } else if (action.equals("validate")) {
190
      handleValidateAction(out, params, response);  
191
    } else if (action.equals("getdatadoc")) {
192
      handleGetDataDocumentAction(out, params, response);  
193
    } else {
194
      out.println("Error: action not registered.  Please report this error.");
195
    }
196

    
197
    // Close the stream to the client
198
    out.close();
199
  }
200

    
201
  /** 
202
   * Handle the database query request and return a result set, possibly
203
   * transformed from XML into HTML
204
   */
205
  private void handleQueryAction(PrintWriter out, Hashtable params, 
206
               HttpServletResponse response) {
207
      // Run the query
208
      Hashtable nodelist = null;
209
      String query = ((String[])params.get("query"))[0]; 
210
      if (queryobj != null) {
211
        nodelist = queryobj.findDocuments(query);
212
      } else {
213
        out.println("Query Object Init failed.");
214
	/*
215
        out.println(user);
216
        out.println(defaultDB);
217
        out.println(xmlcatalogfile);
218
        */
219
        return;
220
      }
221
 
222
      // Create a buffer to hold the xml result
223
      StringBuffer resultset = new StringBuffer();
224
 
225
      // Print the resulting root nodes
226
      Long nodeid;
227
      String document = null;
228
      resultset.append("<?xml version=\"1.0\"?>\n");
229
      //resultset.append("<!DOCTYPE resultset PUBLIC " +
230
      //               "\"-//NCEAS//resultset//EN\" \"resultset.dtd\">\n");
231
      resultset.append("<resultset>\n");
232
      resultset.append("  <query>" + query + "</query>");
233
      Enumeration rootlist = nodelist.keys(); 
234
      while (rootlist.hasMoreElements()) {
235
        nodeid = (Long)rootlist.nextElement();
236
        document = (String)nodelist.get(nodeid);
237
        resultset.append("  <document>" + document + "</document>");
238
      }
239
      resultset.append("</resultset>");
240

    
241
      String qformat = ((String[])params.get("qformat"))[0]; 
242
      if (qformat.equals("xml")) {
243
        // set content type and other response header fields first
244
        response.setContentType("text/xml");
245
        out.println(resultset.toString());
246
      } else if (qformat.equals("html")) {
247
        // set content type and other response header fields first
248
        response.setContentType("text/html");
249
        //out.println("Converting to HTML...");
250
        XMLDocumentFragment htmldoc = null;
251
        try {
252
          XSLStylesheet style = new XSLStylesheet(new URL(resultStyleURL), null);
253
          htmldoc = (new XSLProcessor()).processXSL(style, 
254
                     (Reader)(new StringReader(resultset.toString())),null);
255
          htmldoc.print(out);
256
        } catch (Exception e) {
257
          out.println("Error transforming document:\n" + e.getMessage());
258
        }
259
      }
260
  }
261

    
262
  /** 
263
   * Handle the database getdocument request and return a XML document, 
264
   * possibly transformed from XML into HTML
265
   */
266
  private void handleGetDocumentAction(PrintWriter out, Hashtable params, 
267
               HttpServletResponse response) 
268
               throws ClassNotFoundException, IOException, SQLException {
269
    String docidstr = null;
270
    long docid = 0;
271
    String doc = null;
272
    try {
273
      // Find the document id number
274
      docidstr = ((String[])params.get("docid"))[0]; 
275
      docid = (new Long(docidstr)).longValue();
276

    
277
      // Get the document indicated fromthe db
278
      doc = docreader.readXMLDocument(docid);
279
    } catch (NullPointerException npe) {
280
      response.setContentType("text/html");
281
      out.println("Error getting document ID: " + docidstr +" (" + docid + ")");
282
    }
283

    
284
      // Return the document in XML or HTML format
285
      String qformat = ((String[])params.get("qformat"))[0]; 
286
      if (qformat.equals("xml")) {
287
        // set content type and other response header fields first
288
        response.setContentType("text/xml");
289
        out.println(doc);
290
      } else if (qformat.equals("html")) {
291
        // set content type and other response header fields first
292
        response.setContentType("text/html");
293

    
294
        // Look up the document type
295
        String sourcetype = getDoctype(docid);
296

    
297
        // Transform the document to the new doctype
298
        dbt.transformXMLDocument(doc, sourcetype, "-//W3C//HTML//EN", out);
299
      }
300
  }
301

    
302
  /** 
303
   * Handle the database putdocument request and write an XML document 
304
   * to the database connection
305
   */
306
  private void handlePutDocumentAction(PrintWriter out, Hashtable params, 
307
               HttpServletResponse response) {
308

    
309
      // Get the document indicated
310
      String[] doctext = (String[])params.get("doctext");
311
      StringReader xml = new StringReader(doctext[0]);
312

    
313
      // write the document to the database
314
      try {
315
        DBSAXWriter dbw = new DBSAXWriter(xml, conn);
316
      } catch (SQLException e1) {
317
          out.println("Error 1 loading document:<p>\n" + e1.getMessage());
318
      }catch (IOException e2) {
319
          out.println("Error 2 loading document:<p>\n" + e2.getMessage());
320
      }catch (ClassNotFoundException e3) {
321
          out.println("Error 3 loading document:<p>\n" + e3.getMessage());
322
      }
323

    
324
      // set content type and other response header fields first
325
      response.setContentType("text/xml");
326
  
327
      out.println(doctext[0]);
328
  }
329
  
330
  /** 
331
   * Handle the validtion request and return the results 
332
   * to the requestor - DFH
333
   */
334
  private void handleValidateAction(PrintWriter out, Hashtable params, HttpServletResponse response) {
335

    
336
      // Get the document indicated
337
      String[] valtext = (String[])params.get("valtext");
338

    
339

    
340
      SAXParser parser = new SAXParser();           // works for both Xerces and Oracle
341
      parser.setValidationMode(true);               // Oracle
342
      GenericXMLValidate gxv = new GenericXMLValidate(parser, xmlcatalogfile);
343
      boolean valid = gxv.validateString(valtext[0]);
344

    
345
      // set content type and other response header fields first
346
      response.setContentType("text/plain");
347
  
348
      if (valid) {
349
        out.println("The input XML is VALID!");
350
      }
351
      else {
352
        out.println("The input XML is NOT VALID\n" + gxv.returnErrors());
353
      } 
354
    }
355

    
356
  /** 
357
   * Look up the document type from the database
358
   *
359
   */
360
  private String getDoctype(long docid) {
361
    // Look up the System ID of the XSL sheet
362
    PreparedStatement pstmt;
363
    String doctype = null;
364
 
365
    try {
366
      pstmt =
367
        conn.prepareStatement("SELECT doctype " + 
368
                                "FROM xml_documents " +
369
                               "WHERE docid = ?");
370
      // Bind the values to the query
371
      pstmt.setLong(1, new Long(docid).longValue());
372

    
373
      pstmt.execute();
374
      try {
375
        ResultSet rs = pstmt.getResultSet();
376
        try {
377
          boolean tableHasRows = rs.next();
378
          if (tableHasRows) {
379
            try {
380
              doctype  = rs.getString(1);
381
            } catch (SQLException e) {
382
              System.out.println("Error with getString: " + e.getMessage());
383
            }
384
          }
385
        } catch (SQLException e) {
386
          System.out.println("Error with next: " + e.getMessage());
387
        }
388
      } catch (SQLException e) {
389
        System.out.println("Error with getrset: " + e.getMessage());
390
      }
391
      pstmt.close();
392
    } catch (SQLException e) {
393
      System.out.println("Error getting id: " + e.getMessage());
394
    }
395

    
396
    return doctype;
397
  }
398
    
399
    
400
  /** 
401
   * Handle the document request and return the results 
402
   * to the requestor - DFH
403
   */
404
  private void handleGetDataDocumentAction(PrintWriter out, Hashtable params, HttpServletResponse response) {
405
      boolean error_flag = false;
406
      String error_message = "";
407
      // Get the document indicated
408
      String[] datadoc = (String[])params.get("datadoc");
409
  //    defaultdatapath = "C:\\Temp\\";    // for testing only!!!
410
   //   executescript = "test.bat";        // for testing only!!!
411
      
412
      // set content type and other response header fields first
413
      response.setContentType("application/octet-stream");
414
   if (defaultdatapath!=null) {
415
        if(!defaultdatapath.endsWith(System.getProperty("file.separator"))) defaultdatapath=defaultdatapath+System.getProperty("file.separator");
416
      System.out.println("Path= "+defaultdatapath+datadoc[0]);
417
      if (executescript!=null) {
418
        String command = null;
419
        File scriptfile = new File(executescript);
420
        if (scriptfile.exists()) {
421
            command=executescript+" "+datadoc[0]; }  // execute script includes path
422
        else {     // look in defaultdatapath
423
                command = defaultdatapath+executescript+" "+datadoc[0];  // on Win98 one MUST include the .bat extender
424
        }
425
      System.out.println(command);
426
      try {
427
      Process proc = Runtime.getRuntime().exec(command);
428
      proc.waitFor();
429
      }
430
      catch (Exception eee) {
431
        System.out.println("Error running process!");
432
        error_flag = true;
433
        error_message = "Error running process!";}
434
      } // end executescript not null if
435
      File datafile = new File(defaultdatapath+datadoc[0]);
436
      try {
437
      FileInputStream fw = new FileInputStream(datafile);
438
      int x;
439
     while ((x = fw.read())!=-1) {
440
        out.write(x); }
441
      fw.close();
442
      
443
      }
444
      catch (Exception e) {
445
        System.out.println("Error in returning file\n"+e.getMessage());
446
        error_flag=true;
447
        error_message = error_message+"\nError in returning file\n"+e.getMessage();}
448
   } // end defaultdatapath not null if
449
  }
450
    
451
    
452
}
(16-16/30)