Project

General

Profile

1
/**
2
 *        Name: DBSAXHandler.java
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
8
 *
9
 *     Version: '$Id: DBSAXHandler.java 136 2000-06-08 00:19:37Z jones $'
10
 */
11

    
12
package edu.ucsb.nceas.metacat;
13

    
14
import org.xml.sax.*;
15

    
16
import java.sql.*;
17
import java.util.Stack;
18
import java.util.EmptyStackException;
19

    
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
import oracle.xml.parser.v2.DTD;
27

    
28
/** 
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
public class DBSAXHandler extends DefaultXMLDocumentHandler {
33

    
34
   static  int 		elementNo = 0;
35
   static  String 	docname = null;
36
   private String 	doctype;
37
   private String 	systemid;
38
   private boolean 	debug 	= false;
39
   private boolean 	stackCreated = false;
40
   private Stack 	elementStack;
41
   private Connection	conn = null;
42

    
43
   /** Construct an instance of the handler class 
44
    *
45
    * @param conn the JDBC connection to which information is written
46
    */
47
   public DBSAXHandler(Connection conn) {
48
      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
   /** SAX Handler that receives notification of beginning of the document */
60
   public void startDocument() throws SAXException {
61
    if (debug) {
62
      System.out.println("start Document");
63
    }
64
    // Create the document node represantation as root
65
    DBSAXElement documentNode = new DBSAXElement(conn, docname);
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
   }
70

    
71
   /** SAX Handler that receives notification of end of the document */
72
   public void endDocument() throws SAXException {
73
    if (debug) {
74
      System.out.println("end Document");
75
    }
76
   }
77

    
78
   /** SAX Handler that receives notification of DTD. Sets the DTD */
79
   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
   }
91

    
92
   /** 
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
   }
105

    
106
   /** SAX Handler that is called at the start of each XML element */
107
   public void startElement(NSName name, SAXAttrList atts) throws SAXException {
108

    
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
      DBSAXElement parentElement = null;
118
      DBSAXElement currentElement = null;
119

    
120
      qName = name.getQualifiedName();
121
      localName = name.getLocalName();
122
      nsName = name.getNamespace();
123
      expName = name.getExpandedName();
124
      
125
      elementNo++;
126
      // Get a reference to the parent element for the id
127
      try {
128
        parentElement = (DBSAXElement)elementStack.peek();
129
      } catch (EmptyStackException e) {
130
      }
131

    
132
      // Document representation that points to the root document node
133
      if (elementNo == 1) {
134
        // If no DOCTYPE declaration: docname = root element name 
135
        if (docname == null) {
136
            docname = localName;
137
        } else if (doctype == null) {
138
            doctype = DBEntityResolver.doctype;
139
        }
140
        DBSAXElement documentNode = (DBSAXElement)elementStack.peek();
141
        documentNode.writeNodename(docname);
142
        new DBSAXDocument(conn, documentNode.getNodeID(), docname, doctype);
143
      }      
144

    
145
      // Create the current element representation
146
      currentElement = new DBSAXElement(conn, localName, parentElement);
147

    
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
   /** SAX Handler that is called for each XML text node */
177
   public void characters(char[] cbuf, int start, int len) {
178
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
179
      String data = new String(cbuf, start, len);
180

    
181
      // Write the content of the element to the database
182
      currentElement.writeChildNodeToDB("TEXT", null, data);
183
   }
184

    
185
   /** 
186
    * SAX Handler that is called for each XML text node that is Ignorable
187
    * white space
188
    */
189
   public void ignorableWhitespace(char[] cbuf, int start, int len) {
190
   }
191

    
192
   /** 
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
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
199
      currentElement.writeChildNodeToDB("COMMENT", null, data);
200
   }
201

    
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
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
209
      currentElement.writeChildNodeToDB("PI", target, data);
210
   }
211

    
212
   /** SAX Handler that is called at the end of each XML element */
213
   public void endElement(NSName name) throws SAXException {
214
      // Use the methods getQualifiedName(), getLocalName(), getNamespace()
215
      // and getExpandedName() in NSName interface to get Namespace
216
      // information.
217
      String expName = name.getExpandedName();
218

    
219
      // Get the element from the stack
220
      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
}
(7-7/19)