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
 *
8
 *   '$Author: jones $'
9
 *     '$Date: 2000-06-26 21:31:07 -0700 (Mon, 26 Jun 2000) $'
10
 * '$Revision: 204 $'
11
 */
12

    
13
package edu.ucsb.nceas.metacat;
14

    
15
import java.sql.*;
16
import java.io.IOException;
17
import java.util.Hashtable;
18
import java.util.Enumeration;
19

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

    
26
  private Connection	conn;
27
  private DBSAXNode	parentNode;
28

    
29
  /** 
30
   * Construct a new node instance for DOCUMENT nodes
31
   *
32
   * @param conn the JDBC Connection to which all information is written
33
   * @param tagname the name of the node
34
   */
35
  public DBSAXNode (Connection conn, String tagname) {
36
    super(tagname);
37
    this.conn = conn;
38
    this.parentNode = null;
39
    writeChildNodeToDB("DOCUMENT", tagname, null);
40
    setRootNodeID(getNodeID());
41
  }
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
  public DBSAXNode (Connection conn, String tagname, DBSAXNode parentNode, 
51
                    DBSAXNode rootNode, DBSAXDocument currentDocument) {
52

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

    
83
      // Bind the values to the query
84
      long nid = generateNodeID();
85
      pstmt.setLong(1, nid);
86
      pstmt.setString(2, nodetype);
87
      pstmt.setString(3, nodename);
88
      if (nodetype != "DOCUMENT") {
89
        if (nodetype == "ELEMENT") {
90
          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
        } else {
96
          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
        }
102
      }
103
      // Do the insertion
104
      pstmt.execute();
105
      pstmt.close();
106
      
107
      if (nodetype.equals("DOCUMENT") || nodetype.equals("ELEMENT")) {
108

    
109
        // Record the node id that was generated from the database
110
        setNodeID(nid);
111

    
112
        // Record the node type that was passed to the method
113
        setNodeType(nodetype);
114

    
115
      }
116

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

    
125
  /** 
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

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

    
147
  /** 
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
   * creates SQL code to put doc ID for the document node and for 
170
   * comment/PI nodes under document node into DB connection 
171
   */
172
  public void writeDocID(String doc_id) {
173
      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
        pstmt.setString(1, doc_id);
181
        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
        pstmt.setString(1, doc_id);
192
        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
      }   
199
  }
200

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

    
218
      return nid;
219
  }
220

    
221
  /** Add a new attribute to this node, or set its value */
222
  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

    
227
      // And enter the attribute in the database
228
      writeChildNodeToDB("ATTRIBUTE", attName, attValue);
229
    } else {
230
      System.err.println("Attribute name must not be null!");
231
    }
232
  }
233

    
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
}
301

    
302
/**
303
 * '$Log$
304
 * '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
 * '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
 */
(11-11/20)