Project

General

Profile

1
/**
2
 *      Name: DBSAXNode.java
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
 *
8
 *   Version: '$Id: DBSAXNode.java 177 2000-06-20 01:42:11Z jones $'
9
 */
10

    
11
package edu.ucsb.nceas.metacat;
12

    
13
import java.sql.*;
14
import java.io.IOException;
15
import java.util.Hashtable;
16
import java.util.Enumeration;
17

    
18
/** 
19
 * A Class that represents an XML node and its contents and
20
 * can write its own representation to a database connection
21
 */
22
public class DBSAXNode extends BasicNode {
23

    
24
  private Connection	conn;
25
  private DBSAXNode	parentNode;
26

    
27
  /** 
28
   * Construct a new node instance for DOCUMENT nodes
29
   *
30
   * @param conn the JDBC Connection to which all information is written
31
   * @param tagname the name of the node
32
   */
33
  public DBSAXNode (Connection conn, String tagname) {
34
    super(tagname);
35
    this.conn = conn;
36
    this.parentNode = null;
37
    writeChildNodeToDB("DOCUMENT", tagname, null);
38
    setRootNodeID(getNodeID());
39
  }
40

    
41
  /** 
42
   * Construct a new node instance for ELEMENT nodes
43
   *
44
   * @param conn the JDBC Connection to which all information is written
45
   * @param tagname the name of the node
46
   * @param parentNode the parent node for this node being created
47
   */
48
  public DBSAXNode (Connection conn, String tagname, DBSAXNode parentNode, 
49
                    DBSAXNode rootNode, DBSAXDocument currentDocument) {
50

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

    
80
      // Bind the values to the query
81
      long nid = generateNodeID();
82
      pstmt.setLong(1, nid);
83
      pstmt.setString(2, nodetype);
84
      pstmt.setString(3, nodename);
85
      if (nodetype != "DOCUMENT") {
86
        if (nodetype == "ELEMENT") {
87
          pstmt.setLong(4, getParentID());
88
          pstmt.setLong(5, getRootNodeID());
89
          pstmt.setString(6, getDocID());
90
          pstmt.setString(7, data);
91
          pstmt.setInt(8, getNodeIndex());
92
        } else {
93
          pstmt.setLong(4, getNodeID());
94
          pstmt.setLong(5, getRootNodeID());
95
          pstmt.setString(6, getDocID());
96
          pstmt.setString(7, data);
97
          pstmt.setInt(8, incChildNum());
98
        }
99
      }
100
      // Do the insertion
101
      pstmt.execute();
102
      pstmt.close();
103
      
104
      if (nodetype.equals("DOCUMENT") || nodetype.equals("ELEMENT")) {
105

    
106
        // Record the node id that was generated from the database
107
        setNodeID(nid);
108

    
109
        // Record the node type that was passed to the method
110
        setNodeType(nodetype);
111

    
112
      }
113

    
114
    } catch (SQLException e) {
115
      System.err.println("Error inserting node: (" + nodetype + ", " +
116
                                                     nodename + ", " + 
117
                                                     data + ")" );
118
      System.err.println(e.getMessage());
119
    }
120
  }
121

    
122
  /** 
123
   * creates SQL code to put nodename for the document node 
124
   * into DB connection 
125
   */
126
  public void writeNodename(String nodename) {
127
      try {
128
        PreparedStatement pstmt;
129
        pstmt = conn.prepareStatement(
130
              "UPDATE xml_nodes set nodename = ? " +
131
              "WHERE nodeid = ?");
132

    
133
        // Bind the values to the query
134
        pstmt.setString(1, nodename);
135
        pstmt.setLong(2, getNodeID());
136
        // Do the insertion
137
        pstmt.execute();
138
        pstmt.close();
139
      } catch (SQLException e) {
140
        System.out.println(e.getMessage());
141
      }
142
  }
143

    
144
  /** 
145
   * creates SQL code to put root node id for the document node 
146
   * into DB connection 
147
   */
