Project

General

Profile

1
/**
2
 *  '$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
 *
8
 *   '$Author: bojilova $'
9
 *     '$Date: 2000-08-03 16:15:11 -0700 (Thu, 03 Aug 2000) $'
10
 * '$Revision: 312 $'
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 writes an XML document main data to a database connection
22
 */
23
public class DBSAXDocument {
24

    
25
    private Connection      conn;
26
    private long            rootnodeid;
27
    private String          docname;
28
    private String          doctype;
29
    private String          doctitle;
30
    private String          docid;
31

    
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
     * @param docname - the name of DTD, i.e. the name immediately following 
38
     *        the DOCTYPE keyword ( should be the root element name ) or
39
     *        the root element name if no DOCTYPE declaration provided
40
     *        (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
     *                  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
     *
47
     */
48
    public DBSAXDocument (Connection conn, long rootnodeid, String docname, 
49
                          String doctype, String docid, String action)
50
                          throws AccessionNumberException {
51
      this.conn = conn;
52
      this.rootnodeid = rootnodeid;
53
      this.docname = docname;
54
      this.doctype = doctype;
55
      this.docid = docid;
56
      writeDocumentToDB(action);
57
    }
58
    
59
    /** 
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
    /** creates SQL code and inserts new document into DB connection */
69
    private void writeDocumentToDB(String action) 
70
                          throws AccessionNumberException {
71
        try {
72
          PreparedStatement pstmt = null;
73

    
74
          if (action.equals("INSERT")) {
75
            this.docid = AccessionNumber.generate(docid, "INSERT");
76
            pstmt = conn.prepareStatement(
77
                "INSERT INTO xml_documents " +
78
                "(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

    
88
            // 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
          // Do the insertion
109
          pstmt.execute();
110
          pstmt.close();
111

    
112
        } catch (SQLException e) {
113
          System.out.println(e.getMessage());
114
        } catch (AccessionNumberException ane) {
115
          MetaCatUtil.debugMessage("Invalid accession number.");
116
          MetaCatUtil.debugMessage(ane.getMessage());
117
          throw ane;
118
        } catch (Exception e) {
119
          System.out.println(e.getMessage());
120
        }
121
    }
122

    
123
    /** Get doctype */
124
    public String getDoctype() {
125
      return doctype;
126
    }
127

    
128
    /** Get doc id */
129
    public String getDocID() {
130
      return docid;
131
    }
132

    
133
    /** Get root node id */
134
    public long getRootNodeID() {
135
      return rootnodeid;
136
    }
137

    
138
    /**
139
     * Get the document title
140
     */
141
    public String getTitle() {
142
      return doctitle;
143
    }
144

    
145
    /**
146
     * Set the document title
147
     *
148
     * @param title the new title for the document
149
     */
150
    public void setTitle( String title ) {
151
      this.doctitle = title;
152
      try {
153
        PreparedStatement pstmt;
154
        pstmt = conn.prepareStatement(
155
              "UPDATE xml_documents " +
156
              " SET doctitle = ? " +
157
              "WHERE docid = ?");
158

    
159
        // Bind the values to the query
160
        pstmt.setString(1, doctitle);
161
        pstmt.setString(2, docid);
162

    
163
        // Do the insertion
164
        pstmt.execute();
165
        pstmt.close();
166
      } catch (SQLException e) {
167
        System.out.println(e.getMessage());
168
      }
169
    }
170

    
171
    /**
172
     * Look up the title of the first child element named "title"
173
     * and record it as the document title
174
     */
175
    public void setTitleFromChildElement() {
176
        String title = null;
177
        long assigned_id=0;
178
        PreparedStatement pstmt;
179
        try {
180
          pstmt = conn.prepareStatement(
181
                  "SELECT nodedata FROM xml_nodes " +
182
                  "WHERE nodetype = 'TEXT' " +
183
                  "AND rootnodeid = ? " +
184
                  "AND parentnodeid IN " +
185
                  "  (SELECT nodeid FROM xml_nodes " +
186
                  "  WHERE nodename = 'title' " +
187
                  "  AND nodetype =  'ELEMENT' " +
188
                  "  AND rootnodeid = ? ) " +
189
                  "ORDER BY nodeid");
190

    
191
          // The above query might be slow, and probably will be because
192
          // it gets ALL of the title elements while searching for one
193
          // title in a small subtree but it avoids the problem of using
194
          // Oracle's Hierarchical Query syntax which is not portable --
195
          // the commented out SQL that follows shows an equivalent query
196
          // using Oracle-specific hierarchical query
197
/*
198
          pstmt = conn.prepareStatement(
199
                  "SELECT nodedata FROM xml_nodes " +
200
                  "WHERE nodetype = 'TEXT' " +
201
                  "AND parentnodeid IN " +
202
                  "(SELECT nodeid FROM xml_nodes " +
203
                  "WHERE nodename = 'title' " +
204
                  "START WITH nodeid = ? " +
205
                  "CONNECT BY PRIOR nodeid = parentnodeid)");
206
*/
207

    
208
          // Bind the values to the query
209
          pstmt.setLong(1, rootnodeid);
210
          pstmt.setLong(2, rootnodeid);
211

    
212
          pstmt.execute();
213
          ResultSet rs = pstmt.getResultSet();
214
          boolean tableHasRows = rs.next();
215
          if (tableHasRows) {
216
            title = rs.getString(1);
217
          }
218
          pstmt.close();
219
        } catch (SQLException e) {
220
          System.out.println("Error getting id: " + e.getMessage());
221
        }
222

    
223
        // assign the new title
224
        this.setTitle(title);
225
    }
226

    
227
  /** Save a document entry in the xml_revisions table */
228
  public void saveDocument(String docid) throws SQLException {
229
    // First get all of the values we need
230
    long rnodeid = -1;
231
    String docname = null;
232
    String doctype = null;
233
    String doctitle = null;
234
    Date date_created = null;
235
    PreparedStatement pstmt = conn.prepareStatement(
236
       "SELECT rootnodeid, docname, doctype, doctitle, date_created " +
237
       "FROM xml_documents " +
238
       "WHERE docid = ?");
239
    // Bind the values to the query and execute it
240
    pstmt.setString(1, docid);
241
    pstmt.execute();
242

    
243
    ResultSet rs = pstmt.getResultSet();
244
    boolean tableHasRows = rs.next();
245
    if (tableHasRows) {
246
      rnodeid      = rs.getLong(1);
247
      docname      = rs.getString(2);
248
      doctype      = rs.getString(3);
249
      doctitle     = rs.getString(4);
250
      date_created = rs.getDate(5);
251
    }
252
    pstmt.close();
253

    
254
    MetaCatUtil.debugMessage(new Long(rnodeid).toString());
255
    MetaCatUtil.debugMessage(docname);
256
    MetaCatUtil.debugMessage(doctitle);
257
    //MetaCatUtil.debugMessage(date_created.toString());
258

    
259
    // Next create the new record in the other table using the values selected
260
    pstmt = conn.prepareStatement(
261
       "INSERT INTO xml_revisions " +
262
       "(revisionid, docid, rootnodeid, docname, doctype, doctitle, " +
263
       "date_created, date_updated) " +
264
       "VALUES (null, ?, ?, ?, ?, ?, sysdate, sysdate)");
265
    // Bind the values to the query and execute it
266
    pstmt.setString(1, docid);
267
    pstmt.setLong(2, rnodeid);
268
    pstmt.setString(3, docname);
269
    pstmt.setString(4, doctype);
270
    pstmt.setString(5, doctitle);
271
    //pstmt.setDate(6, date_created);
272
    pstmt.execute();
273
    pstmt.close();
274
  }
275
}
276

    
277
/**
278
 * '$Log$
279
 * 'Revision 1.15  2000/06/27 04:31:07  jones
280
 * 'Fixed bugs associated with the new UPDATE and DELETE functions of
281
 * 'DBWriter.  There were problematic interactions between some static
282
 * 'variables used in DBEntityResolver and the way in which the
283
 * 'Servlet objects are re-used across multiple client invocations.
284
 * '
285
 * 'Generally cleaned up error reporting.  Now all errors and success
286
 * 'results are reported as XML documents from MetaCatServlet.  Need
287
 * 'to make the command line tools do the same.
288
 * '
289
 * 'Revision 1.14  2000/06/26 10:35:05  jones
290
 * 'Merged in substantial changes to DBWriter and associated classes and to
291
 * 'the MetaCatServlet in order to accomodate the new UPDATE and DELETE
292
 * 'functions.  The command line tools and the parameters for the
293
 * 'servlet have changed substantially.
294
 * '
295
 * 'Revision 1.13.2.8  2000/06/26 08:38:02  jones
296
 * 'Added DELETE feature to DBWriter.  Now takes an action "DELETE" and a
297
 * 'docid and will move the record from the xml_documents table to the
298
 * 'xml_revisions table.
299
 * 'Modified option parsing to support option symbols on command line.
300
 * '
301
 * 'Revision 1.13.2.7  2000/06/26 03:04:31  jones
302
 * 'Completed UPDATE function.  Included new table "xml_revisions" to store a
303
 * 'single document record for each revision to a document.  It is identical
304
 * 'to "xml_documents" with the addition of a "revisionid" column to
305
 * 'allow more than one revision per docid.
306
 * '
307
 * 'Revision 1.13.2.6  2000/06/26 02:02:20  jones
308
 * 'Continued fixing problems with exception handling that deals
309
 * 'with INSERT and UPDATE actions and the docid passed to DBWriter
310
 * '
311
 * 'Revision 1.13.2.5  2000/06/25 23:38:16  jones
312
 * 'Added RCSfile keyword
313
 * '
314
 * 'Revision 1.13.2.4  2000/06/25 23:34:17  jones
315
 * 'Changed documentation formatting, added log entries at bottom of source files
316
 * ''
317
 */
(10-10/25)