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 98 2000-05-13 01:29:51Z 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

    
35
   static int elementNo = 0;
36
   static String docname;
37
   private DBSAXDocument currentDocument;
38
   private String doctype;
39
   private String systemid;
40
   private long rootnodeid = 0;
41
   private boolean 	debug 	= false;
42
   private boolean 	stackCreated = false;
43
   private Stack 	elementStack;
44
   private Connection	conn = null;
45

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

    
54
      // Create the stack for keeping track of element context
55
      // if it doesn't already exist
56
      if (!stackCreated) {
57
        elementStack = new Stack();
58
        stackCreated = true;
59
      }
60

    
61
   }
62
 
63
   /** SAX Handler that receives notification of beginning of the document */
64
   public void startDocument() throws SAXException
65
   {
66
    System.out.println("start Document");
67
   }
68

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

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

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

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

    
107
      // Use the methods getQualifiedName(), getLocalName(), getNamespace()
108
      // and getExpandedName() in NSName interface to get Namespace
109
      // information.
110

    
111
      String qName;
112
      String localName;
113
      String nsName;
114
      String expName;
115
      DBSAXElement parentElement;
116
      DBSAXElement currentElement;
117

    
118
      qName = name.getQualifiedName();
119
      localName = name.getLocalName();
120
      nsName = name.getNamespace();
121
      expName = name.getExpandedName();
122
      
123
      elementNo++;
124
      if (docname == null)
125
        throw new SAXException("No DOCTYPE declaration provided");
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
      // Create the current element representation
139
      currentElement = new DBSAXElement(conn, localName, parent_id, nodeIndex);
140
      // go to create document definition in the db
141
      // call once after insertion of the first element
142
      if (parent_id == 0) {
143
        this.rootnodeid = currentElement.getElementID();
144
        currentDocument = new DBSAXDocument(conn, rootnodeid, docname, doctype);
145
      }
146

    
147
      // Add all of the attributes
148
      for (int i=0; i<atts.getLength(); i++)
149
      {
150

    
151
         // Use the methods getQualifiedName(), getLocalName(), getNamespace()
152
         // and getExpandedName() in SAXAttrList interface to get Namespace
153
         // information.
154

    
155
         qName = atts.getQualifiedName(i);
156
         localName = atts.getLocalName(i);
157
         nsName = atts.getNamespace(i);
158
         expName = atts.getExpandedName(i);
159

    
160
         // You can get the type and value of the attributes either
161
         // by index or by the Qualified Name.
162

    
163
         String type = atts.getType(qName);
164
         String value = atts.getValue(qName);
165

    
166
         currentElement.setAttribute(localName, value);
167
      }      
168

    
169
      // Add the element to the stack, so that any text data can be 
170
      // added as it is encountered
171
      elementStack.push(currentElement);
172

    
173
   }
174

    
175
   /** SAX Handler that is called for each XML text node */
176
   public void characters(char[] cbuf, int start, int len)
177
   {
178
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
179
      currentElement.appendContent(cbuf,start,len);
180
   }
181

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

    
190
   /** SAX Handler called once for each comment found: 
191
     * node that comment may occur before or after the root element.
192
     * For now works only for comments after the root element. */
193
   public void comment(String data) throws SAXException
194
   {
195
    if (elementNo > 0) {
196
      DBSAXElement currentElement = (DBSAXElement)elementStack.peek();
197
      int nodeIndex = currentElement.incChildNum();
198
      currentElement.writeCommentToDB(data, nodeIndex);
199
    }
200
   }
201
   public void processingInstruction(String target, String data) throws SAXException
202
   {
203
    if (elementNo == 0)
204
        System.out.println("target:" + target + "\ndata:" + data);
205
    else if (elementNo > 0)
206
        System.out.println("targetHere:" + target + "\ndata:" + data);
207
   }
208

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

    
217
      // Get the element from the stack
218
      DBSAXElement currentElement = (DBSAXElement)elementStack.pop();
219
      
220
      // Write the content of the element to the database
221
      currentElement.writeContentToDB();
222
   }
223

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