Project

General

Profile

1 87 jones
/**
2 203 jones
 *  '$RCSfile$'
3
 *    Purpose: A Class that transforms an XML text document
4
 *             into a another type using XSL
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Matt Jones
8 349 jones
 *    Release: @release@
9 87 jones
 *
10 203 jones
 *   '$Author$'
11
 *     '$Date$'
12
 * '$Revision$'
13 669 jones
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27 87 jones
 */
28
29
package edu.ucsb.nceas.metacat;
30
31
import java.io.*;
32
import java.net.URL;
33
import java.net.MalformedURLException;
34
import java.sql.*;
35 1688 tao
import java.util.Enumeration;
36 1664 tao
import java.util.Hashtable;
37 87 jones
import java.util.Stack;
38
39 906 berkley
import javax.xml.transform.TransformerFactory;
40
import javax.xml.transform.Transformer;
41
import javax.xml.transform.stream.StreamSource;
42
import javax.xml.transform.stream.StreamResult;
43
import javax.xml.transform.TransformerException;
44
import javax.xml.transform.TransformerConfigurationException;
45
46
import org.apache.xerces.parsers.DOMParser;
47
import org.w3c.dom.Attr;
48
import org.w3c.dom.NamedNodeMap;
49
import org.w3c.dom.NodeList;
50
import org.w3c.dom.Document;
51
import org.w3c.dom.Node;
52
import org.w3c.dom.NodeList;
53
import org.w3c.dom.DocumentType;
54
import org.xml.sax.SAXException;
55
import org.xml.sax.InputSource;
56
import org.apache.xerces.dom.DocumentTypeImpl;
57
import org.apache.xpath.XPathAPI;
58
import org.w3c.dom.NamedNodeMap;
59
60
/*
61 87 jones
import oracle.xml.parser.v2.XSLStylesheet;
62
import oracle.xml.parser.v2.XSLException;
63 832 jones
import oracle.xml.parser.v2.XMLParseException;
64 87 jones
import oracle.xml.parser.v2.XSLProcessor;
65
import oracle.xml.parser.v2.XMLDocument;
66
import oracle.xml.parser.v2.DOMParser;
67 906 berkley
*/
68 832 jones
import org.w3c.dom.Document;
69
import org.w3c.dom.Node;
70
import org.w3c.dom.Element;
71
import org.xml.sax.SAXException;
72 87 jones
73 1716 berkley
/**
74 87 jones
 * A Class that transforms XML documents utitlizing XSL style sheets
75
 */
