Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that represents an XML document
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Matt Jones
7
 *    Release: @release@
8
 *
9
 *   '$Author: jones $'
10
 *     '$Date: 2000-08-22 22:32:53 -0700 (Tue, 22 Aug 2000) $'
11
 * '$Revision: 393 $'
12
 */
13

    
14
package edu.ucsb.nceas.metacat;
15

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

    
20
/**
21
 * A class that represents an XML document. It can be created with a simple
22
 * document identifier from a database connection.
23
 */
24
public class DocumentImpl {
25

    
26
  private Connection conn = null;
27
  private String docid = null;
28
  private String docname = null;
29
  private String doctype = null;
30
  private String system_id = null;
31
  private long rootnodeid;
32
  private ElementNode rootNode = null;
33

    
34
  /**
35
   * Constructor, creates document from database connection
36
   *
37
   * @param conn the database connection from which to read the document
38
   * @param docid the identifier of the document to be created
39
   */
40
  public DocumentImpl(Connection conn, String docid) throws McdbException 
41
  {
42
    try {
43
      this.conn = conn;
44
      this.docid = docid;
45
  
46
      // Look up the document information
47
      getDocumentInfo(docid);
48
      
49
      // Download all of the document nodes using a single SQL query
50
      TreeSet nodeRecordList = getNodeRecordList(docid);
51
  
52
      // Create the elements from the downloaded data in the TreeSet
53
      rootNode = new ElementNode(nodeRecordList, rootnodeid);
54

    
55
    } catch (McdbException ex) {
56
      throw ex;
57
    } catch (Throwable t) {
58
      throw new McdbException("Error reading document " + docid + ".");
59
    }
60
  }
61

    
62
  /**
63
   * get the document name
64
   */
65
  public String getDocname() {
66
    return docname;
67
  }
68

    
69
  /**
70
   * get the document type (which is the PublicID)
71
   */
72
  public String getDoctype() {
73
    return doctype;
74
  }
75

    
76
  /**
77
   * get the system identifier
78
   */
79
  public String getSystemID() {
80
    return system_id;
81
  }
82

    
83
  /**
84
   * get the root node identifier
85
   */
86
  public long getRootNodeID() {
87
    return rootnodeid;
88
  }
89

    
90
  /**
91
   * Create an XML document from the database for the document with ID docid
92
   */
93
  public String toString()
94
  {
95
    StringBuffer doc = new StringBuffer();
96

    
97
    // Append the resulting document to the StringBuffer and return it
98
    doc.append("<?xml version=\"1.0\"?>\n");
99
      
100
    if (docname != null) {
101
      if ((doctype != null) && (system_id != null)) {
102
        doc.append("<!DOCTYPE " + docname + " PUBLIC \"" + doctype + 
103
                   "\" \"" + system_id + "\">\n");
104
      } else {
105
        doc.append("<!DOCTYPE " + docname + ">\n");
106
      }
107
    }
108
    doc.append(rootNode.toString());
109
  
110
    return (doc.toString());
111
  }
112

    
113
  /**
114
   * Look up the document type information from the database
115
   *
116
   * @param docid the id of the document to look up
117
   */
118
  private void getDocumentInfo(String docid) throws McdbException 
119
  {
120
    PreparedStatement pstmt;
121

    
122
    try {
123
      pstmt =
124
        conn.prepareStatement("SELECT docname,doctype,rootnodeid " +
125
                                "FROM xml_documents " +
126
                               "WHERE docid = ?");
127
      // Bind the values to the query
128
      pstmt.setString(1, docid);
129

    
130
      pstmt.execute();
131
      ResultSet rs = pstmt.getResultSet();
132
      boolean tableHasRows = rs.next();
133
      if (tableHasRows) {
134
        this.docname    = rs.getString(1);
135
        this.doctype    = rs.getString(2);
136
        this.rootnodeid = rs.getLong(3);
137
      } 
138
      pstmt.close();
139

    
140
      if (this.doctype != null) {
141
        pstmt =
142
          conn.prepareStatement("SELECT system_id " +
143
                                  "FROM xml_catalog " +
144
                                 "WHERE public_id = ?");
145
        // Bind the values to the query
146
        pstmt.setString(1, doctype);
147
  
148
        pstmt.execute();
149
        rs = pstmt.getResultSet();
150
        tableHasRows = rs.next();
151
        if (tableHasRows) {
152
          this.system_id  = rs.getString(1);
153
        } 
154
        pstmt.close();
155
      }
156
    } catch (SQLException e) {
157
      throw new McdbException("Error accessing database connection.", e);
158
    }
159

    
160
    if (this.docname == null) {
161
      throw new McdbDocNotFoundException("Document not found: " + docid);
162
    }
163
  }
164

    
165
  /**
166
   * Look up the node data from the database
167
   *
168
   * @param docid the id of the document to look up
169
   */
170
  private TreeSet getNodeRecordList(String docid) throws McdbException 
171
  {
172
    PreparedStatement pstmt;
173
    TreeSet nodeRecordList = new TreeSet(new NodeComparator());
174
    long nodeid = 0;
175
    long parentnodeid = 0;
176
    long nodeindex = 0;
177
    String nodetype = null;
178
    String nodename = null;
179
    String nodedata = null;
180

    
181
    try {
182
      pstmt =
183
      conn.prepareStatement("SELECT nodeid,parentnodeid,nodeindex, " +
184
           "nodetype,nodename,"+               
185
           "replace(" +
186
           "replace(" +
187
           "replace(nodedata,'&','&amp;') " +
188
           ",'<','&lt;') " +
189
           ",'>','&gt;') " +
190
           "FROM xml_nodes WHERE docid = ?");
191

    
192
      // Bind the values to the query
193
      pstmt.setString(1, docid);
194

    
195
      pstmt.execute();
196
      ResultSet rs = pstmt.getResultSet();
197
      boolean tableHasRows = rs.next();
198
      while (tableHasRows) {
199
        nodeid = rs.getLong(1);
200
        parentnodeid = rs.getLong(2);
201
        nodeindex = rs.getLong(3);
202
        nodetype = rs.getString(4);
203
        nodename = rs.getString(5);
204
        nodedata = rs.getString(6);
205

    
206
        // add the data to the node record list hashtable
207
        NodeRecord currentRecord = new NodeRecord(nodeid, parentnodeid, 
208
                                   nodeindex, nodetype, nodename, nodedata);
209
        nodeRecordList.add(currentRecord);
210

    
211
        // Advance to the next node
212
        tableHasRows = rs.next();
213
      } 
214
      pstmt.close();
215

    
216
    } catch (SQLException e) {
217
      throw new McdbException("Error accessing database connection.", e);
218
    }
219

    
220
    if (nodeRecordList != null) {
221
      return nodeRecordList;
222
    } else {
223
      throw new McdbException("Error getting node data: " + docid);
224
    }
225
  }
226

    
227
  /**
228
   * main routine used for testing.
229
   * <p>
230
   * Usage: java DocumentImpl <docid>
231
   *
232
   * @param docid the id number of the document to display
233
   */
234
  static public void main(String[] args) {
235
     
236
     if (args.length < 1)
237
     {
238
        System.err.println("Wrong number of arguments!!!");
239
        System.err.println("USAGE: java DocumentImpl <docid>");
240
        return;
241
     } else {
242
        try {
243
                    
244
          String docid = args[0];
245
    
246
          // Open a connection to the database
247
          MetaCatUtil   util = new MetaCatUtil();
248
          Connection dbconn = util.openDBConnection();
249

    
250
          DocumentImpl xmldoc = new DocumentImpl( dbconn, docid );
251
          System.out.println(xmldoc);
252

    
253
        } catch (McdbException me) {
254
          me.toXml(new PrintWriter(System.err));
255
        } catch (Exception e) {
256
          System.err.println("EXCEPTION HANDLING REQUIRED");
257
          System.err.println(e.getMessage());
258
          e.printStackTrace(System.err);
259
        }
260
     }
261
  }
262
}
(18-18/30)