Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that represents an XML node and its contents
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: bojilova $'
10
 *     '$Date: 2000-09-20 13:22:23 -0700 (Wed, 20 Sep 2000) $'
11
 * '$Revision: 461 $'
12
 */
13

    
14
package edu.ucsb.nceas.metacat;
15

    
16
import java.sql.*;
17
import java.io.IOException;
18
import java.util.Hashtable;
19
import java.util.Enumeration;
20
import oracle.jdbc.driver.*;
21
import org.xml.sax.SAXException;
22

    
23
/** 
24
 * A Class that represents an XML node and its contents and
25
 * can write its own representation to a database connection
26
 */
27
public class DBSAXNode extends BasicNode {
28

    
29
  private Connection	conn;
30
  private DBSAXNode	parentNode;
31

    
32
  /** 
33
   * Construct a new node instance for DOCUMENT nodes
34
   *
35
   * @param conn the JDBC Connection to which all information is written
36
   */
37
  public DBSAXNode (Connection conn, String docid) throws SAXException {
38
    super();
39
    this.conn = conn;
40
    this.parentNode = null;
41
    writeChildNodeToDB("DOCUMENT", null, null, docid);
42
  }
43

    
44
  /** 
45
   * Construct a new node instance for ELEMENT nodes
46
   *
47
   * @param conn the JDBC Connection to which all information is written
48
   * @param tagname the name of the node
49
   * @param parentNode the parent node for this node being created
50
   */
51
  public DBSAXNode (Connection conn, String tagname, DBSAXNode parentNode, 
52
                    long rootnodeid, String docid, String doctype) 
53
                    throws SAXException {
54

    
55
    super(tagname);
56
    setParentID(parentNode.getNodeID());
57
    setRootNodeID(rootnodeid);
58
    setDocID(docid);
59
    setNodeIndex(parentNode.incChildNum());
60
    this.conn = conn;
61
    this.parentNode = parentNode;
62
    writeChildNodeToDB("ELEMENT", getTagName(), null, docid);
63
    updateNodeIndex(docid, doctype);
64
  }
65
    
66
  /** creates SQL code and inserts new node into DB connection */
67
  public void writeChildNodeToDB(String nodetype, String nodename,
68
                                 String data, String docid) 
69
                                 throws SAXException {
70
    try {
71
      PreparedStatement pstmt;
72
      if (nodetype == "DOCUMENT") {
73
        pstmt = conn.prepareStatement(
74
            "INSERT INTO xml_nodes " +
75
            "(nodeid, nodetype, nodename, docid, rootnodeid) " +
76
            "VALUES (?, ?, ?, ?, ?)");
77
        MetaCatUtil.debugMessage("INSERTING DOCNAME: " + nodename);
78
      } else {
79
        pstmt = conn.prepareStatement(
80
            "INSERT INTO xml_nodes " +
81
            "(nodeid, nodetype, nodename, docid, " +
82
            "rootnodeid, parentnodeid, nodedata, nodeindex) " +
83
            "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
84
      }
85

    
86
      // Bind the values to the query
87
      long nid = generateNodeID();
88
      pstmt.setLong(1, nid);
89
      pstmt.setString(2, nodetype);
90
      pstmt.setString(3, nodename);
91
      pstmt.setString(4, docid);
92
      if (nodetype == "DOCUMENT") {
93
        pstmt.setLong(5, nid);
94
      } else {
95
        if (nodetype == "ELEMENT") {
96
          pstmt.setLong(5, getRootNodeID());
97
          pstmt.setLong(6, getParentID());
98
          pstmt.setString(7, data);
99
          pstmt.setInt(8, getNodeIndex());
100
        } else {
101
          pstmt.setLong(5, getRootNodeID());
102
          pstmt.setLong(6, getNodeID());
103
          if ( nodetype == "TEXT" && getTagName().equals("meta_file_id") ) {
104
            pstmt.setString(7, getDocID());
105
          } else {
106
            pstmt.setString(7, data);
107
          }  
108
          pstmt.setInt(8, incChildNum());
109
        }
110
      }
111
      // Do the insertion
112
      pstmt.execute();
113
      pstmt.close();
114
      
115
      if (nodetype.equals("DOCUMENT")) {
116
        // Record the root node id that was generated from the database
117
        setRootNodeID(nid);
118
      }
119

    
120
      if (nodetype.equals("DOCUMENT") || nodetype.equals("ELEMENT")) {
121

    
122
        // Record the node id that was generated from the database
123
        setNodeID(nid);
124

    
125
        // Record the node type that was passed to the method
126
        setNodeType(nodetype);
127

    
128
      }
129

    
130
    } catch (SQLException e) {
131
      System.err.println("Error inserting node: (" + nodetype + ", " +
132
                                                     nodename + ", " + 
133
                                                     data + ")" );
134
      System.err.println(e.getMessage());
135
      throw new SAXException(e.getMessage());
136
    }
137
  }
138

    
139
  /** 
140
   * creates SQL code to put nodename for the document node 
141
   * into DB connection 
142
   */
143
  public void writeNodename(String nodename) throws SAXException {
144
      try {
145
        PreparedStatement pstmt;
146
        pstmt = conn.prepareStatement(
147
              "UPDATE xml_nodes set nodename = ? " +
148
              "WHERE nodeid = ?");
149

    
150
        // Bind the values to the query
151
        pstmt.setString(1, nodename);
152
        pstmt.setLong(2, getNodeID());
153
        // Do the insertion
154
        pstmt.execute();
155
        pstmt.close();
156
      } catch (SQLException e) {
157
        System.out.println(e.getMessage());
158
        throw new SAXException(e.getMessage());
159
      }
160
  }
161

    
162
  /** 
163
   * creates SQL code to put doc ID for the document node and for 
164
   * comment/PI nodes under document node into DB connection 
165
   */
166
/*  
167
  public void writeDocID(String doc_id) {
168
      try {
169
        PreparedStatement pstmt;
170
        pstmt = conn.prepareStatement(
171
              "UPDATE xml_nodes set docid = ? " +
172
              "WHERE nodeid = ?");
173

    
174
        // Bind the values to the query
175
        pstmt.setString(1, doc_id);
176
        pstmt.setLong(2, getNodeID());
177
        // Do the insertion
178
        pstmt.execute();
179
        pstmt.close();
180

    
181
        // for comments and PI on the top
182
        pstmt = conn.prepareStatement(
183
              "UPDATE xml_nodes set docid = ? " +
184
              "WHERE parentnodeid = ?");
185
        // Bind the values to the query
186
        pstmt.setString(1, doc_id);
187
        pstmt.setLong(2, getNodeID());
188
        // Do the insertion
189
        pstmt.execute();
190
        pstmt.close();
191
      } catch (SQLException e) {
192
        System.out.println(e.getMessage());
193
      }   
194
  }
195
*/
196
  /** get next node id from DB connection */
197
  private long generateNodeID() throws SAXException {
198
      long nid=0;
199
      Statement stmt;
200
      try {
201
        stmt = conn.createStatement();
202
        stmt.execute("SELECT xml_nodes_id_seq.nextval FROM dual");
203
        ResultSet rs = stmt.getResultSet();
204
        boolean tableHasRows = rs.next();
205
        if (tableHasRows) {
206
          nid = rs.getLong(1);
207
        }
208
        stmt.close();
209
      } catch (SQLException e) {
210
        System.out.println("Error getting id: " + e.getMessage());
211
        throw new SAXException(e.getMessage());
212
      }
213

    
214
      return nid;
215
  }
216

    
217
  /** Add a new attribute to this node, or set its value */
218
  public void setAttribute(String attName, String attValue, String docid)
219
              throws SAXException {
220
    if (attName != null) {
221
      // Enter the attribute in the hash table
222
      super.setAttribute(attName, attValue);
223

    
224
      // And enter the attribute in the database
225
      writeChildNodeToDB("ATTRIBUTE", attName, attValue, docid);
226
    } else {
227
      System.err.println("Attribute name must not be null!");
228
      throw new SAXException("Attribute name must not be null!");
229
    }
230
  }
231

    
232
  /** 
233
   * Update the node index (xml_index) for this node by generating
234
   * test strings that represent all of the relative and absolute
235
   * paths through the XML tree from document root to this node
236
   */
237
  private void updateNodeIndex(String docid, String doctype) 
238
               throws SAXException
239
  {
240
    Hashtable pathlist = new Hashtable();
241
    boolean atStartingNode = true;
242
    boolean atRootDocumentNode = false;
243
    DBSAXNode nodePointer = this;
244
    StringBuffer currentPath = new StringBuffer();
245
    int counter = 0;
246

    
247
    // Create a Hashtable of all of the paths to reach this node
248
    // including absolute paths and relative paths
249
    while (!atRootDocumentNode) {
250
      if (atStartingNode) {
251
        currentPath.insert(0, nodePointer.getTagName());
252
        pathlist.put(currentPath.toString(), new Long(getNodeID()));
253
        counter++;
254
        atStartingNode = false;
255
      } else {
256
        currentPath.insert(0, "/");
257
        currentPath.insert(0, nodePointer.getTagName());
258
        pathlist.put(currentPath.toString(), new Long(getNodeID()));
259
        counter++;
260
      }
261

    
262
      // advance to the next parent node
263
      nodePointer = nodePointer.getParentNode();
264

    
265
      // If we're at the DOCUMENT node (root of DOM tree), add
266
      // the root "/" to make the absolute path
267
      if (nodePointer.getNodeType().equals("DOCUMENT")) {
268
        currentPath.insert(0, "/");
269
        pathlist.put(currentPath.toString(), new Long(getNodeID()));
270
        counter++;
271
        atRootDocumentNode = true;
272
      } 
273
    }
274

    
275
    try {
276
      // Create an insert statement to reuse for all of the path insertions
277
      PreparedStatement pstmt = conn.prepareStatement(
278
              "INSERT INTO xml_index (nodeid, path, docid, doctype, " + 
279
               "parentnodeid) " + 
280
              "VALUES (?, ?, ?, ?, ?)");
281
      ((OraclePreparedStatement)pstmt).setExecuteBatch(counter);
282
  
283
      pstmt.setString(3, docid);
284
      pstmt.setString(4, doctype);
285
      pstmt.setLong(5, getParentID());
286
      
287
      // Step through the hashtable and insert each of the path values
288
      Enumeration en = pathlist.keys();
289
      while (en.hasMoreElements()) {
290
        String path = (String)en.nextElement();
291
        Long nodeid = (Long)pathlist.get(path);
292
        pstmt.setLong(1, nodeid.longValue());
293
        pstmt.setString(2, path);
294
        pstmt.executeUpdate();
295
  
296
        //System.out.println(nodeid + " ==> " + path);
297
      }
298

    
299
      // Close the database statement
300
      pstmt.close();
301
    } catch (SQLException sqe) {
302
      System.err.println("SQL Exception while inserting path to index.");
303
      System.err.println(sqe.getMessage());
304
      throw new SAXException(sqe.getMessage());
305
    }
306
  }
307
 
308
  /** get the parent of this node */
309
  public DBSAXNode getParentNode() {
310
    return parentNode;
311
  }
312
}
(10-10/28)