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: 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 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
    /**
134
     * Get the document title
135
     */
136
    public String getTitle() {
137
      return doctitle;
138
    }
139

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

    
154
        // Bind the values to the query
155
        pstmt.setString(1, doctitle);
156
        pstmt.setString(2, docid);
157

    
158
        // Do the insertion
159
        pstmt.execute();
160
        pstmt.close();
161
      } catch (SQLException e) {
162
        System.out.println(e.getMessage());
163
      }
164
    }
165

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

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

    
203
          // Bind the values to the query
204
          pstmt.setLong(1, rootnodeid);
205
          pstmt.setLong(2, rootnodeid);
206

    
207
          pstmt.execute();
208
          ResultSet rs = pstmt.getResultSet();
209
          boolean tableHasRows = rs.next();
210
          if (tableHasRows) {
211
            title = rs.getString(1);
212
          }
213
          pstmt.close();
214
        } catch (SQLException e) {
215
          System.out.println("Error getting id: " + e.getMessage());
216
        }
217

    
218
        // assign the new title
219
        this.setTitle(title);
220
    }
221

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

    
238
    ResultSet rs = pstmt.getResultSet();
239
    boolean tableHasRows = rs.next();
240
    if (tableHasRows) {
241
      rnodeid      = rs.getLong(1);
242
      docname      = rs.getString(2);
243
      doctype      = rs.getString(3);
244
      doctitle     = rs.getString(4);
245
      date_created = rs.getDate(5);
246
    }
247
    pstmt.close();
248

    
249
    MetaCatUtil.debugMessage(new Long(rnodeid).toString());
250
    MetaCatUtil.debugMessage(docname);
251
    MetaCatUtil.debugMessage(doctitle);
252
    //MetaCatUtil.debugMessage(date_created.toString());
253

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

    
272
/**
273
 * '$Log$
274
 * 'Revision 1.14  2000/06/26 10:35:05  jones
275
 * 'Merged in substantial changes to DBWriter and associated classes and to
276
 * 'the MetaCatServlet in order to accomodate the new UPDATE and DELETE
277
 * 'functions.  The command line tools and the parameters for the
278
 * 'servlet have changed substantially.
279
 * '
280
 * 'Revision 1.13.2.8  2000/06/26 08:38:02  jones
281
 * 'Added DELETE feature to DBWriter.  Now takes an action "DELETE" and a
282
 * 'docid and will move the record from the xml_documents table to the
283
 * 'xml_revisions table.
284
 * 'Modified option parsing to support option symbols on command line.
285
 * '
286
 * 'Revision 1.13.2.7  2000/06/26 03:04:31  jones
287
 * 'Completed UPDATE function.  Included new table "xml_revisions" to store a
288
 * 'single document record for each revision to a document.  It is identical
289
 * 'to "xml_documents" with the addition of a "revisionid" column to
290
 * 'allow more than one revision per docid.
291
 * '
292
 * 'Revision 1.13.2.6  2000/06/26 02:02:20  jones
293
 * 'Continued fixing problems with exception handling that deals
294
 * 'with INSERT and UPDATE actions and the docid passed to DBWriter
295
 * '
296
 * 'Revision 1.13.2.5  2000/06/25 23:38:16  jones
297
 * 'Added RCSfile keyword
298
 * '
299
 * 'Revision 1.13.2.4  2000/06/25 23:34:17  jones
300
 * 'Changed documentation formatting, added log entries at bottom of source files
301
 * ''
302
 */
(9-9/20)