Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that creates an XML text document
4
 *             from a query to a relational DB containing a DOM representation
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: 2000-08-21 14:52:48 -0700 (Mon, 21 Aug 2000) $'
12
 * '$Revision: 388 $'
13
 */
14

    
15
package edu.ucsb.nceas.metacat;
16

    
17
import java.sql.*;
18
import java.io.PrintWriter;
19
import java.util.TreeSet;
20

    
21
/** 
22
 * A Class that creates an XML text document
23
 * from a query to a relational DB containing a DOM representation
24
 */
25
public class DBReader {
26

    
27
  private Connection	conn = null;
28

    
29
  /**
30
   * main routine used for testing.
31
   * <p>
32
   * Usage: java DBReader <docid>
33
   *
34
   * @param nodeid the id number of the root of the subtree to display
35
   */
36
  static public void main(String[] args) {
37
     
38
     if (args.length < 1)
39
     {
40
        System.err.println("Wrong number of arguments!!!");
41
        System.err.println("USAGE: java DBReader <docid>");
42
        return;
43
     } else {
44
        try {
45
                    
46
          String docid = args[0];
47

    
48
          // Open a connection to the database
49
          MetaCatUtil   util = new MetaCatUtil();
50
          Connection dbconn = util.openDBConnection();
51

    
52
          DBReader rd = new DBReader( dbconn );
53
          String xml = rd.readXMLDocument(docid);
54
          System.out.println(xml);
55

    
56
        } catch (McdbException me) {
57
          me.toXml(new PrintWriter(System.err));
58
        } catch (Exception e) {
59
          System.err.println("EXCEPTION HANDLING REQUIRED");
60
          System.err.println(e.getMessage());
61
          e.printStackTrace(System.err);
62
        }
63
     }
64
  }
65
  
66
  /**
67
   * construct a DBReader instance.
68
   *
69
   * Generally, one calls readXMLDocument() after constructing the instance
70
   *
71
   * @param conn the database connection from which to read the document
72
   */
73
  public DBReader( Connection conn ) 
74
  {
75
    this.conn = conn;
76
  }
77
  
78
  /**
79
   * Create an XML document from the database for the document with ID docid
80
   *
81
   * @param docid the document identifier that we want retrieved
82
   */
83
  public String readXMLDocument(String docid) 
84
         throws McdbException
85
  {
86
    try {
87
      StringBuffer doc = new StringBuffer();
88

    
89
      // Look up the document information
90
      DoctypeInfo dti = getDoctypeInfo(docid);
91
      String docname = dti.getDocname();
92
      String doctype = dti.getDoctype();
93
      String sysid = dti.getSystemID();
94
      long rootnodeid = dti.getRootNodeID();
95
    
96
      // Download all of the document nodes using a single SQL query
97
      TreeSet nodeRecordList = getNodeRecordList(docid);
98

    
99
      // Create the elements from the downloaded nodes
100
      //ElementNode element = new ElementNode(conn, rootnodeid);
101
      ElementNode element = new ElementNode(nodeRecordList, rootnodeid);
102

    
103
      // Append the resulting document to the StringBuffer
104
      doc.append("<?xml version=\"1.0\"?>\n");
105
        
106
      if (docname != null) {
107
        if ((doctype != null) && (sysid != null)) {
108
          doc.append("<!DOCTYPE " + docname + " PUBLIC \"" + doctype + 
109
                     "\" \"" + sysid + "\">\n");
110
        } else {
111
          doc.append("<!DOCTYPE " + docname + ">\n");
112
        }
113
      }
114
      doc.append(element.toString());
115
  
116
      return (doc.toString());
117

    
118
    } catch (McdbException ex) {
119
      throw ex;
120
    } catch (Throwable t) {
121
      throw new McdbException("Error reading document " + docid + ".");
122
    }
123
  }
124

    
125
  /**
126
   * Look up the document type information from the database
127
   *
128
   * @param docid the id of the document to look up
129
   */
130
  public DoctypeInfo getDoctypeInfo(String docid) 
131
         throws McdbException 
132
  {
133
    PreparedStatement pstmt;
134
    String doctype = null;
135
    String docname = null;
136
    String sysid   = null;
137
    long rootnodeid = 0;
138
    DoctypeInfo dti = null;
139

    
140
    try {
141
      pstmt =
142
        conn.prepareStatement("SELECT docname,doctype,rootnodeid " +
143
                                "FROM xml_documents " +
144
                               "WHERE docid = ?");
145
      // Bind the values to the query
146
      pstmt.setString(1, docid);
147

    
148
      pstmt.execute();
149
      ResultSet rs = pstmt.getResultSet();
150
      boolean tableHasRows = rs.next();
151
      if (tableHasRows) {
152
        docname    = rs.getString(1);
153
        doctype    = rs.getString(2);
154
        rootnodeid = rs.getLong(3);
155
      } 
156
      pstmt.close();
157

    
158
      if (doctype != null) {
159
        pstmt =
160
          conn.prepareStatement("SELECT system_id " +
161
                                  "FROM xml_catalog " +
162
                                 "WHERE public_id = ?");
163
        // Bind the values to the query
164
        pstmt.setString(1, doctype);
165
  
166
        pstmt.execute();
167
        rs = pstmt.getResultSet();
168
        tableHasRows = rs.next();
169
        if (tableHasRows) {
170
          sysid  = rs.getString(1);
171
        } 
172
        pstmt.close();
173
      }
174
    } catch (SQLException e) {
175
      throw new McdbException("Error accessing database connection.", e);
176
    }
177

    
178
    if (docname != null) {
179
      dti = new DoctypeInfo(docname, doctype, sysid, rootnodeid);
180
      return dti;
181
    } else {
182
      throw new McdbDocNotFoundException("Document not found: " + docid);
183
    }
184
  }
185

    
186
  /**
187
   * Look up the node data from the database
188
   *
189
   * @param docid the id of the document to look up
190
   */
191
  public TreeSet getNodeRecordList(String docid) 
192
         throws McdbException 
193
  {
194
    PreparedStatement pstmt;
195
    TreeSet nodeRecordList = new TreeSet(new NodeComparator());
196
    long nodeid = 0;
197
    long parentnodeid = 0;
198
    long nodeindex = 0;
199
    String nodetype = null;
200
    String nodename = null;
201
    String nodedata = null;
202

    
203
    try {
204
      pstmt =
205
      conn.prepareStatement("SELECT nodeid,parentnodeid,nodeindex, " +
206
           "nodetype,nodename,"+               
207
           "replace(" +
208
           "replace(" +
209
           "replace(nodedata,'&','&amp;') " +
210
           ",'<','&lt;') " +
211
           ",'>','&gt;') " +
212
           "FROM xml_nodes WHERE docid = ?");
213

    
214
      // Bind the values to the query
215
      pstmt.setString(1, docid);
216

    
217
      pstmt.execute();
218
      ResultSet rs = pstmt.getResultSet();
219
      boolean tableHasRows = rs.next();
220
      while (tableHasRows) {
221
        nodeid = rs.getLong(1);
222
        parentnodeid = rs.getLong(2);
223
        nodeindex = rs.getLong(3);
224
        nodetype = rs.getString(4);
225
        nodename = rs.getString(5);
226
        nodedata = rs.getString(6);
227

    
228
        // add the data to the node record list hashtable
229
        NodeRecord currentRecord = new NodeRecord(nodeid, parentnodeid, 
230
                                   nodeindex, nodetype, nodename, nodedata);
231
        nodeRecordList.add(currentRecord);
232

    
233
        // Advance to the next node
234
        tableHasRows = rs.next();
235
      } 
236
      pstmt.close();
237

    
238
    } catch (SQLException e) {
239
      throw new McdbException("Error accessing database connection.", e);
240
    }
241

    
242
    if (nodeRecordList != null) {
243
      return nodeRecordList;
244
    } else {
245
      throw new McdbException("Error getting node data: " + docid);
246
    }
247
  }
248

    
249
  /**
250
   * A utility class that encapsulates document type information
251
   */
252
  public class DoctypeInfo {
253
    private String docname = null;
254
    private String doctype = null;
255
    private String system_id = null;
256
    private long rootnodeid;
257

    
258
    /**
259
     * Constructor
260
     */
261
    public DoctypeInfo(String docname, String doctype, 
262
                       String system_id, long rootnodeid) {
263
      this.docname = docname;
264
      this.doctype = doctype;
265
      this.system_id = system_id;
266
      this.rootnodeid = rootnodeid;
267
    }
268

    
269
    /**
270
     * get the document name
271
     */
272
    public String getDocname() {
273
      return docname;
274
    }
275

    
276
    /**
277
     * get the document type
278
     */
279
    public String getDoctype() {
280
      return doctype;
281
    }
282

    
283
    /**
284
     * get the system identifier
285
     */
286
    public String getSystemID() {
287
      return system_id;
288
    }
289

    
290
    /**
291
     * get the root node identifier
292
     */
293
    public long getRootNodeID() {
294
      return rootnodeid;
295
    }
296
  }
297
}
(9-9/29)