Project

General

Profile

1 72 bojilova
/**
2 203 jones
 *  '$RCSfile$'
3
 *    Purpose: A Class that writes an XML document main data
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Jivka Bojilova, Matt Jones
7 72 bojilova
 *
8 203 jones
 *   '$Author$'
9
 *     '$Date$'
10
 * '$Revision$'
11 72 bojilova
 */
12
13 75 jones
package edu.ucsb.nceas.metacat;
14 72 bojilova
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 writes an XML document main data to a database connection
22
 */
23
public class DBSAXDocument {
24
25 142 jones
    private Connection      conn;
26 72 bojilova
    private long            rootnodeid;
27
    private String          docname;
28
    private String          doctype;
29 142 jones
    private String          doctitle;
30 161 bojilova
    private String          docid;
31 72 bojilova
32
    /**
33
     * Construct a new document instance
34
     *
35
     * @param conn the JDBC Connection to which all information is written
36
     * @param rootnodeid - sequence id of the root node in the document
37 122 jones
     * @param docname - the name of DTD, i.e. the name immediately following
38 148 bojilova
     *        the DOCTYPE keyword ( should be the root element name ) or
39
     *        the root element name if no DOCTYPE declaration provided
40 122 jones
     *        (Oracle's and IBM parsers are not aware if it is not the
41
     *        root element name)
42
     * @param doctype - Public ID of the DTD, i.e. the name immediately
43 148 bojilova
     *                  following the PUBLIC keyword in DOCTYPE declaration or
44
     *                  the docname if no Public ID provided or
45
     *                  null if no DOCTYPE declaration provided
46 72 bojilova
     *
47
     */
48 122 jones
    public DBSAXDocument (Connection conn, long rootnodeid, String docname,
49 203 jones
                          String doctype, String docid, String action)
50
                          throws AccessionNumberException {
51 72 bojilova
      this.conn = conn;
52
      this.rootnodeid = rootnodeid;
53
      this.docname = docname;
54
      this.doctype = doctype;
55 203 jones
      this.docid = docid;
56
      writeDocumentToDB(action);
57 72 bojilova
    }
58
59 203 jones
    /**
60
     * Construct a new document instance, used for deleting documents
61
     *
62
     * @param conn the JDBC Connection to which all information is written
63
     */
64
    public DBSAXDocument (Connection conn) {
65
      this.conn = conn;
66
    }
67
68 72 bojilova
    /** creates SQL code and inserts new document into DB connection */
69 203 jones
    private void writeDocumentToDB(String action)
70
                          throws AccessionNumberException {
71 72 bojilova
        try {
72 203 jones
          PreparedStatement pstmt = null;
73
74
          if (action.equals("INSERT")) {
75
            this.docid = AccessionNumber.generate(docid, "INSERT");
76
            pstmt = conn.prepareStatement(
77 122 jones
                "INSERT INTO xml_documents " +
78 203 jones
                "(docid, rootnodeid, docname, doctype, " +
79
                "date_created, date_updated) " +
80
                "VALUES (?, ?, ?, ?, sysdate, sysdate)");
81
            // Bind the values to the query
82
            pstmt.setString(1, this.docid);
83
            pstmt.setLong(2, rootnodeid);
84
            pstmt.setString(3, docname);
85
            pstmt.setString(4, doctype);
86
          } else if (action.equals("UPDATE")) {
87 72 bojilova
88 203 jones
            // Determine if the docid is OK for an UPDATE
89
            this.docid = AccessionNumber.generate(docid, "UPDATE");
90
91
            // Save the old document entry in a backup table
92
            saveDocument(docid);
93
94
            // Update the new document to reflect the new node tree
95
            pstmt = conn.prepareStatement(
96
                "UPDATE xml_documents " +
97
                "SET rootnodeid = ?, docname = ?, doctype = ?, " +
98
                "date_updated = sysdate WHERE docid LIKE ?");
99
            // Bind the values to the query
100
            pstmt.setLong(1, rootnodeid);
101
            pstmt.setString(2, docname);
102
            pstmt.setString(3, doctype);
103
            pstmt.setString(4, this.docid);
104
          } else {
105
            System.err.println("Action not supported: " + action);
106
          }
107
108 72 bojilova
          // Do the insertion
109
          pstmt.execute();
110
          pstmt.close();
111 203 jones
112 72 bojilova
        } catch (SQLException e) {
113
          System.out.println(e.getMessage());
114 203 jones
        } catch (AccessionNumberException ane) {
115
          MetaCatUtil.debugMessage("Invalid accession number.");
116
          MetaCatUtil.debugMessage(ane.getMessage());
117
          throw ane;
118 161 bojilova
        } catch (Exception e) {
119
          System.out.println(e.getMessage());
120 72 bojilova
        }
121
    }
122
123 152 bojilova
    /** Get doc id */
124 161 bojilova
    public String getDocID() {
125 152 bojilova
      return docid;
126 149 bojilova
    }
127
128 142 jones
    /**
129
     * Get the document title
130
     */
131
    public String getTitle() {
132
      return doctitle;
133
    }
134
135
    /**
136
     * Set the document title
137
     *
138
     * @param title the new title for the document
139
     */
140
    public void setTitle( String title ) {
141
      this.doctitle = title;
142
      try {
143
        PreparedStatement pstmt;
144
        pstmt = conn.prepareStatement(
145
              "UPDATE xml_documents " +
146
              " SET doctitle = ? " +
147
              "WHERE docid = ?");
148
149
        // Bind the values to the query
150
        pstmt.setString(1, doctitle);
151 161 bojilova
        pstmt.setString(2, docid);
152 142 jones
153
        // Do the insertion
154
        pstmt.execute();
155
        pstmt.close();
156
      } catch (SQLException e) {
157
        System.out.println(e.getMessage());
158
      }
159
    }
160
161
    /**
162
     * Look up the title of the first child element named "title"
163
     * and record it as the document title
164
     */
165
    public void setTitleFromChildElement() {
166
        String title = null;
167
        long assigned_id=0;
168
        PreparedStatement pstmt;
169
        try {
170
          pstmt = conn.prepareStatement(
171
                  "SELECT nodedata FROM xml_nodes " +
172
                  "WHERE nodetype = 'TEXT' " +
173 150 jones
                  "AND rootnodeid = ? " +
174 142 jones
                  "AND parentnodeid IN " +
175 150 jones
                  "  (SELECT nodeid FROM xml_nodes " +
176
                  "  WHERE nodename = 'title' " +
177
                  "  AND nodetype =  'ELEMENT' " +
178
                  "  AND rootnodeid = ? ) " +
179
                  "ORDER BY nodeid");
180
181
          // The above query might be slow, and probably will be because
182
          // it gets ALL of the title elements while searching for one
183
          // title in a small subtree but it avoids the problem of using
184
          // Oracle's Hierarchical Query syntax which is not portable --
185
          // the commented out SQL that follows shows an equivalent query
186
          // using Oracle-specific hierarchical query
187
/*
188
          pstmt = conn.prepareStatement(
189
                  "SELECT nodedata FROM xml_nodes " +
190
                  "WHERE nodetype = 'TEXT' " +
191
                  "AND parentnodeid IN " +
192 142 jones
                  "(SELECT nodeid FROM xml_nodes " +
193
                  "WHERE nodename = 'title' " +
194
                  "START WITH nodeid = ? " +
195
                  "CONNECT BY PRIOR nodeid = parentnodeid)");
196
*/
197
198
          // Bind the values to the query
199
          pstmt.setLong(1, rootnodeid);
200 150 jones
          pstmt.setLong(2, rootnodeid);
201 142 jones
202
          pstmt.execute();
203
          ResultSet rs = pstmt.getResultSet();
204
          boolean tableHasRows = rs.next();
205
          if (tableHasRows) {
206
            title = rs.getString(1);
207
          }
208
          pstmt.close();
209
        } catch (SQLException e) {
210
          System.out.println("Error getting id: " + e.getMessage());
211
        }
212
213
        // assign the new title
214
        this.setTitle(title);
215
    }
216 203 jones
217
  /** Save a document entry in the xml_revisions table */
218
  public void saveDocument(String docid) throws SQLException {
219
    // First get all of the values we need
220
    long rnodeid = -1;
221
    String docname = null;
222
    String doctype = null;
223
    String doctitle = null;
224
    Date date_created = null;
225
    PreparedStatement pstmt = conn.prepareStatement(
226
       "SELECT rootnodeid, docname, doctype, doctitle, date_created " +
227
       "FROM xml_documents " +
228
       "WHERE docid = ?");
229
    // Bind the values to the query and execute it
230
    pstmt.setString(1, docid);
231
    pstmt.execute();
232
233
    ResultSet rs = pstmt.getResultSet();
234
    boolean tableHasRows = rs.next();
235
    if (tableHasRows) {
236
      rnodeid      = rs.getLong(1);
237
      docname      = rs.getString(2);
238
      doctype      = rs.getString(3);
239
      doctitle     = rs.getString(4);
240
      date_created = rs.getDate(5);
241
    }
242
    pstmt.close();
243
244
    MetaCatUtil.debugMessage(new Long(rnodeid).toString());
245
    MetaCatUtil.debugMessage(docname);
246
    MetaCatUtil.debugMessage(doctitle);
247
    //MetaCatUtil.debugMessage(date_created.toString());
248
249
    // Next create the new record in the other table using the values selected
250
    pstmt = conn.prepareStatement(
251
       "INSERT INTO xml_revisions " +
252
       "(revisionid, docid, rootnodeid, docname, doctype, doctitle, " +
253
       "date_created, date_updated) " +
254
       "VALUES (null, ?, ?, ?, ?, ?, sysdate, sysdate)");
255
    // Bind the values to the query and execute it
256
    pstmt.setString(1, docid);
257
    pstmt.setLong(2, rnodeid);
258
    pstmt.setString(3, docname);
259
    pstmt.setString(4, doctype);
260
    pstmt.setString(5, doctitle);
261
    //pstmt.setDate(6, date_created);
262
    pstmt.execute();
263
    pstmt.close();
264
  }
265 72 bojilova
}
266 203 jones
267
/**
268
 * '$Log$
269
 * 'Revision 1.13.2.8  2000/06/26 08:38:02  jones
270
 * 'Added DELETE feature to DBWriter.  Now takes an action "DELETE" and a
271
 * 'docid and will move the record from the xml_documents table to the
272
 * 'xml_revisions table.
273
 * 'Modified option parsing to support option symbols on command line.
274
 * '
275
 * 'Revision 1.13.2.7  2000/06/26 03:04:31  jones
276
 * 'Completed UPDATE function.  Included new table "xml_revisions" to store a
277
 * 'single document record for each revision to a document.  It is identical
278
 * 'to "xml_documents" with the addition of a "revisionid" column to
279
 * 'allow more than one revision per docid.
280
 * '
281
 * 'Revision 1.13.2.6  2000/06/26 02:02:20  jones
282
 * 'Continued fixing problems with exception handling that deals
283
 * 'with INSERT and UPDATE actions and the docid passed to DBWriter
284
 * '
285
 * 'Revision 1.13.2.5  2000/06/25 23:38:16  jones
286
 * 'Added RCSfile keyword
287
 * '
288
 * 'Revision 1.13.2.4  2000/06/25 23:34:17  jones
289
 * 'Changed documentation formatting, added log entries at bottom of source files
290
 * ''
291
 */