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 142 2000-06-08 03:47:46Z 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 	nodeStack;
41
   private Connection	conn = null;
42
   private DBSAXDocument currentDocument;
43

    
44
   /** Construct an instance of the handler class 
45
    *
46
    * @param conn the JDBC connection to which information is written
47
    */
48
   public DBSAXHandler(Connection conn) {
49
      this.conn = conn;
50

    
51
      // Create the stack for keeping track of node context
52
      // if it doesn't already exist
53
      if (!stackCreated) {
54
        nodeStack = new Stack();
55
        stackCreated = true;
56
      }
57

    
58
   }
59
 
60
   /** SAX Handler that receives notification of beginning of the document */
61
   public void startDocument() throws SAXException {
62
    if (debug) {
63
      System.out.println("start Document");
64
    }
65
    // Create the document node represantation as root
66
    DBSAXNode documentNode = new DBSAXNode(conn, docname);
67
    // Add the node to the stack, so that any text data can be 
68
    // added as it is encountered
69
    nodeStack.push(documentNode);
70
   }
71

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

    
80
   /** SAX Handler that receives notification of DTD. Sets the DTD */
81
   public void setDoctype(DTD dtd) throws SAXException {
82
     // here is a bug: dtd.getPublicId() and dtd.getSustemId() 
83
     // always return null.
84
     docname = dtd.getName();
85
     doctype = dtd.getPublicId();
86
     systemid = dtd.getSystemId();
87
     if (debug) {
88
       System.out.println("DOCNAME: " + docname);
89
       System.out.println("DOCTYPE: " + doctype);
90
       System.out.println("  SYSID: " + systemid);
91
     }
92
   }
93

    
94
   /** 
95
    * SAX Handler that receives notification of end of DTD 
96
    * All events in DTDHandler about all unparsed entities and the 
97
    * event in EntityResolver for the DTD file declaration appear 
98
    * between setDoctype and endDoctype. The rest of parsable external 
99
    * entities inside DTD file appear later in the elements from where 
100
    * they are referred to. 
101
    */
102
   public void endDoctype() throws SAXException {
103
     if (debug) {
104
       System.out.println("end of DOCTYPE");
105
     }
106
   }
107

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

    
111
      // Use the methods getQualifiedName(), getLocalName(), getNamespace()
112
      // and getExpandedName() in NSName interface to get Namespace
113
      // information.
114

    
115
      String qName;
116
      String localName;
117
      String nsName;
118
      String expName;
119
      DBSAXNode parentNode = null;
120
      DBSAXNode currentNode = null;
121

    
122
      qName = name.getQualifiedName();
123
      localName = name.getLocalName();
124
      nsName = name.getNamespace();
125
      expName = name.getExpandedName();
126
      
127
      elementNo++;
128
      // Get a reference to the parent node for the id
129
      try {
130
        parentNode = (DBSAXNode)nodeStack.peek();
131
      } catch (EmptyStackException e) {
132
      }
133

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

    
148
      // Create the current node representation
149
      currentNode = new DBSAXNode(conn, localName, parentNode);
150

    
151
      // Add all of the attributes
152
      for (int i=0; i<atts.getLength(); i++)
153
      {
154

    
155
         // Use the methods getQualifiedName(), getLocalName(), getNamespace()
156
         // and getExpandedName() in SAXAttrList interface to get Namespace
157
         // information.
158

    
159
         qName = atts.getQualifiedName(i);
160
         localName = atts.getLocalName(i);
161
         nsName = atts.getNamespace(i);
162
         expName = atts.getExpandedName(i);
163

    
164
         // You can get the type and value of the attributes either
165
         // by index or by the Qualified Name.
166

    
167
         String type = atts.getType(qName);
168
         String value = atts.getValue(qName);
169

    
170
         currentNode.setAttribute(localName, value);
171
      }      
172

    
173
      // Add the node to the stack, so that any text data can be 
174
      // added as it is encountered
175
      nodeStack.push(currentNode);
176

    
177
   }
178

    
179
   /** SAX Handler that is called for each XML text node */
180
   public void characters(char[] cbuf, int start, int len) {
181
      DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
182
      String data = new String(cbuf, start, len);
183

    
184
      // Write the content of the node to the database
185
      currentNode.writeChildNodeToDB("TEXT", null, data);
186
   }
187

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

    
195
   /** 
196
    * SAX Handler called once for each comment found: 
197
    * node that comment may occur before or after the root element.
198
    */
199
   public void comment(String data) throws SAXException {
200
      DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
201
      currentNode.writeChildNodeToDB("COMMENT", null, data);
202
   }
203

    
204
   /** 
205
    * SAX Handler called once for each processing instruction found: 
206
    * node that PI may occur before or after the root element.
207
    */
208
   public void processingInstruction(String target, String data) 
209
          throws SAXException {
210
      DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
211
      currentNode.writeChildNodeToDB("PI", target, data);
212
   }
213

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

    
221
      // Get the node from the stack
222
      DBSAXNode currentNode = (DBSAXNode)nodeStack.pop();
223
   }
224

    
225
   /** Debug routine */
226
   private void db(int flag) {
227
     if (debug) {
228
       System.err.println("DEBUG POSITION " + flag);
229
     }
230
   }   
231
}
(7-7/18)