Project

General

Profile

1 17 jones
/**
2
 *        Name: DBSAXHandler.java
3
 *     Purpose: A Class that handles the SAX XML events as they
4
 *              are generated from XML documents
5 35 jones
 *   Copyright: 2000 Regents of the University of California and the
6
 *              National Center for Ecological Analysis and Synthesis
7 17 jones
 *     Authors: Matt Jones
8
 *
9
 *     Version: '$Id$'
10
 */
11
12 75 jones
package edu.ucsb.nceas.metacat;
13 51 jones
14 17 jones
import org.xml.sax.*;
15
16
import java.sql.*;
17
import java.util.Stack;
18 18 jones
import java.util.EmptyStackException;
19 17 jones
20
// Extensions to the SAX Interfaces for Namespace support.
21
import oracle.xml.parser.v2.DefaultXMLDocumentHandler;
22
import oracle.xml.parser.v2.NSName;
23
import oracle.xml.parser.v2.SAXAttrList;
24
25
import oracle.xml.parser.v2.SAXParser;
26 72 bojilova
import oracle.xml.parser.v2.DTD;
27 17 jones
28 31 jones
/**
29
 * A database aware Class implementing callback bethods for the SAX parser to
30
 * call when processing the XML stream and generating events
31
 */
32 122 jones
public class DBSAXHandler extends DefaultXMLDocumentHandler {
33 17 jones
34 72 bojilova
   static int elementNo = 0;
35 109 bojilova
   static String docname = null;
36 72 bojilova
   private String doctype;
37
   private String systemid;
38 17 jones
   private boolean 	debug 	= false;
39
   private boolean 	stackCreated = false;
40
   private Stack 	elementStack;
41
   private Connection	conn = null;
42
43 31 jones
   /** Construct an instance of the handler class
44
    *
45
    * @param conn the JDBC connection to which information is written
46
    */
47 122 jones
   public DBSAXHandler(Connection conn) {
48 17 jones
      this.conn = conn;
49
50
      // Create the stack for keeping track of element context
51
      // if it doesn't already exist
52
      if (!stackCreated) {
53
        elementStack = new Stack();
54
        stackCreated = true;
55
      }
56
57
   }
58
59 72 bojilova
   /** SAX Handler that receives notification of beginning of the document */
60 122 jones
   public void startDocument() throws SAXException {
61
    if (debug) {
62
      System.out.println("start Document");
63
    }
64 110 bojilova
    // Create the document node represantation as root
65
    DBSAXElement documentNode = new DBSAXElement(conn, docname, 0, 0);
66
    // Add the element to the stack, so that any text data can be
67
    // added as it is encountered
68
    elementStack.push(documentNode);
69 72 bojilova
   }
70
71
   /** SAX Handler that receives notification of end of the document */
72 122 jones
   public void endDocument() throws SAXException {
73
    if (debug) {
74
      System.out.println("end Document");
75
    }
76 72 bojilova
   }
77
78
   /** SAX Handler that receives notification of DTD. Sets the DTD */
79 122 jones
   public void setDoctype(DTD dtd) throws SAXException {
80
     // here is a bug: dtd.getPublicId() and dtd.getSustemId()
81
     // always return null.
82
     docname = dtd.getName();
83
     doctype = dtd.getPublicId();
84
     systemid = dtd.getSystemId();
85
     if (debug) {
86
       System.out.println("DOCNAME: " + docname);
87
       System.out.println("DOCTYPE: " + doctype);
88
       System.out.println("  SYSID: " + systemid);
89
     }
90 72 bojilova
   }
91
92 122 jones
   /**
93
    * SAX Handler that receives notification of end of DTD
94
    * All events in DTDHandler about all unparsed entities and the
95
    * event in EntityResolver for the DTD file declaration appear
96
    * between setDoctype and endDoctype. The rest of parsable external
97
    * entities inside DTD file appear later in the elements from where
98
    * they are referred to.
99
    */
100
   public void endDoctype() throws SAXException {
101
     if (debug) {
102
       System.out.println("end of DOCTYPE");
103
     }
104 72 bojilova
   }
105
106 31 jones
   /** SAX Handler that is called at the start of each XML element */
107 122 jones
   public void startElement(NSName name, SAXAttrList atts) throws SAXException {
108 17 jones
109
      // Use the methods getQualifiedName(), getLocalName(), getNamespace()
110
      // and getExpandedName() in NSName interface to get Namespace
111
      // information.
112
113
      String qName;
114
      String localName;
115
      String nsName;
116
      String expName;
117 18 jones
      DBSAXElement parentElement;
118 17 jones
      DBSAXElement currentElement;
119
120
      qName = name.getQualifiedName();
121
      localName = name.getLocalName();
122
      nsName = name.getNamespace();
123
      expName = name.getExpandedName();
124
125 72 bojilova
      elementNo++;
126 18 jones
      // Get a reference to the parent element for the id
127
      long parent_id;
128 72 bojilova
      int nodeIndex;
129 18 jones
      try {
130
        parentElement = (DBSAXElement)elementStack.peek();
131
        parent_id = parentElement.getElementID();
132 72 bojilova
        nodeIndex = parentElement.incChildNum();
133 18 jones
      } catch (EmptyStackException e) {
134
        parent_id = 0;
135 72 bojilova
        nodeIndex = 0;
136 18 jones
      }
137
138 109 bojilova
      // Document representation that points to the root document node
139
      if (elementNo == 1) {
140
        // If no DOCTYPE declaration: docname = root element name
141
        if (docname == null)
142
            docname = localName;
143
        else if (doctype == null)
144
            doctype = DBEntityResolver.doctype;
145
        DBSAXElement documentNode = (DBSAXElement)elementStack.peek();
146 110 bojilova
        documentNode.writeNodename(docname);
147 109 bojilova
        new DBSAXDocument(conn, documentNode.getElementID(), docname, doctype);
148
      }
149 17 jones
      // Create the current element representation
150 72 bojilova
      currentElement = new DBSAXElement(conn, localName, parent_id, nodeIndex);
151 17 jones
152
      // Add all of the attributes
153
      for (int i=0; i<atts.getLength(); i++)
154
      {
155
156
         // Use the methods getQualifiedName(), getLocalName(), getNamespace()
157
         // and getExpandedName() in SAXAttrList interface to get Namespace
158
         // information.
159
160
         qName = atts.getQualifiedName(i);
161
         localName = atts.getLocalName(i);
162
         nsName = atts.getNamespace(i);
163
         expName = atts.getExpandedName(i);
164
165
         // You can get the type and value of the attributes either
166
         // by index or by the Qualified Name.
167
168
         String type = atts.getType(qName);
169
         String value = atts.getValue(qName);
170
171
         currentElement.setAttribute(localName, value);
172
      }
173
174
      // Add the element to the stack, so that any text data can be
175
      // added as it is encountered
176
      elementStack.push(currentElement);
177
178
   }
179
180 31 jones
   /** SAX Handler that is called for each XML text node */
181 122 jones
   public void characters(char[] cbuf, int start, int len) {
182 17 jones
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
183 122 jones
      int nodeIndex = currentElement.incChildNum();
184
      String data = new String(cbuf, start, len);
185
186
      // Write the content of the element to the database
187 133 jones
      currentElement.writeChildNodeToDB("TEXT", null, data, nodeIndex);
188 17 jones
   }
189
190 31 jones
   /**
191
    * SAX Handler that is called for each XML text node that is Ignorable
192
    * white space
193
    */
194 122 jones
   public void ignorableWhitespace(char[] cbuf, int start, int len) {
195 17 jones
   }
196
197 122 jones
   /**
198
    * SAX Handler called once for each comment found:
199
    * node that comment may occur before or after the root element.
200
    * For now works only for comments after the root element.
201
    */
202
   public void comment(String data) throws SAXException {
203 72 bojilova
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
204 92 bojilova
      int nodeIndex = currentElement.incChildNum();
205 133 jones
      currentElement.writeChildNodeToDB("COMMENT", null, data, nodeIndex);
206 72 bojilova
   }
207 122 jones
208
   /**
209
    * SAX Handler called once for each processing instruction found:
210
    * node that PI may occur before or after the root element.
211
    */
212
   public void processingInstruction(String target, String data)
213
          throws SAXException {
214 109 bojilova
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
215
      int nodeIndex = currentElement.incChildNum();
216 133 jones
      currentElement.writeChildNodeToDB("PI", target, data, nodeIndex);
217 92 bojilova
   }
218 72 bojilova
219 31 jones
   /** SAX Handler that is called at the end of each XML element */
220 122 jones
   public void endElement(NSName name) throws SAXException {
221 17 jones
      // Use the methods getQualifiedName(), getLocalName(), getNamespace()
222
      // and getExpandedName() in NSName interface to get Namespace
223
      // information.
224
      String expName = name.getExpandedName();
225
226 18 jones
      // Get the element from the stack
227 17 jones
      DBSAXElement currentElement = (DBSAXElement)elementStack.pop();
228
   }
229
230
   /** Debug routine */
231
   private void db(int flag) {
232
     if (debug) {
233
       System.err.println("DEBUG POSITION " + flag);
234
     }
235
   }
236
}