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 72 2000-05-04 22:30:15Z bojilova $'
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

    
35
   static int elementNo = 0;
36
   private String docname;
37
   private String doctype;
38
   private String systemid;
39
   private boolean 	debug 	= false;
40
   private boolean 	stackCreated = false;
41
   private Stack 	elementStack;
42
   private Connection	conn = null;
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
   {
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
   /** 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
    System.out.println("DOCTYPE: " + docname);
81
    System.out.println("DOCTYPE: " + doctype);
82
    System.out.println("DOCTYPE: " + systemid);
83
   }
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
    if (doctype == null)
93
        doctype = DBEntityResolver.doctype;
94
   }
95

    
96
   /** SAX Handler that is called at the start of each XML element */
97
   public void startElement(NSName name, SAXAttrList atts) throws SAXException 
98
   {
99

    
100
      // Use the methods getQualifiedName(), getLocalName(), getNamespace()
101
      // and getExpandedName() in NSName interface to get Namespace
102
      // information.
103

    
104
      String qName;
105
      String localName;
106
      String nsName;
107
      String expName;
108
      DBSAXElement parentElement;
109
      DBSAXElement currentElement;
110

    
111
      qName = name.getQualifiedName();
112
      localName = name.getLocalName();
113
      nsName = name.getNamespace();
114
      expName = name.getExpandedName();
115
      
116
      elementNo++;
117
      if ((elementNo == 1) && (doctype == null))
118
        throw new SAXException("No DOCTYPE declaration or PUBLIC ID provided");
119
      // Get a reference to the parent element for the id
120
      long parent_id;
121
      int nodeIndex;
122
      try {
123
        parentElement = (DBSAXElement)elementStack.peek();
124
        parent_id = parentElement.getElementID();
125
        nodeIndex = parentElement.incChildNum();
126
      } catch (EmptyStackException e) {
127
        parent_id = 0;
128
        nodeIndex = 0;
129
      }
130

    
131
      // Create the current element representation
132
      currentElement = new DBSAXElement(conn, localName, parent_id, nodeIndex);
133
      // go to create document definition in the db
134
      // call once after insertion of the first element
135
      if (parent_id == 0) {
136
        long rootnodeid = currentElement.getElementID();
137
        new DBSAXDocument(conn, rootnodeid, docname, doctype);
138
      }
139

    
140
      // Add all of the attributes
141
      for (int i=0; i<atts.getLength(); i++)
142
      {
143

    
144
         // Use the methods getQualifiedName(), getLocalName(), getNamespace()
145
         // and getExpandedName() in SAXAttrList interface to get Namespace
146
         // information.
147

    
148
         qName = atts.getQualifiedName(i);
149
         localName = atts.getLocalName(i);
150
         nsName = atts.getNamespace(i);
151
         expName = atts.getExpandedName(i);
152

    
153
         // You can get the type and value of the attributes either
154
         // by index or by the Qualified Name.
155

    
156
         String type = atts.getType(qName);
157
         String value = atts.getValue(qName);
158

    
159
         currentElement.setAttribute(localName, value);
160
      }      
161

    
162
      // Add the element to the stack, so that any text data can be 
163
      // added as it is encountered
164
      elementStack.push(currentElement);
165

    
166
   }
167

    
168
   /** SAX Handler that is called for each XML text node */
169
   public void characters(char[] cbuf, int start, int len)
170
   {
171
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
172
      currentElement.appendContent(cbuf,start,len);
173
   }
174

    
175
   /** 
176
    * SAX Handler that is called for each XML text node that is Ignorable
177
    * white space
178
    */
179
   public void ignorableWhitespace(char[] cbuf, int start, int len)
180
   {
181
   }
182

    
183
   /** SAX Handler called once for each comment found: 
184
     * node that comment may occur before or after the root element.
185
     * For now works only for comments after the root element. */
186
   public void comment(String data) throws SAXException
187
   {
188
    if (elementNo > 0) {
189
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
190
      currentElement.writeCommentToDB(data);
191
    }
192
   }
193

    
194
   /** SAX Handler that is called at the end of each XML element */
195
   public void endElement(NSName name) throws SAXException 
196
   {
197
      // Use the methods getQualifiedName(), getLocalName(), getNamespace()
198
      // and getExpandedName() in NSName interface to get Namespace
199
      // information.
200
      String expName = name.getExpandedName();
201

    
202
      // Get the element from the stack
203
      DBSAXElement currentElement = (DBSAXElement)elementStack.pop();
204
      
205
      // Write the content of the element to the database
206
      currentElement.writeContentToDB();
207
   }
208

    
209
   /** Debug routine */
210
   private void db(int flag) {
211
     if (debug) {
212
       System.err.println("DEBUG POSITION " + flag);
213
     }
214
   }   
215
}
(9-9/26)