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 133 2000-06-07 22:40:05Z 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, 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
   }
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;
118
      DBSAXElement currentElement;
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
      long parent_id;
128
      int nodeIndex;
129
      try {
130
        parentElement = (DBSAXElement)elementStack.peek();
131
        parent_id = parentElement.getElementID();
132
        nodeIndex = parentElement.incChildNum();
133
      } catch (EmptyStackException e) {
134
        parent_id = 0;
135
        nodeIndex = 0;
136
      }
137

    
138
      // 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
        documentNode.writeNodename(docname);
147
        new DBSAXDocument(conn, documentNode.getElementID(), docname, doctype);
148
      }      
149
      // Create the current element representation
150
      currentElement = new DBSAXElement(conn, localName, parent_id, nodeIndex);
151

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

    
186
      // Write the content of the element to the database
187
      currentElement.writeChildNodeToDB("TEXT", null, data, nodeIndex);
188
   }
189

    
190
   /** 
191
    * SAX Handler that is called for each XML text node that is Ignorable
192
    * white space
193
    */
194
   public void ignorableWhitespace(char[] cbuf, int start, int len) {
195
   }
196

    
197
   /** 
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
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
204
      int nodeIndex = currentElement.incChildNum();
205
      currentElement.writeChildNodeToDB("COMMENT", null, data, nodeIndex);
206
   }
207

    
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
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
215
      int nodeIndex = currentElement.incChildNum();
216
      currentElement.writeChildNodeToDB("PI", target, data, nodeIndex);
217
   }
218

    
219
   /** SAX Handler that is called at the end of each XML element */
220
   public void endElement(NSName name) throws SAXException {
221
      // Use the methods getQualifiedName(), getLocalName(), getNamespace()
222
      // and getExpandedName() in NSName interface to get Namespace
223
      // information.
224
      String expName = name.getExpandedName();
225

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