76
public class DBTransform {
77
78 1217 tao
  //private Connection	conn = null;
79 832 jones
  private MetaCatUtil   util = null;
80
  private String 	configDir = null;
81
  private String	defaultStyle = null;
82 87 jones
83
  /**
84
   * construct a DBTransform instance.
85
   *
86
   * Generally, one calls transformXMLDocument() after constructing the instance
87
   *
88
   * @param conn the database connection from which to lookup the public ids
89
   */
90 1716 berkley
  public DBTransform()
91
                  throws IOException,
92
                         SQLException,
93 87 jones
                         ClassNotFoundException
94
  {
95 1217 tao
    //this.conn = conn;
96 832 jones
    util = new MetaCatUtil();
97
    configDir = util.getOption("config-dir");
98
    defaultStyle = util.getOption("default-style");
99 87 jones
  }
100 1716 berkley
101 87 jones
  /**
102 1716 berkley
   * @see transformXMLDocument(String doc, String sourceType,
103
   *            String targetType, String qformat, PrintWriter pw,
104
   *            String sessionid)
105
   */
106
  public void transformXMLDocument(String doc, String sourceType,
107 1717 berkley
                String targetType, String qformat, PrintWriter pw,
108
                Hashtable param)
109 1716 berkley
  {
110 1717 berkley
    transformXMLDocument(doc, sourceType, targetType, qformat, pw, param, null);
111 1716 berkley
  }
112
113
  /**
114 87 jones
   * Transform an XML document using the stylesheet reference from the db
115
   *
116
   * @param doc the document to be transformed
117
   * @param sourcetype the document type of the source
118
   * @param targettype the target document type
119 832 jones
   * @param qformat the name of the style set to use
120
   * @param pw the PrintWriter to which output is printed
121 1664 tao
   * @param params some parameters for eml2 transformation
122 87 jones
   */
123 1716 berkley
  public void transformXMLDocument(String doc, String sourceType,
124
                                   String targetType, String qformat,
125
                                   PrintWriter pw, Hashtable param,
126
                                   String sessionid)
127 1664 tao
 {
128 1716 berkley
129 87 jones
    // Look up the stylesheet for this type combination
130 941 tao
    String xslSystemId = getStyleSystemId(qformat, sourceType, targetType);
131 87 jones
132 941 tao
    if (xslSystemId != null) {
133 87 jones
      // Create a stylesheet from the system id that was found
134
      try {
135 906 berkley
        TransformerFactory tFactory = TransformerFactory.newInstance();
136
        Transformer transformer = tFactory.newTransformer(
137 941 tao
                                  new StreamSource(xslSystemId));
138 1688 tao
        //transformer.setParameter("qformat", qformat);
139
        //MetaCatUtil.debugMessage("qformat: "+qformat, 30);
140 1716 berkley
141
        if(sessionid != null)
142
        {
143
          transformer.setParameter("sessid", sessionid);
144
        }
145
146 1688 tao
        // Set up parameter for transformation
147 1664 tao
        if ( param != null)
148
        {
149 1688 tao
          Enumeration en = param.keys();
150
          while (en.hasMoreElements())
151
          {
152
            String key =(String)en.nextElement();
153
            String value = ((String[])(param.get(key)))[0];
154
            MetaCatUtil.debugMessage(key+" : "+value, 30);
155
            transformer.setParameter(key, value);
156
          }
157 1664 tao
        }
158 1716 berkley
159
        transformer.transform(new StreamSource(new StringReader(doc)),
160 906 berkley
                              new StreamResult(pw));
161 87 jones
      } catch (Exception e) {
162 941 tao
        pw.println(xslSystemId + "Error transforming document in " +
163 675 berkley
                   "DBTransform.transformXMLDocument: " +
164 87 jones
                   e.getMessage());
165 1716 berkley
166 87 jones
      }
167
    } else {
168 1716 berkley
      // No stylesheet registered form this document type, so just return the
169 87 jones
      // XML stream we were passed
170 100 jones
      pw.print(doc);
171 87 jones
    }
172
  }
173 1716 berkley
174 941 tao
  /**
175 1716 berkley
   * Transform an XML document to StringWriter using the stylesheet reference
176 941 tao
   * from the db
177
   * @param doc the document to be transformed
178
   * @param sourceType the document type of the source
179
   * @param targetType the target document type
180
   * @param qFormat the name of the style set to use
181
   * @param pw the StringWriter to which output will be stored
182
   */
183
  public void transformXMLDocument(String doc, String sourceType,
184 1716 berkley
                String targetType, String qFormat, StringWriter pw,
185
                String sessionid) {
186 941 tao
187
    // Look up the stylesheet for this type combination
188
    String xslSystemId = getStyleSystemId(qFormat, sourceType, targetType);
189
190
    if (xslSystemId != null) {
191
      // Create a stylesheet from the system id that was found
192
      try {
193
        TransformerFactory tFactory = TransformerFactory.newInstance();
194
        Transformer transformer = tFactory.newTransformer(
195
                                  new StreamSource(xslSystemId));
196 1716 berkley
        if(sessionid != null)
197
        {
198
          transformer.setParameter("sessid", sessionid);
199
        }
200 941 tao
        transformer.setParameter("qFormat", qFormat);
201
        transformer.transform(new StreamSource(new StringReader(doc)),
202
                              new StreamResult(pw));
203
      } catch (Exception e) {
204
        util.debugMessage(xslSystemId + "Error transforming document in " +
205
                   "DBTransform.transformXMLDocument: " +
206 1496 tao
                   e.getMessage(), 30);
207 1716 berkley
208 941 tao
      }
209
    } else {
210 1716 berkley
      // No stylesheet registered form this document type, so just return the
211 941 tao
      // XML stream we were passed
212 950 tao
      pw.write(doc);
213 941 tao
    }
214
  }
215 1716 berkley
216 906 berkley
  /**
217 1716 berkley
   * @see transformXMLDocument(String doc, String sourceType,
218
   *            String targetType, String qFormat, StringWriter pw
219
   *            String sessionid)
220
   */
221
  public void transformXMLDocument(String doc, String sourceType,
222
                String targetType, String qFormat, StringWriter pw)
223
  {
224
    transformXMLDocument(doc, sourceType, targetType, qFormat, pw, null);
225
  }
226
227
  /**
228 906 berkley
   * gets the content of a tag in a given xml file with the given path
229
   * @param f the file to parse
230
   * @param path the path to get the content from
231
   */
232 1716 berkley
  public static NodeList getPathContent(File f, String path)
233 906 berkley
  {
234
    if(f == null)
235
    {
236
      return null;
237
    }
238 1716 berkley
239 906 berkley
    DOMParser parser = new DOMParser();
240
    InputSource in;
241
    FileInputStream fs;
242 1716 berkley
243 906 berkley
    try
244 1716 berkley
    {
245 906 berkley
      fs = new FileInputStream(f);
246
      in = new InputSource(fs);
247
    }
248
    catch(FileNotFoundException fnf)
249
    {
250
      fnf.printStackTrace();
251
      return null;
252
    }
253 1716 berkley
254 906 berkley
    try
255
    {
256
      parser.parse(in);
257
      fs.close();
258
    }
259
    catch(Exception e1)
260
    {
261 1716 berkley
      System.err.println("File: " + f.getPath() + " : parse threw: " +
262 906 berkley
                         e1.toString());
263
      return null;
264
    }
265 1716 berkley
266 906 berkley
    Document doc = parser.getDocument();
267 1716 berkley
268 906 berkley
    try
269
    {
270
      NodeList docNodeList = XPathAPI.selectNodeList(doc, path);
271
      return docNodeList;
272
    }
273
    catch(Exception se)
274
    {
275 1716 berkley
      System.err.println("file: " + f.getPath() + " : parse threw: " +
276 906 berkley
                         se.toString());
277
      return null;
278
    }
279
  }
280 87 jones
281
  /**
282
   * Lookup a stylesheet reference from the db catalog
283
   *
284 832 jones
   * @param qformat    the named style-set format
285
   * @param sourcetype the document type of the source
286
   * @param targettype the document type of the target
287
   */
288 1716 berkley
  public String getStyleSystemId(String qformat, String sourcetype,
289 832 jones
                String targettype) {
290
    String systemId = null;
291
292
    if ((qformat == null) || (qformat.equals("html"))) {
293
      qformat = defaultStyle;
294
    }
295
296
    // Load the style-set map for this qformat into a DOM
297
    try {
298 906 berkley
      boolean breakflag = false;
299 1716 berkley
      String filename = configDir + "/" + qformat + ".xml";
300 1457 tao
      util.debugMessage("Trying style-set file: " + filename, 30);
301 906 berkley
      File f = new File(filename);
302
      NodeList nlDoctype = getPathContent(f, "/style-set/doctype");
303
      NodeList nlDefault = getPathContent(f, "/style-set/default-style");
304
      Node nDefault = nlDefault.item(0);
305
      systemId = nDefault.getFirstChild().getNodeValue(); //set the default
306 1716 berkley
307 906 berkley
      for(int i=0; i<nlDoctype.getLength(); i++)
308
      { //look for the right sourcetype
309
        Node nDoctype = nlDoctype.item(i);
310
        NamedNodeMap atts = nDoctype.getAttributes();
311
        Node nAtt = atts.getNamedItem("publicid");
312
        String doctype = nAtt.getFirstChild().getNodeValue();
313
        if(doctype.equals(sourcetype))
314
        { //found the right sourcetype now we need to get the target type
315
          NodeList nlChildren = nDoctype.getChildNodes();
316
          for(int j=0; j<nlChildren.getLength(); j++)
317
          {
318
            Node nChild = nlChildren.item(j);
319
            String childName = nChild.getNodeName();
320
            if(childName.equals("target"))
321
            {
322
              NamedNodeMap childAtts = nChild.getAttributes();
323
              Node nTargetPublicId = childAtts.getNamedItem("publicid");
324
              String target = nTargetPublicId.getFirstChild().getNodeValue();
325
              if(target.equals(targettype))
326
              { //we found the right target type
327
                NodeList nlTarget = nChild.getChildNodes();
328
                for(int k=0; k<nlTarget.getLength(); k++)
329
                {
330
                  Node nChildText = nlTarget.item(k);
331
                  if(nChildText.getNodeType() == Node.TEXT_NODE)
332
                  { //get the text from the target node
333
                    systemId = nChildText.getNodeValue();
334
                    breakflag = true;
335
                    break;
336
                  }
337
                }
338 832 jones
              }
339
            }
340 1716 berkley
341 906 berkley
            if(breakflag)
342
            {
343
              break;
344
            }
345 832 jones
          }
346
        }
347 1716 berkley
348 906 berkley
        if(breakflag)
349
        {
350
          break;
351
        }
352 832 jones
      }
353
    }
354 906 berkley
    catch(Exception e)
355
    {
356
      System.out.println("Error parsing style-set file: " + e.getMessage());
357
      e.printStackTrace();
358
    }
359 832 jones
360
    // Return the system ID for this particular source document type
361 1457 tao
    MetaCatUtil.debugMessage("style system id is: "+systemId, 30);
362 832 jones
    return systemId;
363
  }
364
365
  /**
366
   * Lookup a stylesheet reference from the db catalog
367
   *
368 87 jones
   * @param objecttype the type of the object we want to retrieve
369
   * @param sourcetype the document type of the source
370
   * @param targettype the document type of the target
371
   */
372 1716 berkley
  public String getSystemId(String objecttype, String sourcetype,
373 87 jones
                String targettype) {
374
375
    // Look up the System ID of a particular object
376 1217 tao
    PreparedStatement pstmt = null;
377 87 jones
    String the_system_id = null;
378 1217 tao
    DBConnection dbConn = null;
379
    int serialNumber = -1;
380 87 jones
    try {
381 1217 tao
      dbConn=DBConnectionPool.
382
                  getDBConnection("DBTransform.getSystemId");
383
      serialNumber=dbConn.getCheckOutSerialNumber();
384 87 jones
      pstmt =
385 1217 tao
        dbConn.prepareStatement("SELECT system_id " +
386 94 jones
                "FROM xml_catalog " +
387 764 bojilova
                "WHERE entry_type = ? " +
388
                "AND source_doctype = ? " +
389
                "AND target_doctype = ? ");
390 87 jones
      // Bind the values to the query
391 94 jones
      pstmt.setString(1, objecttype);
392
      pstmt.setString(2, sourcetype);
393
      pstmt.setString(3, targettype);
394 87 jones
      pstmt.execute();
395
      try {
396
        ResultSet rs = pstmt.getResultSet();
397
        try {
398
          boolean tableHasRows = rs.next();
399
          if (tableHasRows) {
400
            try {
401
              the_system_id = rs.getString(1);
402
            } catch (SQLException e) {
403 1716 berkley
              System.out.println("Error with getString in " +
404
                                 "DBTransform.getSystemId: " + e.getMessage());
405 675 berkley
            }
406 87 jones
          } else {
407 1716 berkley
            the_system_id = null;
408 87 jones
          }
409
        } catch (SQLException e) {
410 1716 berkley
          System.err.println("Error with next in DBTransform.getSystemId: " +
411 675 berkley
                              e.getMessage());
412 87 jones
          return ("Error with next: " + e.getMessage());
413
        }
414
      } catch (SQLException e) {
415 1716 berkley
        System.err.println("Error with getrset in DBTransform.getSystemId: " +
416 675 berkley
                            e.getMessage());
417 87 jones
        return ("Error with getrset: " + e.getMessage());
418
      }
419
      pstmt.close();
420
    } catch (SQLException e) {
421 1716 berkley
      System.err.println("Error getting id in DBTransform.getSystemId: " +
422 675 berkley
                          e.getMessage());
423 1716 berkley
      return ("Error getting id in DBTransform.getSystemId:: " +
424 675 berkley
               e.getMessage());
425 87 jones
    }
426 1217 tao
    finally
427
    {
428
      try
429
      {
430
        pstmt.close();
431
      }//try
432
      catch (SQLException sqlE)
433
      {
434
        MetaCatUtil.debugMessage("Error in DBTransform.getSystemId: "
435
                                   +sqlE.getMessage(), 30);
436
      }//catch
437
      finally
438
      {
439
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
440
      }//finally
441
    }//finally
442 87 jones
    return the_system_id;
443
  }
444 99 jones
445
  /**
446
   * the main routine used to test the transform utility.
447
   *
448 184 jones
   * Usage: java DBTransform
449 99 jones
   */
450
  static public void main(String[] args) {
451 1716 berkley
452 184 jones
     if (args.length > 0)
453 99 jones
     {
454
        System.err.println("Wrong number of arguments!!!");
455 184 jones
        System.err.println("USAGE: java DBTransform");
456 99 jones
        return;
457
     } else {
458
        try {
459 1716 berkley
460 99 jones
          // Open a connection to the database
461 1217 tao
          /*MetaCatUtil   util = new MetaCatUtil();
462
          Connection dbconn = util.openDBConnection();*/
463 99 jones
464
          // Create a test document
465
          StringBuffer testdoc = new StringBuffer();
466
          testdoc.append("<?xml version=\"1.0\"?>");
467
          testdoc.append("<eml-dataset><metafile_id>NCEAS-0001</metafile_id>");
468
          testdoc.append("<dataset_id>DS001</dataset_id>");
469
          testdoc.append("<title>My test doc</title></eml-dataset>");
470
471
          // Transform the document to the new doctype
472 1217 tao
          DBTransform dbt = new DBTransform();
473 1716 berkley
          dbt.transformXMLDocument(testdoc.toString(),
474
                                   "-//NCEAS//eml-dataset//EN",
475
                                   "-//W3C//HTML//EN",
476 832 jones
                                   "knb",
477 1664 tao
                                   new PrintWriter(System.out), null);
478 99 jones
479
        } catch (Exception e) {
480
          System.err.println("EXCEPTION HANDLING REQUIRED");
481
          System.err.println(e.getMessage());
482
          e.printStackTrace(System.err);
483
        }
484
     }
485
  }
486 1716 berkley
487 184 jones
  private void dbg(int position) {
488 99 jones
    System.err.println("Debug flag: " + position);
489
  }
490
491 87 jones
}