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