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-14 12:33:15 -0700 (Thu, 14 Sep 2000) $'
11
 * '$Revision: 452 $'
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

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

    
27
  private Connection	conn;
28
  private DBSAXNode	parentNode;
29

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

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

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

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

    
117
      if (nodetype.equals("DOCUMENT") || nodetype.equals("ELEMENT")) {
118

    
119
        // Record the node id that was generated from the database
120
        setNodeID(nid);
121

    
122
        // Record the node type that was passed to the method
123
        setNodeType(nodetype);
124

    
125
      }
126

    
127
    } catch (SQLException e) {
128
      System.err.println("Error inserting node: (" + nodetype + ", " +
129
                                                     nodename + ", " + 
130
                                                     data + ")" );
131
      System.err.println(e.getMessage());
132
    }
133
  }
134

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

    
146
        // Bind the values to the query
147
        pstmt.setString(1, nodename);
148
        pstmt.setLong(2, getNodeID());
149
        // Do the insertion
150
        pstmt.execute();
151
        pstmt.close();
152
      } catch (SQLException e) {
153
        System.out.println(e.getMessage());
154
      }
155
  }
156

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

    
168
        // Bind the values to the query
169
        pstmt.setString(1, doc_id);
170
        pstmt.setLong(2, getNodeID());
171
        // Do the insertion
172
        pstmt.execute();
173
        pstmt.close();
174

    
175
        // for comments and PI on the top
176
        pstmt = conn.prepareStatement(
177
              "UPDATE xml_nodes set docid = ? " +
178
              "WHERE parentnodeid = ?");
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
      } catch (SQLException e) {
186
        System.out.println(e.getMessage());
187
      }   
188
  }
189

    
190
  /** get next node id from DB connection */
191
  private long generateNodeID() {
192
      long nid=0;
193
      Statement stmt;
194
      try {
195
        stmt = conn.createStatement();
196
        stmt.execute("SELECT xml_nodes_id_seq.nextval FROM dual");
197
        ResultSet rs = stmt.getResultSet();
198
        boolean tableHasRows = rs.next();
199
        if (tableHasRows) {
200
          nid = rs.getLong(1);
201
        }
202
        stmt.close();
203
      } catch (SQLException e) {
204
        System.out.println("Error getting id: " + e.getMessage());
205
      }
206

    
207
      return nid;
208
  }
209

    
210
  /** Add a new attribute to this node, or set its value */
211
  public void setAttribute(String attName, String attValue) {
212
    if (attName != null) {
213
      // Enter the attribute in the hash table
214
      super.setAttribute(attName, attValue);
215

    
216
      // And enter the attribute in the database
217
      writeChildNodeToDB("ATTRIBUTE", attName, attValue);
218
    } else {
219
      System.err.println("Attribute name must not be null!");
220
    }
221
  }
222

    
223
  /** 
224
   * Update the node index (xml_index) for this node by generating
225
   * test strings that represent all of the relative and absolute
226
   * paths through the XML tree from document root to this node
227
   */
228
  private void updateNodeIndex(String docid, String doctype) {
229
    Hashtable pathlist = new Hashtable();
230
    boolean atStartingNode = true;
231
    boolean atRootDocumentNode = false;
232
    DBSAXNode nodePointer = this;
233
    StringBuffer currentPath = new StringBuffer();
234

    
235
    // Create a Hashtable of all of the paths to reach this node
236
    // including absolute paths and relative paths
237
    while (!atRootDocumentNode) {
238
      if (atStartingNode) {
239
        currentPath.insert(0, nodePointer.getTagName());
240
        pathlist.put(currentPath.toString(), new Long(getNodeID()));
241
        atStartingNode = false;
242
      } else {
243
        currentPath.insert(0, "/");
244
        currentPath.insert(0, nodePointer.getTagName());
245
        pathlist.put(currentPath.toString(), new Long(getNodeID()));
246
      }
247

    
248
      // advance to the next parent node
249
      nodePointer = nodePointer.getParentNode();
250

    
251
      // If we're at the DOCUMENT node (root of DOM tree), add
252
      // the root "/" to make the absolute path
253
      if (nodePointer.getNodeType().equals("DOCUMENT")) {
254
        currentPath.insert(0, "/");
255
        pathlist.put(currentPath.toString(), new Long(getNodeID()));
256
        atRootDocumentNode = true;
257
      } 
258
    }
259

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

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