148
  public void writeRootNodeID(long rootnode_id) {
149
      try {
150
        PreparedStatement pstmt;
151
        pstmt = conn.prepareStatement(
152
              "UPDATE xml_nodes set rootnodeid = ? " +
153
              "WHERE nodeid = ?");
154

    
155
        // Bind the values to the query
156
        pstmt.setLong(1, rootnode_id);
157
        pstmt.setLong(2, getNodeID());
158
        // Do the insertion
159
        pstmt.execute();
160
        pstmt.close();
161
      } catch (SQLException e) {
162
        System.out.println(e.getMessage());
163
      }
164
  }
165
  /** 
166
   * creates SQL code to put doc ID for the document node and for 
167
   * comment/PI nodes under document node into DB connection 
168
   */
169
  public void writeDocID(String doc_id) {
170
      try {
171
        PreparedStatement pstmt;
172
        pstmt = conn.prepareStatement(
173
              "UPDATE xml_nodes set docid = ? " +
174
              "WHERE nodeid = ?");
175

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

    
183
        // for comments and PI on the top
184
        pstmt = conn.prepareStatement(
185
              "UPDATE xml_nodes set docid = ? " +
186
              "WHERE parentnodeid = ?");
187
        // Bind the values to the query
188
        pstmt.setString(1, doc_id);
189
        pstmt.setLong(2, getNodeID());
190
        // Do the insertion
191
        pstmt.execute();
192
        pstmt.close();
193
      } catch (SQLException e) {
194
        System.out.println(e.getMessage());
195
      }   
196
  }
197

    
198
  /** get next node id from DB connection */
199
  private long generateNodeID() {
200
      long nid=0;
201
      Statement stmt;
202
      try {
203
        stmt = conn.createStatement();
204
        stmt.execute("SELECT xml_nodes_id_seq.nextval FROM dual");
205
        ResultSet rs = stmt.getResultSet();
206
        boolean tableHasRows = rs.next();
207
        if (tableHasRows) {
208
          nid = rs.getLong(1);
209
        }
210
        stmt.close();
211
      } catch (SQLException e) {
212
        System.out.println("Error getting id: " + e.getMessage());
213
      }
214

    
215
      return nid;
216
  }
217

    
218
  /** Add a new attribute to this node, or set its value */
219
  public void setAttribute(String attName, String attValue) {
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);
226
    } else {
227
      System.err.println("Attribute name must not be null!");
228
    }
229
  }
230

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

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

    
256
      // advance to the next parent node
257
      nodePointer = nodePointer.getParentNode();
258

    
259
      // If we're at the DOCUMENT node (root of DOM tree), add
260
      // the root "/" to make the absolute path
261
      if (nodePointer.getNodeType().equals("DOCUMENT")) {
262
        currentPath.insert(0, "/");
263
        pathlist.put(currentPath.toString(), new Long(getNodeID()));
264
        atRootDocumentNode = true;
265
      } 
266
    }
267

    
268
    try {
269
      // Create an insert statement to reuse for all of the path insertions
270
      PreparedStatement pstmt = conn.prepareStatement(
271
              "INSERT INTO xml_index (nodeid, path) VALUES (?, ?)");
272
  
273
      // Step through the hashtable and insert each of the path values
274
      Enumeration en = pathlist.keys();
275
      while (en.hasMoreElements()) {
276
        String path = (String)en.nextElement();
277
        Long nodeid = (Long)pathlist.get(path);
278
        pstmt.setLong(1, nodeid.longValue());
279
        pstmt.setString(2, path);
280
        pstmt.execute();
281
  
282
        //System.out.println(nodeid + " ==> " + path);
283
      }
284

    
285
      // Close the database statement
286
      pstmt.close();
287
    } catch (SQLException sqe) {
288
      System.err.println("SQL Exception while inserting path to index.");
289
      System.err.println(sqe.getMessage());
290
    }
291
  }
292
 
293
  /** get the parent of this node */
294
  public DBSAXNode getParentNode() {
295
    return parentNode;
296
  }
297
}
(9-9/20)