Project

General

Profile

1
/**
2
 *  '$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
 *    Release: @release@
9
 *
10
 *   '$Author: jones $'
11
 *     '$Date: 2001-09-14 16:00:54 -0700 (Fri, 14 Sep 2001) $'
12
 * '$Revision: 832 $'
13
 *
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
 */
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
import java.util.Stack;
36

    
37
import oracle.xml.parser.v2.XSLStylesheet;
38
import oracle.xml.parser.v2.XSLException;
39
import oracle.xml.parser.v2.XMLParseException;
40
import oracle.xml.parser.v2.XSLProcessor;
41
import oracle.xml.parser.v2.XMLDocument;
42
import oracle.xml.parser.v2.DOMParser;
43
import org.w3c.dom.Document;
44
import org.w3c.dom.Node;
45
import org.w3c.dom.Element;
46
import org.xml.sax.SAXException;
47

    
48
/** 
49
 * A Class that transforms XML documents utitlizing XSL style sheets
50
 */
51
public class DBTransform {
52

    
53
  private Connection	conn = null;
54
  private MetaCatUtil   util = null;
55
  private String 	configDir = null;
56
  private String	defaultStyle = null;
57

    
58
  /**
59
   * construct a DBTransform instance.
60
   *
61
   * Generally, one calls transformXMLDocument() after constructing the instance
62
   *
63
   * @param conn the database connection from which to lookup the public ids
64
   */
65
  public DBTransform( Connection conn ) 
66
                  throws IOException, 
67
                         SQLException, 
68
                         ClassNotFoundException
69
  {
70
    this.conn = conn;
71
    util = new MetaCatUtil();
72
    configDir = util.getOption("config-dir");
73
    defaultStyle = util.getOption("default-style");
74
  }
75
  
76
  /**
77
   * Transform an XML document using the stylesheet reference from the db
78
   *
79
   * @param doc the document to be transformed
80
   * @param sourcetype the document type of the source
81
   * @param targettype the target document type
82
   * @param qformat the name of the style set to use
83
   * @param pw the PrintWriter to which output is printed
84
   */
85
  public void transformXMLDocument(String doc, String sourcetype, 
86
                String targettype, String qformat, PrintWriter pw) {
87
    
88
    // Look up the stylesheet for this type combination
89
    String xsl_system_id = getStyleSystemId(qformat, sourcetype, targettype);
90

    
91
    if (xsl_system_id != null) {
92
      // Create a stylesheet from the system id that was found
93
      try {
94
        XSLStylesheet style = new XSLStylesheet(new URL(xsl_system_id), null);
95
        DOMParser dp = new DOMParser();
96
        dp.setValidationMode(false);
97
        dp.parse((Reader)(new StringReader(doc)));
98
        new XSLProcessor().processXSL(style, dp.getDocument(), pw);
99
      } catch (Exception e) {
100
        pw.println(xsl_system_id + "Error transforming document in " +
101
                   "DBTransform.transformXMLDocument: " +
102
                   e.getMessage());
103
      }
104
    } else {
105
      // No stylesheet registered form this document type, so just return the 
106
      // XML stream we were passed
107
      pw.print(doc);
108
    }
109
  }
110

    
111
  /**
112
   * Lookup a stylesheet reference from the db catalog
113
   *
114
   * @param qformat    the named style-set format
115
   * @param sourcetype the document type of the source
116
   * @param targettype the document type of the target
117
   */
118
  public String getStyleSystemId(String qformat, String sourcetype, 
119
                String targettype) {
120
    String systemId = null;
121

    
122
    if ((qformat == null) || (qformat.equals("html"))) {
123
      qformat = defaultStyle;
124
    }
125

    
126
    // Load the style-set map for this qformat into a DOM
127
    try {
128
      String filename = configDir + "/" + qformat + ".xml";       
129
      util.debugMessage("Trying style-set file: " + filename);
130

    
131
      DOMParser dp = new DOMParser();
132
      dp.setValidationMode(false);
133
      dp.parse((Reader)(new FileReader(filename)));
134
      Document doc = dp.getDocument();
135
      Element root = doc.getDocumentElement();
136
      String styleName = root.getAttribute("name");
137
      util.debugMessage("Root style-set element is: " + styleName);
138
      
139
      Element currentElement = (Element)root.getFirstChild();
140
      systemId = ((Node)currentElement.getFirstChild()).getNodeValue();
141
      util.debugMessage("Default is: " + systemId);
142

    
143
      while ((currentElement = 
144
              (Element)currentElement.getNextSibling()) != null) {
145
        String tagName = currentElement.getTagName();
146
        util.debugMessage("Processing element: " + tagName);
147
        if (tagName.equals("doctype")) {
148
          String doctype = currentElement.getAttribute("publicid");
149
          util.debugMessage("Processing publicid: " + doctype);
150
          util.debugMessage("Comparing to source: " + sourcetype);
151
          if (doctype.equals(sourcetype)) {
152
            Element currentChild = (Element)currentElement.getFirstChild();
153
            while (currentChild != null) {
154
              String target = currentChild.getAttribute("publicid");
155
              util.debugMessage("Processing target publicid: " + target);
156
              util.debugMessage("Comparing to target: " + targettype);
157
              if (target.equals(targettype)) {
158
                Node styleText = currentChild.getFirstChild();
159
                systemId = styleText.getNodeValue();
160
                break; 
161
              }
162
              currentChild = (Element)currentChild.getNextSibling();
163
            }
164
          }
165
        }
166
      }
167
    } catch (IOException ioe) {
168
      util.debugMessage("Caught IOException while opening style-set config.");
169
    } catch (XMLParseException xpe) {
170
      util.debugMessage("Error parsing style-set file");
171
    } catch (SAXException se) {
172
      util.debugMessage("SAX error parsing style-set file");
173
    }
174

    
175
    // Return the system ID for this particular source document type
176
    return systemId;
177
  }
178

    
179
  /**
180
   * Lookup a stylesheet reference from the db catalog
181
   *
182
   * @param objecttype the type of the object we want to retrieve
183
   * @param sourcetype the document type of the source
184
   * @param targettype the document type of the target
185
   */
186
  public String getSystemId(String objecttype, String sourcetype, 
187
                String targettype) {
188

    
189
    // Look up the System ID of a particular object
190
    PreparedStatement pstmt;
191
    String the_system_id = null;
192
    try {
193
      pstmt =
194
        conn.prepareStatement("SELECT system_id " +
195
                "FROM xml_catalog " +
196
                "WHERE entry_type = ? " +
197
                "AND source_doctype = ? " +
198
                "AND target_doctype = ? ");
199
      // Bind the values to the query
200
      pstmt.setString(1, objecttype);
201
      pstmt.setString(2, sourcetype);
202
      pstmt.setString(3, targettype);
203
      pstmt.execute();
204
      try {
205
        ResultSet rs = pstmt.getResultSet();
206
        try {
207
          boolean tableHasRows = rs.next();
208
          if (tableHasRows) {
209
            try {
210
              the_system_id = rs.getString(1);
211
            } catch (SQLException e) {
212
              System.out.println("Error with getString in " + 
213
                                 "DBTransform.getSystemId: " + e.getMessage());                
214
            }
215
          } else {
216
            the_system_id = null; 
217
          }
218
        } catch (SQLException e) {
219
          System.err.println("Error with next in DBTransform.getSystemId: " + 
220
                              e.getMessage());
221
          return ("Error with next: " + e.getMessage());
222
        }
223
      } catch (SQLException e) {
224
        System.err.println("Error with getrset in DBTransform.getSystemId: " + 
225
                            e.getMessage());
226
        return ("Error with getrset: " + e.getMessage());
227
      }
228
      pstmt.close();
229
    } catch (SQLException e) {
230
      System.err.println("Error getting id in DBTransform.getSystemId: " + 
231
                          e.getMessage());
232
      return ("Error getting id in DBTransform.getSystemId:: " + 
233
               e.getMessage());
234
    }
235
    return the_system_id;
236
  }
237

    
238
  /**
239
   * the main routine used to test the transform utility.
240
   *
241
   * Usage: java DBTransform
242
   */
243
  static public void main(String[] args) {
244
     
245
     if (args.length > 0)
246
     {
247
        System.err.println("Wrong number of arguments!!!");
248
        System.err.println("USAGE: java DBTransform");
249
        return;
250
     } else {
251
        try {
252
                    
253
          // Open a connection to the database
254
          MetaCatUtil   util = new MetaCatUtil();
255
          Connection dbconn = util.openDBConnection();
256

    
257
          // Create a test document
258
          StringBuffer testdoc = new StringBuffer();
259
          testdoc.append("<?xml version=\"1.0\"?>");
260
          testdoc.append("<eml-dataset><metafile_id>NCEAS-0001</metafile_id>");
261
          testdoc.append("<dataset_id>DS001</dataset_id>");
262
          testdoc.append("<title>My test doc</title></eml-dataset>");
263

    
264
          // Transform the document to the new doctype
265
          DBTransform dbt = new DBTransform(dbconn);
266
          dbt.transformXMLDocument(testdoc.toString(), 
267
                                   "-//NCEAS//eml-dataset//EN", 
268
                                   "-//W3C//HTML//EN", 
269
                                   "knb",
270
                                   new PrintWriter(System.out));
271

    
272
        } catch (Exception e) {
273
          System.err.println("EXCEPTION HANDLING REQUIRED");
274
          System.err.println(e.getMessage());
275
          e.printStackTrace(System.err);
276
        }
277
     }
278
  }
279
  
280
  private void dbg(int position) {
281
    System.err.println("Debug flag: " + position);
282
  }
283

    
284
}
(18-18/40)