Project

General

Profile

1 17 jones
/**
2 203 jones
 *  '$RCSfile$'
3
 *    Purpose: A Class that handles the SAX XML events as they
4
 *             are generated from XML documents
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Matt Jones, Jivka Bojilova
8 17 jones
 *
9 203 jones
 *   '$Author$'
10
 *     '$Date$'
11
 * '$Revision$'
12 17 jones
 */
13
14 75 jones
package edu.ucsb.nceas.metacat;
15 51 jones
16 17 jones
import java.sql.*;
17
import java.util.Stack;
18 18 jones
import java.util.EmptyStackException;
19 17 jones
20 185 jones
import org.xml.sax.Attributes;
21
import org.xml.sax.SAXException;
22 204 jones
import org.xml.sax.SAXParseException;
23 186 jones
import org.xml.sax.ext.DeclHandler;
24 185 jones
import org.xml.sax.ext.LexicalHandler;
25
import org.xml.sax.helpers.DefaultHandler;
26 17 jones
27 31 jones
/**
28
 * A database aware Class implementing callback bethods for the SAX parser to
29
 * call when processing the XML stream and generating events
30
 */
31 186 jones
public class DBSAXHandler extends DefaultHandler
32
                          implements LexicalHandler, DeclHandler {
33 17 jones
34 204 jones
   private boolean	atFirstElement;
35
   private String 	docname = null;
36 135 jones
   private String 	doctype;
37
   private String 	systemid;
38 17 jones
   private boolean 	stackCreated = false;
39 137 jones
   private Stack 	nodeStack;
40 17 jones
   private Connection	conn = null;
41 142 jones
   private DBSAXDocument currentDocument;
42 185 jones
   private DBSAXNode    rootNode;
43 203 jones
   private String       action = null;
44
   private String       docid = null;
45 17 jones
46 31 jones
   /** Construct an instance of the handler class
47
    *
48
    * @param conn the JDBC connection to which information is written
49
    */
50 122 jones
   public DBSAXHandler(Connection conn) {
51 185 jones
     this.conn = conn;
52 204 jones
     this.atFirstElement = true;
53 17 jones
54 185 jones
     // Create the stack for keeping track of node context
55
     // if it doesn't already exist
56
     if (!stackCreated) {
57
       nodeStack = new Stack();
58
       stackCreated = true;
59
     }
60 17 jones
   }
61
62 203 jones
   /** Construct an instance of the handler class
63
    *
64
    * @param conn the JDBC connection to which information is written
65
    */
66
   public DBSAXHandler(Connection conn, String action, String docid) {
67
     this(conn);
68
     this.action = action;
69
     this.docid = docid;
70
   }
71
72 72 bojilova
   /** SAX Handler that receives notification of beginning of the document */
73 122 jones
   public void startDocument() throws SAXException {
74 203 jones
     MetaCatUtil.debugMessage("start Document");
75
76 185 jones
     // Create the document node representation as root
77
     rootNode = new DBSAXNode(conn, docname);
78 204 jones
     MetaCatUtil.debugMessage("PRINTING DOCNAME FROM ROOTNODE: " +
79
                               rootNode.getTagName());
80 185 jones
     // Add the node to the stack, so that any text data can be
81
     // added as it is encountered
82
     nodeStack.push(rootNode);
83 72 bojilova
   }
84
85
   /** SAX Handler that receives notification of end of the document */
86 122 jones
   public void endDocument() throws SAXException {
87 185 jones
     currentDocument.setTitleFromChildElement();
88 203 jones
     MetaCatUtil.debugMessage("end Document");
89
     if ((docid != null) && (!docid.equals(currentDocument.getDocID()))) {
90
       throw (new SAXException("New document ID generated:",
91 204 jones
           new AccessionNumberGeneratedException(currentDocument.getDocID())));
92 203 jones
     } else {
93
       throw (new SAXException("New document ID generated:",
94 204 jones
           new AccessionNumberGeneratedException(currentDocument.getDocID())));
95 122 jones
     }
96 72 bojilova
   }
97
98 185 jones
   /** SAX Handler that is called at the start of each XML element */
99
   public void startElement(String uri, String localName,
100
                            String qName, Attributes atts)
101
               throws SAXException {
102 203 jones
     MetaCatUtil.debugMessage("Start ELEMENT " + localName);
103 72 bojilova
104 203 jones
     DBSAXNode parentNode = null;
105
     DBSAXNode currentNode = null;
106 17 jones
107 203 jones
     // Get a reference to the parent node for the id
108
     try {
109
       parentNode = (DBSAXNode)nodeStack.peek();
110
     } catch (EmptyStackException e) {
111
     }
112 18 jones
113 203 jones
     // Document representation that points to the root document node
114 204 jones
     if (atFirstElement) {
115
       atFirstElement = false;
116 203 jones
       // If no DOCTYPE declaration: docname = root element name
117
       if (docname == null) {
118
         docname = localName;
119 204 jones
         doctype = docname;
120
         MetaCatUtil.debugMessage("DOCNAME-a: " + docname);
121
         MetaCatUtil.debugMessage("DOCTYPE-a: " + doctype);
122 203 jones
       } else if (doctype == null) {
123 204 jones
         doctype = docname;
124
         //doctype = DBEntityResolver.doctype;
125
         MetaCatUtil.debugMessage("DOCTYPE-b: " + doctype);
126 203 jones
       }
127
       rootNode.writeNodename(docname);
128
       rootNode.writeRootNodeID(rootNode.getNodeID());
129
       try {
130
         currentDocument = new DBSAXDocument(conn, rootNode.getNodeID(),
131
                                           docname, doctype, docid, action);
132
         } catch (AccessionNumberException ane) {
133 204 jones
           throw (new SAXException("Error with " + action, ane));
134 203 jones
         }
135
       rootNode.writeDocID(currentDocument.getDocID());
136
     }
137 135 jones
138 203 jones
     // Create the current node representation
139
     currentNode = new DBSAXNode(conn, localName, parentNode,
140
                                 rootNode, currentDocument);
141 17 jones
142 203 jones
     // Add all of the attributes
143
     for (int i=0; i<atts.getLength(); i++) {
144
       currentNode.setAttribute(atts.getLocalName(i), atts.getValue(i));
145
     }
146 17 jones
147 203 jones
     // Add the node to the stack, so that any text data can be
148
     // added as it is encountered
149
     nodeStack.push(currentNode);
150
  }
151 17 jones
152 31 jones
   /** SAX Handler that is called for each XML text node */
153 122 jones
   public void characters(char[] cbuf, int start, int len) {
154 203 jones
     MetaCatUtil.debugMessage("CHARACTERS");
155 186 jones
     DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
156
     String data = new String(cbuf, start, len);
157 122 jones
158 186 jones
     // Write the content of the node to the database
159
     currentNode.writeChildNodeToDB("TEXT", null, data);
160 17 jones
   }
161
162 31 jones
   /**
163
    * SAX Handler that is called for each XML text node that is Ignorable
164
    * white space
165
    */
166 122 jones
   public void ignorableWhitespace(char[] cbuf, int start, int len) {
167 203 jones
     MetaCatUtil.debugMessage("IGNORABLEWHITESPACE");
168 17 jones
   }
169
170 122 jones
   /**
171
    * SAX Handler called once for each processing instruction found:
172
    * node that PI may occur before or after the root element.
173
    */
174
   public void processingInstruction(String target, String data)
175
          throws SAXException {
176 203 jones
     MetaCatUtil.debugMessage("PI");
177 186 jones
     DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
178
     currentNode.writeChildNodeToDB("PI", target, data);
179 92 bojilova
   }
180 72 bojilova
181 31 jones
   /** SAX Handler that is called at the end of each XML element */
182 185 jones
   public void endElement(String uri, String localName,
183
                          String qName) throws SAXException {
184 203 jones
     MetaCatUtil.debugMessage("End ELEMENT " + localName);
185 17 jones
186 185 jones
     // Get the node from the stack
187
     DBSAXNode currentNode = (DBSAXNode)nodeStack.pop();
188 17 jones
   }
189
190 185 jones
   //
191
   // the next section implements the LexicalHandler interface
192
   //
193
194
   /** SAX Handler that receives notification of DOCTYPE. Sets the DTD */
195
   public void startDTD(String name, String publicId, String systemId)
196
               throws SAXException {
197
     docname = name;
198
     doctype = publicId;
199
     systemid = systemId;
200
201 204 jones
     MetaCatUtil.debugMessage("Start DTD");
202 203 jones
     MetaCatUtil.debugMessage("DOCNAME: " + docname);
203
     MetaCatUtil.debugMessage("DOCTYPE: " + doctype);
204
     MetaCatUtil.debugMessage("  SYSID: " + systemid);
205 185 jones
   }
206
207
   /**
208
    * SAX Handler that receives notification of end of DTD
209
    */
210
   public void endDTD() throws SAXException {
211 204 jones
     MetaCatUtil.debugMessage("end DTD");
212 185 jones
   }
213
214
   /**
215
    * SAX Handler that receives notification of comments in the DTD
216
    */
217
   public void comment(char[] ch, int start, int length) throws SAXException {
218 203 jones
     MetaCatUtil.debugMessage("COMMENT");
219 186 jones
     DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
220
     currentNode.writeChildNodeToDB("COMMENT", null, new String(ch));
221 185 jones
   }
222
223
   /**
224
    * SAX Handler that receives notification of the start of CDATA sections
225
    */
226
   public void startCDATA() throws SAXException {
227 203 jones
     MetaCatUtil.debugMessage("start CDATA");
228 185 jones
   }
229
230
   /**
231
    * SAX Handler that receives notification of the end of CDATA sections
232
    */
233
   public void endCDATA() throws SAXException {
234 203 jones
     MetaCatUtil.debugMessage("end CDATA");
235 185 jones
   }
236
237
   /**
238
    * SAX Handler that receives notification of the start of entities
239
    */
240
   public void startEntity(String name) throws SAXException {
241 203 jones
     MetaCatUtil.debugMessage("start ENTITY");
242 185 jones
   }
243
244
   /**
245
    * SAX Handler that receives notification of the end of entities
246
    */
247
   public void endEntity(String name) throws SAXException {
248 203 jones
     MetaCatUtil.debugMessage("end ENTITY");
249 185 jones
   }
250 186 jones
251
   /**
252
    * SAX Handler that receives notification of element declarations
253
    */
254
   public void elementDecl(String name, String model)
255
                        throws org.xml.sax.SAXException {
256 203 jones
     MetaCatUtil.debugMessage("ELEMENTDECL");
257 186 jones
   }
258
259
   /**
260
    * SAX Handler that receives notification of attribute declarations
261
    */
262
   public void attributeDecl(String eName, String aName,
263
                        String type, String valueDefault, String value)
264
                        throws org.xml.sax.SAXException {
265 203 jones
     MetaCatUtil.debugMessage("ATTRIBUTEDECL");
266 186 jones
   }
267
268
   /**
269
    * SAX Handler that receives notification of internal entity declarations
270
    */
271
   public void internalEntityDecl(String name, String value)
272
                        throws org.xml.sax.SAXException {
273 203 jones
     MetaCatUtil.debugMessage("INTERNENTITYDECL");
274 186 jones
   }
275
276
   /**
277
    * SAX Handler that receives notification of external entity declarations
278
    */
279
   public void externalEntityDecl(String name, String publicId,
280
                        String systemId)
281
                        throws org.xml.sax.SAXException {
282 203 jones
     MetaCatUtil.debugMessage("EXTERNENTITYDECL");
283 186 jones
   }
284
285 204 jones
   //
286
   // the next section implements the ErrorHandler interface
287
   //
288 186 jones
289 204 jones
   /**
290
    * SAX Handler that receives notification of fatal parsing errors
291
    */
292
   public void fatalError(SAXParseException exception) throws SAXException {
293
     MetaCatUtil.debugMessage("FATALERROR");
294
     throw (new SAXException("Fatal processing error.", exception));
295
   }
296
297
   /**
298
    * SAX Handler that receives notification of recoverable parsing errors
299
    */
300
   public void error(SAXParseException exception) throws SAXException {
301
     MetaCatUtil.debugMessage("ERROR");
302
   }
303
304
   /**
305
    * SAX Handler that receives notification of warnings
306
    */
307
   public void warning(SAXParseException exception) throws SAXException {
308
     MetaCatUtil.debugMessage("FATALERROR");
309
   }
310
311
   //
312
   // Helper, getter and setter methods
313
   //
314
315
   /**
316
    * get the document name
317
    */
318
   public String getDocname() {
319
     return docname;
320
   }
321
322
   /**
323
    * get the document processing state
324
    */
325
   public boolean atFirstElement() {
326
     return atFirstElement;
327
   }
328 17 jones
}
329 203 jones
330
/**
331
 * '$Log$
332 204 jones
 * 'Revision 1.28  2000/06/26 10:35:05  jones
333
 * 'Merged in substantial changes to DBWriter and associated classes and to
334
 * 'the MetaCatServlet in order to accomodate the new UPDATE and DELETE
335
 * 'functions.  The command line tools and the parameters for the
336
 * 'servlet have changed substantially.
337
 * '
338 203 jones
 * 'Revision 1.27.2.6  2000/06/26 02:02:20  jones
339
 * 'Continued fixing problems with exception handling that deals
340
 * 'with INSERT and UPDATE actions and the docid passed to DBWriter
341
 * '
342
 * 'Revision 1.27.2.5  2000/06/26 00:51:06  jones
343
 * 'If docid passed to DBWriter.write() is not unique, classes now generate
344
 * 'an AccessionNumberException containing the new docid generated as a
345
 * 'replacement.  The docid is then extracted from the exception and
346
 * 'returned to the calling application for user feedback or client processing.
347
 * '
348
 * 'Revision 1.27.2.4  2000/06/25 23:38:16  jones
349
 * 'Added RCSfile keyword
350
 * '
351
 * 'Revision 1.27.2.3  2000/06/25 23:34:17  jones
352
 * 'Changed documentation formatting, added log entries at bottom of source files
353
 * ''
354
 */