Project

General

Profile

« Previous | Next » 

Revision 388

Added by Matt Jones over 23 years ago

Modified the DBReader and ElementNode classes to more efficiently read
documents from the database. In the old implementation, a db connection
was opened for each and every node in a document, recursively fromthe root
node. In the new implementation, all of the data from xml_nodes is
retrieved from the database with a single query and stored in a
sorted list of NodeRecord, and the node tree is build from this data structure
recursively. This should speed up the document retieval substantially,
especially as the document repository grows.

View differences:

ElementNode.java
16 16

  
17 17
import java.sql.*;
18 18
import java.io.IOException;
19
import java.util.Enumeration;
20
import java.util.Iterator;
21
import java.util.TreeSet;
19 22
import java.util.Vector;
20
import java.util.Enumeration;
21 23

  
22 24
/**
23 25
 * A Class that represents an XML element and its contents,
......
25 27
 */
26 28
public class ElementNode extends BasicNode {
27 29

  
28
    private Connection	conn;
30
  /** 
31
   * Construct a new ElementNode instance, and recursively create its children
32
   *
33
   * @param nodeRecordList the nodedata to use to initialize, which is a
34
   *        TreeSet of NodeRecord objects
35
   * @param nodeid the identifier for the node to be created
36
   */
37
  public ElementNode (TreeSet nodeRecordList, long nodeid) {
29 38

  
30
    /** 
31
     * Construct a new ElementNode instance
32
     *
33
     * @param conn the database connection to use to initialize 
34
     */
35
    public ElementNode (Connection conn) {
36
      this.conn = conn;
37
    }
39
    MetaCatUtil util = new MetaCatUtil();
38 40

  
39
    /** 
40
     * Construct a new ElementNode instance
41
     *
42
     * @param conn the database connection to use to initialize 
43
     * @param nodeid the element_id for the node to be created
44
     */
45
    public ElementNode (Connection conn, long nodeid) {
46
      this(conn);
41
    // Step through all of the node records we were given
42
    Iterator it = nodeRecordList.iterator();
43
    while (it.hasNext()) {
44
      NodeRecord currentNode = (NodeRecord)it.next();
45
      if (currentNode.nodeid == nodeid) {
46
        util.debugMessage("Got Node ID: " + currentNode.nodeid +
47
                          " (" + currentNode.parentnodeid +
48
                          ", " + currentNode.nodeindex + 
49
                          ", " + currentNode.nodetype + ")");
50
        // Process the current node
51
        setNodeType(currentNode.nodetype);
52
        setNodeID(currentNode.nodeid);
53
        setParentID(currentNode.parentnodeid);
54
        setTagName(currentNode.nodename);
55
      } else {
56
        // Process the children nodes
57
        if (currentNode.parentnodeid == getNodeID()) {
58
          util.debugMessage("  Processing child: " + currentNode.nodeid +
59
                          " (" + currentNode.parentnodeid +
60
                          ", " + currentNode.nodeindex + 
61
                          ", " + currentNode.nodetype + ")");
47 62

  
48
      //Lookup data for self
49
      setElementInfo(nodeid);
50
      
51
      //Create child nodes (elements or attributes)
52
      setChildrenNodes(nodeid);
53
    }
63
          if ((currentNode.nodetype).equals("ELEMENT")) {
64
            util.debugMessage("Creating child node: " + currentNode.nodeid);
65
            ElementNode child = new ElementNode(nodeRecordList,
66
                                                currentNode.nodeid);
67
            addChildNode(child);
68
          } else if (currentNode.nodetype.equals("ATTRIBUTE")) {
69
            setAttribute(currentNode.nodename,currentNode.nodedata);
70
          } else if (currentNode.nodetype.equals("TEXT")) {
71
            TextNode child = new TextNode(currentNode.nodeid,
72
                                          currentNode.parentnodeid,
73
                                          currentNode.nodedata);
74
            addChildNode(child);
75
          } else if (currentNode.nodetype.equals("COMMENT")) {
76
            CommentNode child = new CommentNode(currentNode.nodeid,
77
                                                currentNode.parentnodeid,
78
                                                currentNode.nodedata);
79
            addChildNode(child);
80
          } else if (currentNode.nodetype.equals("PI")) {
81
            PINode child = new PINode(currentNode.nodeid,
82
                                      currentNode.parentnodeid,
83
                                      currentNode.nodename,
84
                                      currentNode.nodedata);
85
            addChildNode(child);
86
          }
54 87

  
55
    /** 
56
     * Construct a new ElementNode instance
57
     *
58
     * @param conn the database connection to use to initialize 
59
     * @param nodeid the element_id for the node to be created
60
     * @param parentnodeid the id of the parent node
61
     * @param nodename the name of the element
62
     */
63
    public ElementNode (Connection conn, long nodeid, long parentnodeid,
64
                          String nodename, String nodetype) {
65
      this(conn);
66
      setNodeID(nodeid);
67
      setParentID(parentnodeid);
68
      setTagName(nodename);
69
      setNodeType(nodetype);
70

  
71
      
72
      // Create child nodes (elements or attributes)
73
      setChildrenNodes(nodeid);
74
    }
75

  
76
    /** Look up the info needed to construct this element from the DB */
77
    private void setElementInfo(long nodeid) {
78
      long element_id=0;
79
      long parentnodeid=0;
80
      String nodetype=null;
81
      String nodename=null;
82
      String nodedata=null;
83

  
84
      PreparedStatement pstmt;
85
      try {
86
        pstmt =
87
          conn.prepareStatement("SELECT nodeid,parentnodeid,nodetype,nodename,"+
88
               "replace(" +
89
               "replace(" +
90
               "replace(nodedata,'&','&') " +
91
               ",'<','&lt;') " +
92
               ",'>','&gt;') " +
93
               "FROM xml_nodes WHERE nodeid = ?");
94
        // Bind the values to the query
95
        pstmt.setLong(1, nodeid);
96

  
97
        pstmt.execute();
98
        try {
99
          ResultSet rs = pstmt.getResultSet();
100
          try {
101
            boolean tableHasRows = rs.next();
102
            if (tableHasRows) {
103
              try {
104
                element_id = rs.getLong(1);
105
                parentnodeid = rs.getLong(2);
106
                nodetype = rs.getString(3);
107
                nodename = rs.getString(4);
108
                nodedata = rs.getString(5);
109
              } catch (SQLException e) {
110
                System.out.println("Error with getInt: " + e.getMessage());
111
              }
112
            } else {
113
              System.err.println("Error: no rows for nodeid: " + nodeid);
114
            }
115
          } catch (SQLException e) {
116
            System.out.println("Error with next: " + e.getMessage());
117
          }
118
        } catch (SQLException e) {
119
          System.out.println("Error with getrset: " + e.getMessage());
88
        } else {
89
          util.debugMessage("  Discarding child: " + currentNode.nodeid +
90
                          " (" + currentNode.parentnodeid +
91
                          ", " + currentNode.nodeindex +
92
                          ", " + currentNode.nodetype + ")");
120 93
        }
121
        pstmt.close();
122
      } catch (SQLException e) {
123
        System.out.println("Error getting id: " + e.getMessage());
124 94
      }
125

  
126
      // Record our node type
127
      setNodeType(nodetype);
128

  
129
      try {
130
      if (nodetype.equals("ELEMENT") || nodetype.equals("DOCUMENT") ) {
131
        setNodeID(element_id);
132
        setParentID(parentnodeid);
133
        setTagName(nodename);
134
      }
135
      } catch (NullPointerException npe) {
136
        System.err.println("Error with nodetype: " + 
137
                           nodetype + npe.getMessage());
138
        System.err.println("Nodeid: " + element_id);
139
      } 
140 95
    }
96
  }
141 97

  
142
    /** Look up each child node from the DB and and create it */
143
    private void setChildrenNodes(long nodeid) {
144
      long element_id=0;
145
      long parentnodeid=0;
146
      String nodetype=null;
147
      String nodename=null;
148
      String nodedata=null;
98
  /** 
99
   * String representation for display purposes (recursively descends through
100
   * children to create an XML subtree)
101
   */
102
  public String toString () {
149 103

  
150
      PreparedStatement pstmt;
151
      try {
152
        pstmt =
153
          conn.prepareStatement("SELECT nodeid,parentnodeid,nodetype, " +
154
                  "nodename, " +
155
                  "replace(" +
156
                  "replace(" +
157
                  "replace(nodedata,'&','&amp;')" +
158
                  ",'<','&lt;') " +
159
                  ",'>','&gt;') " +
160
                  "FROM xml_nodes WHERE parentnodeid = ? " +
161
                  "ORDER BY nodeindex");
104
    StringBuffer value = new StringBuffer();
105
    String nodetype = getNodeType();
162 106

  
163
        // Bind the values to the query
164
        pstmt.setLong(1, nodeid);
107
    if (nodetype.equals("ELEMENT")) {
108
      value.append('<');
109
      value.append(getTagName());
110
      value.append(getAttributes().toString());
111
      value.append('>');
112
    } 
165 113

  
166
        pstmt.execute();
167
        try {
168
          ResultSet rs = pstmt.getResultSet();
169
          try {
170
            boolean tableHasRows = rs.next();
171
            while (tableHasRows) {
172
              try {
173
                element_id = rs.getLong(1);
174
                parentnodeid = rs.getLong(2);
175
                nodetype = rs.getString(3);
176
                nodename = rs.getString(4);
177
                nodedata = rs.getString(5);
114
    // Process children recursively here
115
    BasicNode child = null;
116
    Enumeration e = getChildren();
117
    while (e.hasMoreElements()) {
118
      child = (BasicNode)e.nextElement(); 
119
      value.append(child);
120
    }
178 121

  
179
                if ( (nodetype.equals("ELEMENT")) ||
180
                     (nodetype.equals("DOCUMENT"))
181
                   ) {
182
                  ElementNode child = new ElementNode(conn,
183
                                element_id,parentnodeid,nodename, nodetype);
184
                  addChildNode(child);
185
                } else if (nodetype.equals("ATTRIBUTE")) {
186
                  setAttribute(nodename,nodedata);
187
                } else if (nodetype.equals("TEXT")) {
188
                  TextNode child = new TextNode(element_id,parentnodeid,
189
                                                nodedata);
190
                  addChildNode(child);
191
                } else if (nodetype.equals("COMMENT")) {
192
                  CommentNode child = new CommentNode(element_id,parentnodeid,
193
                                                nodedata);
194
                  addChildNode(child);
195
                } else if (nodetype.equals("PI")) {
196
                  PINode child = new PINode(element_id,parentnodeid,nodename,
197
                                                nodedata);
198
                  addChildNode(child);
199
                } 
200

  
201
              } catch (SQLException e) {
202
                System.out.println("Error with getInt: " + e.getMessage());
203
              }
204

  
205
              // Advance to the next record in the cursor
206
              tableHasRows = rs.next();
207
            }
208
          } catch (SQLException e) {
209
            System.out.println("Error with next: " + e.getMessage());
210
          }
211
        } catch (SQLException e) {
212
          System.out.println("Error with getrset: " + e.getMessage());
213
        }
214
        pstmt.close();
215
      } catch (SQLException e) {
216
        System.out.println("Error getting id: " + e.getMessage());
217
      }
218

  
122
    if (nodetype.equals("ELEMENT")) {
123
      value.append("</");
124
      value.append(getTagName());
125
      value.append('>');
219 126
    }
220 127

  
221
    /** 
222
     * String representation for display purposes (recursively descends through
223
     * children to create an XML subtree)
224
     */
225
    public String toString () {
226

  
227
        StringBuffer value = new StringBuffer();
228
        String nodetype = getNodeType();
229

  
230
        if (nodetype.equals("ELEMENT")) {
231
          value.append('<');
232
          value.append(getTagName());
233
          value.append(getAttributes().toString());
234
          value.append('>');
235
        } 
236

  
237
        // Process children recursively here
238
        BasicNode child = null;
239
        Enumeration e = getChildren();
240
        while (e.hasMoreElements()) {
241
          child = (BasicNode)e.nextElement(); 
242
          value.append(child);
243
        }
244

  
245
        if (nodetype.equals("ELEMENT")) {
246
          value.append("</");
247
          value.append(getTagName());
248
          value.append('>');
249
        }
250

  
251
        return value.toString();
252
    }
128
    return value.toString();
129
  }
253 130
}
254

  
255
/**
256
 * '$Log$
257
 * 'Revision 1.21  2000/06/28 02:36:26  jones
258
 * 'Added feature to now ouput COMMENTs and PIs when the document is
259
 * 'read from the database with DBReader.
260
 * '
261
 * 'Revision 1.20  2000/06/26 10:35:05  jones
262
 * 'Merged in substantial changes to DBWriter and associated classes and to
263
 * 'the MetaCatServlet in order to accomodate the new UPDATE and DELETE
264
 * 'functions.  The command line tools and the parameters for the
265
 * 'servlet have changed substantially.
266
 * '
267
 * 'Revision 1.19.2.2  2000/06/25 23:38:16  jones
268
 * 'Added RCSfile keyword
269
 * '
270
 * 'Revision 1.19.2.1  2000/06/25 23:34:18  jones
271
 * 'Changed documentation formatting, added log entries at bottom of source files
272
 * ''
273
 */

Also available in: Unified diff