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 149 bojilova
   //private String 	docID;
37
   //private String 	rootNodeID;
38 135 jones
   private String 	doctype;
39
   private String 	systemid;
40 17 jones
   private boolean 	debug 	= false;
41
   private boolean 	stackCreated = false;
42 137 jones
   private Stack 	nodeStack;
43 17 jones
   private Connection	conn = null;
44 142 jones
   private DBSAXDocument currentDocument;
45 149 bojilova
   private DBSAXNode rootNode;
46 17 jones
47 31 jones
   /** Construct an instance of the handler class
48
    *
49
    * @param conn the JDBC connection to which information is written
50
    */
51 122 jones
   public DBSAXHandler(Connection conn) {
52 17 jones
      this.conn = conn;
53
54 137 jones
      // Create the stack for keeping track of node context
55 17 jones
      // if it doesn't already exist
56
      if (!stackCreated) {
57 137 jones
        nodeStack = new Stack();
58 17 jones
        stackCreated = true;
59
      }
60
61
   }
62
63 72 bojilova
   /** SAX Handler that receives notification of beginning of the document */
64 122 jones
   public void startDocument() throws SAXException {
65
    if (debug) {
66
      System.out.println("start Document");
67
    }
68 110 bojilova
    // Create the document node represantation as root
69 149 bojilova
    rootNode = new DBSAXNode(conn, docname);
70 137 jones
    // Add the node to the stack, so that any text data can be
71 110 bojilova
    // added as it is encountered
72 149 bojilova
    nodeStack.push(rootNode);
73 72 bojilova
   }
74
75
   /** SAX Handler that receives notification of end of the document */
76 122 jones
   public void endDocument() throws SAXException {
77 142 jones
    currentDocument.setTitleFromChildElement();
78 122 jones
    if (debug) {
79
      System.out.println("end Document");
80
    }
81 72 bojilova
   }
82
83
   /** SAX Handler that receives notification of DTD. Sets the DTD */
84 122 jones
   public void setDoctype(DTD dtd) throws SAXException {
85
     // here is a bug: dtd.getPublicId() and dtd.getSustemId()
86
     // always return null.
87
     docname = dtd.getName();
88
     doctype = dtd.getPublicId();
89
     systemid = dtd.getSystemId();
90
     if (debug) {
91
       System.out.println("DOCNAME: " + docname);
92
       System.out.println("DOCTYPE: " + doctype);
93
       System.out.println("  SYSID: " + systemid);
94
     }
95 72 bojilova
   }
96
97 122 jones
   /**
98
    * SAX Handler that receives notification of end of DTD
99
    * All events in DTDHandler about all unparsed entities and the
100
    * event in EntityResolver for the DTD file declaration appear
101
    * between setDoctype and endDoctype. The rest of parsable external
102
    * entities inside DTD file appear later in the elements from where
103
    * they are referred to.
104
    */
105
   public void endDoctype() throws SAXException {
106
     if (debug) {
107
       System.out.println("end of DOCTYPE");
108
     }
109 72 bojilova
   }
110
111 31 jones
   /** SAX Handler that is called at the start of each XML element */
112 122 jones
   public void startElement(NSName name, SAXAttrList atts) throws SAXException {
113 17 jones
114
      // Use the methods getQualifiedName(), getLocalName(), getNamespace()
115
      // and getExpandedName() in NSName interface to get Namespace
116
      // information.
117
118
      String qName;
119
      String localName;
120
      String nsName;
121
      String expName;
122 137 jones
      DBSAXNode parentNode = null;
123
      DBSAXNode currentNode = null;
124 17 jones
125
      qName = name.getQualifiedName();
126
      localName = name.getLocalName();
127
      nsName = name.getNamespace();
128
      expName = name.getExpandedName();
129
130 72 bojilova
      elementNo++;
131 137 jones
      // Get a reference to the parent node for the id
132 18 jones
      try {
133 137 jones
        parentNode = (DBSAXNode)nodeStack.peek();
134 18 jones
      } catch (EmptyStackException e) {
135
      }
136
137 109 bojilova
      // Document representation that points to the root document node
138
      if (elementNo == 1) {
139
        // If no DOCTYPE declaration: docname = root element name
140 135 jones
        if (docname == null) {
141 109 bojilova
            docname = localName;
142 135 jones
        } else if (doctype == null) {
143 109 bojilova
            doctype = DBEntityResolver.doctype;
144 135 jones
        }
145 149 bojilova
        //DBSAXNode documentNode = (DBSAXNode)nodeStack.peek();
146
        rootNode.writeNodename(docname);
147
        rootNode.writeRootNodeID(rootNode.getNodeID());
148
        currentDocument = new DBSAXDocument(conn, rootNode.getNodeID(),
149 142 jones
                                            docname, doctype);
150 149 bojilova
        rootNode.writeDocID(currentDocument.getDocID());
151 109 bojilova
      }
152 135 jones
153 137 jones
      // Create the current node representation
154 149 bojilova
      currentNode = new DBSAXNode(conn, localName, parentNode, rootNode, currentDocument);
155 17 jones
156
      // Add all of the attributes
157
      for (int i=0; i<atts.getLength(); i++)
158
      {
159
160
         // Use the methods getQualifiedName(), getLocalName(), getNamespace()
161
         // and getExpandedName() in SAXAttrList interface to get Namespace
162
         // information.
163
164
         qName = atts.getQualifiedName(i);
165
         localName = atts.getLocalName(i);
166
         nsName = atts.getNamespace(i);
167
         expName = atts.getExpandedName(i);
168
169
         // You can get the type and value of the attributes either
170
         // by index or by the Qualified Name.
171
172
         String type = atts.getType(qName);
173
         String value = atts.getValue(qName);
174
175 137 jones
         currentNode.setAttribute(localName, value);
176 17 jones
      }
177
178 137 jones
      // Add the node to the stack, so that any text data can be
179 17 jones
      // added as it is encountered
180 137 jones
      nodeStack.push(currentNode);
181 17 jones
182
   }
183
184 31 jones
   /** SAX Handler that is called for each XML text node */
185 122 jones
   public void characters(char[] cbuf, int start, int len) {
186 137 jones
      DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
187 122 jones
      String data = new String(cbuf, start, len);
188
189 137 jones
      // Write the content of the node to the database
190
      currentNode.writeChildNodeToDB("TEXT", null, data);
191 17 jones
   }
192
193 31 jones
   /**
194
    * SAX Handler that is called for each XML text node that is Ignorable
195
    * white space
196
    */
197 122 jones
   public void ignorableWhitespace(char[] cbuf, int start, int len) {
198 17 jones
   }
199
200 122 jones
   /**
201
    * SAX Handler called once for each comment found:
202
    * node that comment may occur before or after the root element.
203
    */
204
   public void comment(String data) throws SAXException {
205 137 jones
      DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
206
      currentNode.writeChildNodeToDB("COMMENT", null, data);
207 72 bojilova
   }
208 122 jones
209
   /**
210
    * SAX Handler called once for each processing instruction found:
211
    * node that PI may occur before or after the root element.
212
    */
213
   public void processingInstruction(String target, String data)
214
          throws SAXException {
215 137 jones
      DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
216
      currentNode.writeChildNodeToDB("PI", target, data);
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 137 jones
      // Get the node from the stack
227
      DBSAXNode currentNode = (DBSAXNode)nodeStack.pop();
228 17 jones
   }
229
230
   /** Debug routine */
231
   private void db(int flag) {
232
     if (debug) {
233
       System.err.println("DEBUG POSITION " + flag);
234
     }
235
   }
236
}