Project

General

Profile

1 15 jones
/**
2 203 jones
 *  '$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 15 jones
 *
8 203 jones
 *   '$Author$'
9
 *     '$Date$'
10
 * '$Revision$'
11 15 jones
 */
12
13 75 jones
package edu.ucsb.nceas.metacat;
14 15 jones
15
import java.sql.*;
16
import java.io.IOException;
17
import java.util.Hashtable;
18
import java.util.Enumeration;
19
20 31 jones
/**
21 137 jones
 * A Class that represents an XML node and its contents and
22 31 jones
 * can write its own representation to a database connection
23
 */
24 137 jones
public class DBSAXNode extends BasicNode {
25 15 jones
26 176 jones
  private Connection	conn;
27
  private DBSAXNode	parentNode;
28 15 jones
29 133 jones
  /**
30 136 jones
   * Construct a new node instance for DOCUMENT nodes
31 133 jones
   *
32
   * @param conn the JDBC Connection to which all information is written
33 136 jones
   * @param tagname the name of the node
34 133 jones
   */
35 137 jones
  public DBSAXNode (Connection conn, String tagname) {
36 136 jones
    super(tagname);
37
    this.conn = conn;
38 176 jones
    this.parentNode = null;
39 136 jones
    writeChildNodeToDB("DOCUMENT", tagname, null);
40 149 bojilova
    setRootNodeID(getNodeID());
41 136 jones
  }
42
43
  /**
44
   * Construct a new node instance for ELEMENT nodes
45
   *
46
   * @param conn the JDBC Connection to which all information is written
47
   * @param tagname the name of the node
48
   * @param parentNode the parent node for this node being created
49
   */
50 176 jones
  public DBSAXNode (Connection conn, String tagname, DBSAXNode parentNode,
51
                    DBSAXNode rootNode, DBSAXDocument currentDocument) {
52 21 jones
53 136 jones
    super(tagname);
54
    setParentID(parentNode.getNodeID());
55 149 bojilova
    setRootNodeID(rootNode.getNodeID());
56
    setDocID(currentDocument.getDocID());
57 136 jones
    setNodeIndex(parentNode.incChildNum());
58 133 jones
    this.conn = conn;
59 176 jones
    this.parentNode = parentNode;
60 136 jones
    writeChildNodeToDB("ELEMENT", getTagName(), null);
61 176 jones
    updateNodeIndex();
62 133 jones
  }
63 15 jones
64 133 jones
  /** creates SQL code and inserts new node into DB connection */
65
  public void writeChildNodeToDB(String nodetype, String nodename,
66 136 jones
                                 String data) {
67 133 jones
    try {
68
      PreparedStatement pstmt;
69
      if (nodetype == "DOCUMENT") {
70
        pstmt = conn.prepareStatement(
71
            "INSERT INTO xml_nodes " +
72
            "(nodeid, nodetype, nodename) " +
73 174 bojilova
            "VALUES (?, ?, ?)");
74 204 jones
        MetaCatUtil.debugMessage("INSERTING DOCNAME: " + nodename);
75 133 jones
      } else {
76
        pstmt = conn.prepareStatement(
77
            "INSERT INTO xml_nodes " +
78
            "(nodeid, nodetype, nodename, " +
79 149 bojilova
            "parentnodeid, rootnodeid, docid, nodedata, nodeindex) " +
80 174 bojilova
            "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
81 133 jones
      }
82 19 jones
83 133 jones
      // Bind the values to the query
84 176 jones
      long nid = generateNodeID();
85 174 bojilova
      pstmt.setLong(1, nid);
86
      pstmt.setString(2, nodetype);
87
      pstmt.setString(3, nodename);
88 133 jones
      if (nodetype != "DOCUMENT") {
89
        if (nodetype == "ELEMENT") {
90 174 bojilova
          pstmt.setLong(4, getParentID());
91
          pstmt.setLong(5, getRootNodeID());
92
          pstmt.setString(6, getDocID());
93
          pstmt.setString(7, data);
94
          pstmt.setInt(8, getNodeIndex());
95 133 jones
        } else {
96 174 bojilova
          pstmt.setLong(4, getNodeID());
97
          pstmt.setLong(5, getRootNodeID());
98
          pstmt.setString(6, getDocID());
99
          pstmt.setString(7, data);
100
          pstmt.setInt(8, incChildNum());
101 72 bojilova
        }
102 133 jones
      }
103
      // Do the insertion
104
      pstmt.execute();
105
      pstmt.close();
106 174 bojilova
107 177 jones
      if (nodetype.equals("DOCUMENT") || nodetype.equals("ELEMENT")) {
108 176 jones
109 177 jones
        // Record the node id that was generated from the database
110
        setNodeID(nid);
111 176 jones
112 177 jones
        // Record the node type that was passed to the method
113
        setNodeType(nodetype);
114
115
      }
116
117 133 jones
    } catch (SQLException e) {
118
      System.err.println("Error inserting node: (" + nodetype + ", " +
119
                                                     nodename + ", " +
120 136 jones
                                                     data + ")" );
121 133 jones
      System.err.println(e.getMessage());
122 110 bojilova
    }
123 133 jones
  }
124 110 bojilova
125 133 jones
  /**
126
   * creates SQL code to put nodename for the document node
127
   * into DB connection
128
   */
129
  public void writeNodename(String nodename) {
130
      try {
131
        PreparedStatement pstmt;
132
        pstmt = conn.prepareStatement(
133
              "UPDATE xml_nodes set nodename = ? " +
134
              "WHERE nodeid = ?");
135 16 jones
136 133 jones
        // Bind the values to the query
137
        pstmt.setString(1, nodename);
138 134 jones
        pstmt.setLong(2, getNodeID());
139 133 jones
        // Do the insertion
140
        pstmt.execute();
141
        pstmt.close();
142
      } catch (SQLException e) {
143
        System.out.println(e.getMessage());
144
      }
145
  }
146 16 jones
147 149 bojilova
  /**
148
   * creates SQL code to put root node id for the document node
149
   * into DB connection
150
   */
151
  public void writeRootNodeID(long rootnode_id) {
152
      try {
153
        PreparedStatement pstmt;
154
        pstmt = conn.prepareStatement(
155
              "UPDATE xml_nodes set rootnodeid = ? " +
156
              "WHERE nodeid = ?");
157
158
        // Bind the values to the query
159
        pstmt.setLong(1, rootnode_id);
160
        pstmt.setLong(2, getNodeID());
161
        // Do the insertion
162
        pstmt.execute();
163
        pstmt.close();
164
      } catch (SQLException e) {
165
        System.out.println(e.getMessage());
166
      }
167
  }
168
  /**
169 176 jones
   * creates SQL code to put doc ID for the document node and for
170
   * comment/PI nodes under document node into DB connection
171 149 bojilova
   */
172 162 bojilova
  public void writeDocID(String doc_id) {
173 149 bojilova
      try {
174
        PreparedStatement pstmt;
175
        pstmt = conn.prepareStatement(
176
              "UPDATE xml_nodes set docid = ? " +
177
              "WHERE nodeid = ?");
178
179
        // Bind the values to the query
180 162 bojilova
        pstmt.setString(1, doc_id);
181 149 bojilova
        pstmt.setLong(2, getNodeID());
182
        // Do the insertion
183
        pstmt.execute();
184
        pstmt.close();
185
186
        // for comments and PI on the top
187
        pstmt = conn.prepareStatement(
188
              "UPDATE xml_nodes set docid = ? " +
189
              "WHERE parentnodeid = ?");
190
        // Bind the values to the query
191 162 bojilova
        pstmt.setString(1, doc_id);
192 149 bojilova
        pstmt.setLong(2, getNodeID());
193
        // Do the insertion
194
        pstmt.execute();
195
        pstmt.close();
196
      } catch (SQLException e) {
197
        System.out.println(e.getMessage());
198 174 bojilova
      }
199 149 bojilova
  }
200
201 174 bojilova
  /** get next node id from DB connection */
202 176 jones
  private long generateNodeID() {
203 174 bojilova
      long nid=0;
204 133 jones
      Statement stmt;
205
      try {
206
        stmt = conn.createStatement();
207 174 bojilova
        stmt.execute("SELECT xml_nodes_id_seq.nextval FROM dual");
208 133 jones
        ResultSet rs = stmt.getResultSet();
209
        boolean tableHasRows = rs.next();
210
        if (tableHasRows) {
211 174 bojilova
          nid = rs.getLong(1);
212 19 jones
        }
213 133 jones
        stmt.close();
214
      } catch (SQLException e) {
215
        System.out.println("Error getting id: " + e.getMessage());
216 15 jones
      }
217
218 174 bojilova
      return nid;
219 133 jones
  }
220 18 jones
221 137 jones
  /** Add a new attribute to this node, or set its value */
222 133 jones
  public void setAttribute(String attName, String attValue) {
223
    if (attName != null) {
224
      // Enter the attribute in the hash table
225
      super.setAttribute(attName, attValue);
226 18 jones
227 133 jones
      // And enter the attribute in the database
228 136 jones
      writeChildNodeToDB("ATTRIBUTE", attName, attValue);
229 133 jones
    } else {
230
      System.err.println("Attribute name must not be null!");
231 18 jones
    }
232 133 jones
  }
233 176 jones
234
  /**
235
   * Update the node index (xml_index) for this node by generating
236
   * test strings that represent all of the relative and absolute
237
   * paths through the XML tree from document root to this node
238
   */
239
  private void updateNodeIndex() {
240
    Hashtable pathlist = new Hashtable();
241
    boolean atStartingNode = true;
242
    boolean atRootDocumentNode = false;
243
    DBSAXNode nodePointer = this;
244
    StringBuffer currentPath = new StringBuffer();
245
246
    // Create a Hashtable of all of the paths to reach this node
247
    // including absolute paths and relative paths
248
    while (!atRootDocumentNode) {
249
      if (atStartingNode) {
250
        currentPath.insert(0, nodePointer.getTagName());
251
        pathlist.put(currentPath.toString(), new Long(getNodeID()));
252
        atStartingNode = false;
253
      } else {
254
        currentPath.insert(0, "/");
255
        currentPath.insert(0, nodePointer.getTagName());
256
        pathlist.put(currentPath.toString(), new Long(getNodeID()));
257
      }
258
259
      // advance to the next parent node
260
      nodePointer = nodePointer.getParentNode();
261
262
      // If we're at the DOCUMENT node (root of DOM tree), add
263
      // the root "/" to make the absolute path
264
      if (nodePointer.getNodeType().equals("DOCUMENT")) {
265
        currentPath.insert(0, "/");
266
        pathlist.put(currentPath.toString(), new Long(getNodeID()));
267
        atRootDocumentNode = true;
268
      }
269
    }
270
271
    try {
272
      // Create an insert statement to reuse for all of the path insertions
273
      PreparedStatement pstmt = conn.prepareStatement(
274
              "INSERT INTO xml_index (nodeid, path) VALUES (?, ?)");
275
276
      // Step through the hashtable and insert each of the path values
277
      Enumeration en = pathlist.keys();
278
      while (en.hasMoreElements()) {
279
        String path = (String)en.nextElement();
280
        Long nodeid = (Long)pathlist.get(path);
281
        pstmt.setLong(1, nodeid.longValue());
282
        pstmt.setString(2, path);
283
        pstmt.execute();
284
285
        //System.out.println(nodeid + " ==> " + path);
286
      }
287
288
      // Close the database statement
289
      pstmt.close();
290
    } catch (SQLException sqe) {
291
      System.err.println("SQL Exception while inserting path to index.");
292
      System.err.println(sqe.getMessage());
293
    }
294
  }
295
296
  /** get the parent of this node */
297
  public DBSAXNode getParentNode() {
298
    return parentNode;
299
  }
300 15 jones
}
301 203 jones
302
/**
303
 * '$Log$
304 204 jones
 * 'Revision 1.31  2000/06/26 10:35:05  jones
305
 * 'Merged in substantial changes to DBWriter and associated classes and to
306
 * 'the MetaCatServlet in order to accomodate the new UPDATE and DELETE
307
 * 'functions.  The command line tools and the parameters for the
308
 * 'servlet have changed substantially.
309
 * '
310 203 jones
 * 'Revision 1.30.2.2  2000/06/25 23:38:16  jones
311
 * 'Added RCSfile keyword
312
 * '
313
 * 'Revision 1.30.2.1  2000/06/25 23:34:17  jones
314
 * 'Changed documentation formatting, added log entries at bottom of source files
315
 * ''
316
 */