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 135 jones
   static  int 		elementNo = 0;
35
   static  String 	docname = null;
36
   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 135 jones
    DBSAXElement documentNode = new DBSAXElement(conn, docname);
66 110 bojilova
    // 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 135 jones
      DBSAXElement parentElement = null;
118 136 jones
      DBSAXElement currentElement = null;
119 17 jones
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
      try {
128
        parentElement = (DBSAXElement)elementStack.peek();
129
      } catch (EmptyStackException e) {
130
      }
131
132 109 bojilova
      // Document representation that points to the root document node
133
      if (elementNo == 1) {
134
        // If no DOCTYPE declaration: docname = root element name
135 135 jones
        if (docname == null) {
136 109 bojilova
            docname = localName;
137 135 jones
        } else if (doctype == null) {
138 109 bojilova
            doctype = DBEntityResolver.doctype;
139 135 jones
        }
140 109 bojilova
        DBSAXElement documentNode = (DBSAXElement)elementStack.peek();
141 110 bojilova
        documentNode.writeNodename(docname);
142 134 jones
        new DBSAXDocument(conn, documentNode.getNodeID(), docname, doctype);
143 109 bojilova
      }
144 135 jones
145 17 jones
      // Create the current element representation
146 135 jones
      currentElement = new DBSAXElement(conn, localName, parentElement);
147 17 jones
148
      // Add all of the attributes
149
      for (int i=0; i<atts.getLength(); i++)
150
      {
151
152
         // Use the methods getQualifiedName(), getLocalName(), getNamespace()
153
         // and getExpandedName() in SAXAttrList interface to get Namespace
154
         // information.
155
156
         qName = atts.getQualifiedName(i);
157
         localName = atts.getLocalName(i);
158
         nsName = atts.getNamespace(i);
159
         expName = atts.getExpandedName(i);
160
161
         // You can get the type and value of the attributes either
162
         // by index or by the Qualified Name.
163
164
         String type = atts.getType(qName);
165
         String value = atts.getValue(qName);
166
167
         currentElement.setAttribute(localName, value);
168
      }
169
170
      // Add the element to the stack, so that any text data can be
171
      // added as it is encountered
172
      elementStack.push(currentElement);
173
174
   }
175
176 31 jones
   /** SAX Handler that is called for each XML text node */
177 122 jones
   public void characters(char[] cbuf, int start, int len) {
178 17 jones
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
179 122 jones
      String data = new String(cbuf, start, len);
180
181
      // Write the content of the element to the database
182 135 jones
      currentElement.writeChildNodeToDB("TEXT", null, data);
183 17 jones
   }
184
185 31 jones
   /**
186
    * SAX Handler that is called for each XML text node that is Ignorable
187
    * white space
188
    */
189 122 jones
   public void ignorableWhitespace(char[] cbuf, int start, int len) {
190 17 jones
   }
191
192 122 jones
   /**
193
    * SAX Handler called once for each comment found:
194
    * node that comment may occur before or after the root element.
195
    * For now works only for comments after the root element.
196
    */
197
   public void comment(String data) throws SAXException {
198 72 bojilova
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
199 135 jones
      currentElement.writeChildNodeToDB("COMMENT", null, data);
200 72 bojilova
   }
201 122 jones
202
   /**
203
    * SAX Handler called once for each processing instruction found:
204
    * node that PI may occur before or after the root element.
205
    */
206
   public void processingInstruction(String target, String data)
207
          throws SAXException {
208 109 bojilova
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
209 135 jones
      currentElement.writeChildNodeToDB("PI", target, data);
210 92 bojilova
   }
211 72 bojilova
212 31 jones
   /** SAX Handler that is called at the end of each XML element */
213 122 jones
   public void endElement(NSName name) throws SAXException {
214 17 jones
      // Use the methods getQualifiedName(), getLocalName(), getNamespace()
215
      // and getExpandedName() in NSName interface to get Namespace
216
      // information.
217
      String expName = name.getExpandedName();
218
219 18 jones
      // Get the element from the stack
220 17 jones
      DBSAXElement currentElement = (DBSAXElement)elementStack.pop();
221
   }
222
223
   /** Debug routine */
224
   private void db(int flag) {
225
     if (debug) {
226
       System.err.println("DEBUG POSITION " + flag);
227
     }
228
   }
229
}