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