Project

General

Profile

1 17 jones
/**
2 203 jones
 *  '$RCSfile$'
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, Jivka Bojilova
8 17 jones
 *
9 203 jones
 *   '$Author$'
10
 *     '$Date$'
11
 * '$Revision$'
12 669 jones
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 17 jones
 */
27
28 75 jones
package edu.ucsb.nceas.metacat;
29 51 jones
30 6606 leinfelder
import java.sql.PreparedStatement;
31 2076 jones
import java.sql.ResultSet;
32
import java.sql.Statement;
33 6595 leinfelder
import java.util.Date;
34 2076 jones
import java.util.EmptyStackException;
35
import java.util.Enumeration;
36
import java.util.Hashtable;
37
import java.util.Stack;
38
import java.util.Vector;
39
40 5015 daigle
import edu.ucsb.nceas.metacat.database.DBConnection;
41
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
42 5030 daigle
import edu.ucsb.nceas.metacat.properties.PropertyService;
43 4425 daigle
import edu.ucsb.nceas.metacat.service.XMLSchema;
44 4698 daigle
import edu.ucsb.nceas.metacat.util.MetacatUtil;
45 1590 tao
import edu.ucsb.nceas.morpho.datapackage.Triple;
46
import edu.ucsb.nceas.morpho.datapackage.TripleCollection;
47 4080 daigle
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
48 4425 daigle
import edu.ucsb.nceas.utilities.StringUtil;
49 1590 tao
50 2663 sgarg
import org.apache.log4j.Logger;
51 185 jones
import org.xml.sax.Attributes;
52
import org.xml.sax.SAXException;
53 204 jones
import org.xml.sax.SAXParseException;
54 186 jones
import org.xml.sax.ext.DeclHandler;
55 185 jones
import org.xml.sax.ext.LexicalHandler;
56
import org.xml.sax.helpers.DefaultHandler;
57 17 jones
58 1359 tao
/**
59 31 jones
 * A database aware Class implementing callback bethods for the SAX parser to
60 2076 jones
 * call when processing the XML stream and generating events.
61 31 jones
 */
62 2076 jones
public class DBSAXHandler extends DefaultHandler implements LexicalHandler,
63 2730 sgarg
        DeclHandler
64 2076 jones
{
65 17 jones
66 2076 jones
    protected boolean atFirstElement;
67 17 jones
68 2076 jones
    protected boolean processingDTD;
69 220 jones
70 2076 jones
    protected String docname = null;
71 17 jones
72 2076 jones
    protected String doctype;
73 2620 tao
74
    protected String catalogid = null;
75 1359 tao
76 2076 jones
    protected String systemid;
77 1359 tao
78 2076 jones
    private boolean stackCreated = false;
79 1359 tao
80 4470 daigle
    protected Stack<DBSAXNode> nodeStack;
81 203 jones
82 4470 daigle
    protected Vector<DBSAXNode> nodeIndex;
83 72 bojilova
84 2076 jones
    protected DBConnection connection = null;
85
86
    protected DocumentImpl currentDocument;
87 2620 tao
88 6595 leinfelder
    protected Date createDate = null;
89 2620 tao
90 6595 leinfelder
    protected Date updateDate = null;
91 2076 jones
92
    protected DBSAXNode rootNode;
93
94
    protected String action = null;
95
96
    protected String docid = null;
97
98
    protected String revision = null;
99
100
    protected String user = null;
101
102
    protected String[] groups = null;
103
104
    protected String pub = null;
105 5752 leinfelder
106
	protected String encoding = null;
107 2076 jones
108 4470 daigle
//    private boolean endDocument = false;
109 2076 jones
110
    protected int serverCode = 1;
111
112 4470 daigle
    protected Hashtable<String,String> namespaces = new Hashtable<String,String>();
113 2076 jones
114
    protected boolean hitTextNode = false; // a flag to hit text node
115
116
    // a buffer to keep all text nodes for same element
117 4470 daigle
    // it is for if element was split
118 2076 jones
    protected StringBuffer textBuffer = new StringBuffer();
119
120 4470 daigle
//    protected Stack textBufferStack = new Stack();
121 2076 jones
122 5208 daigle
    public static final int MAXDATACHARS = 4000;
123 2076 jones
124
    //protected static final int MAXDATACHARS = 50;
125
126
    // methods writeChildNodeToDB, setAttribute, setNamespace,
127
    // writeTextForDBSAXNode will increase endNodeId.
128
    protected long endNodeId = -1; // The end node id for a substree
129
    // DOCTITLE attr cleared from the db
130
    //   private static final int MAXTITLELEN = 1000;
131 2590 tao
132
    private boolean isRevisionDoc  = false;
133 4425 daigle
134
    protected Vector<XMLSchema> schemaList = new Vector<XMLSchema>();
135 2076 jones
136
    //HandlerTriple stuff
137
    TripleCollection tripleList = new TripleCollection();
138
139
    Triple currentTriple = new Triple();
140
141
    boolean startParseTriple = false;
142
143
    boolean hasTriple = false;
144
145 2165 tao
    public static final String ECOGRID = "ecogrid://";
146
147 2663 sgarg
    private Logger logMetacat = Logger.getLogger(DBSAXHandler.class);
148
149 2076 jones
    /**
150
     * Construct an instance of the handler class
151 2165 tao
     *
152 2076 jones
     * @param conn the JDBC connection to which information is written
153
     */
154 6595 leinfelder
    private DBSAXHandler(DBConnection conn, Date createDate, Date updateDate)
155 2076 jones
    {
156
        this.connection = conn;
157
        this.atFirstElement = true;
158
        this.processingDTD = false;
159 2620 tao
        this.createDate = createDate;
160
        this.updateDate = updateDate;
161 2076 jones
162
        // Create the stack for keeping track of node context
163
        // if it doesn't already exist
164
        if (!stackCreated) {
165 4470 daigle
            nodeStack = new Stack<DBSAXNode>();
166
            nodeIndex = new Vector<DBSAXNode>();
167 2076 jones
            stackCreated = true;
168 1590 tao
        }
169 2076 jones
    }
170
171
    /**
172
     * Construct an instance of the handler class
173 2165 tao
     *
174 2076 jones
     * @param conn the JDBC connection to which information is written
175
     * @param action - "INSERT" or "UPDATE"
176
     * @param docid to be inserted or updated into JDBC connection
177
     * @param user the user connected to MetaCat servlet and owns the document
178
     * @param groups the groups to which user belongs
179
     * @param pub flag for public "read" access on document
180
     * @param serverCode the serverid from xml_replication on which this
181
     *            document resides.
182 2165 tao
     *
183 2076 jones
     */
184 2165 tao
/* TODO excise this constructor because not used anywhere in project
185 2076 jones
    public DBSAXHandler(DBConnection conn, String action, String docid,
186
            String user, String[] groups, String pub, int serverCode)
187
    {
188
        this(conn);
189
        this.action = action;
190
        this.docid = docid;
191
        this.user = user;
192
        this.groups = groups;
193
        this.pub = pub;
194
        this.serverCode = serverCode;
195
        this.xmlIndex = new Thread(this);
196
    }
197
*/
198
    /**
199
     * Construct an instance of the handler class In this constructor, user can
200
     * specify the version need to upadate
201 2165 tao
     *
202 2076 jones
     * @param conn the JDBC connection to which information is written
203
     * @param action - "INSERT" or "UPDATE"
204
     * @param docid to be inserted or updated into JDBC connection
205
     * @param revision, the user specified the revision need to be update
206
     * @param user the user connected to MetaCat servlet and owns the document
207
     * @param groups the groups to which user belongs
208
     * @param pub flag for public "read" access on document
209
     * @param serverCode the serverid from xml_replication on which this
210
     *            document resides.
211 2165 tao
     *
212 2076 jones
     */
213
    public DBSAXHandler(DBConnection conn, String action, String docid,
214
            String revision, String user, String[] groups, String pub,
215 6595 leinfelder
            int serverCode, Date createDate, Date updateDate)
216 2076 jones
    {
217 2620 tao
        this(conn, createDate, updateDate);
218 2076 jones
        this.action = action;
219
        this.docid = docid;
220
        this.revision = revision;
221
        this.user = user;
222
        this.groups = groups;
223
        this.pub = pub;
224
        this.serverCode = serverCode;
225
    }
226
227
    /** SAX Handler that receives notification of beginning of the document */
228
    public void startDocument() throws SAXException
229
    {
230 5208 daigle
        logMetacat.debug("DBSaxHandler.startDocument - starting document");
231 2076 jones
232
        // Create the document node representation as root
233
        rootNode = new DBSAXNode(connection, this.docid);
234
        // Add the node to the stack, so that any text data can be
235
        // added as it is encountered
236
        nodeStack.push(rootNode);
237
    }
238
239
    /** SAX Handler that receives notification of end of the document */
240 4080 daigle
	public void endDocument() throws SAXException {
241 5208 daigle
		logMetacat.debug("DBSaxHandler.endDocument - ending document");
242 4080 daigle
		// Starting new thread for writing XML Index.
243
		// It calls the run method of the thread.
244 2076 jones
245 4080 daigle
		try {
246 4470 daigle
			// if it is data package insert triple into relation table;
247 4080 daigle
			if (doctype != null
248 4698 daigle
					&& MetacatUtil.getOptionList(
249 4213 daigle
							PropertyService.getProperty("xml.packagedoctype")).contains(
250 4080 daigle
							doctype) && hasTriple && !isRevisionDoc) {
251 72 bojilova
252 4470 daigle
				// initial handler and write into relation db only for
253 4080 daigle
				// xml-documents
254
				if (!isRevisionDoc) {
255
					RelationHandler handler = new RelationHandler(docid, doctype,
256
							connection, tripleList);
257
				}
258
			}
259
		} catch (Exception e) {
260 5208 daigle
			logMetacat.error("DBSaxHandler.endDocument - Failed to write triples into relation table"
261 4080 daigle
					+ e.getMessage());
262
			throw new SAXException("Failed to write triples into relation table "
263
					+ e.getMessage());
264
		}
265 4425 daigle
266
		// If we get here, the document and schema parsed okay.  If there are
267
		// any schemas in the schema list, they are new and need to be registered.
268
    	for (XMLSchema xmlSchema : schemaList) {
269
    		String externalFileUri = xmlSchema.getExternalFileUri();
270
    		String fileNamespace = xmlSchema.getFileNamespace();
271
    		SchemaLocationResolver resolver =
272
    			new SchemaLocationResolver(fileNamespace, externalFileUri);
273
    		resolver.resolveNameSpace();
274
    	}
275 4080 daigle
	}
276
277 2076 jones
    /** SAX Handler that is called at the start of Namespace */
278
    public void startPrefixMapping(String prefix, String uri)
279
            throws SAXException
280
    {
281 5208 daigle
        logMetacat.debug("DBSaxHandler.startPrefixMapping - Starting namespace");
282 821 bojilova
283 2076 jones
        namespaces.put(prefix, uri);
284
    }
285 1359 tao
286 2076 jones
    /** SAX Handler that is called at the start of each XML element */
287
    public void startElement(String uri, String localName, String qName,
288
            Attributes atts) throws SAXException
289
    {
290
        // for element <eml:eml...> qname is "eml:eml", local name is "eml"
291
        // for element <acl....> both qname and local name is "eml"
292 4470 daigle
        // uri is namespace
293 5208 daigle
        logMetacat.debug("DBSaxHandler.startElement - Start ELEMENT(qName) " + qName);
294
        logMetacat.debug("DBSaxHandler.startElement - Start ELEMENT(localName) " + localName);
295
        logMetacat.debug("DBSaxHandler.startElement - Start ELEMENT(uri) " + uri);
296 17 jones
297 2076 jones
        DBSAXNode parentNode = null;
298
        DBSAXNode currentNode = null;
299 18 jones
300 2076 jones
        // Get a reference to the parent node for the id
301
        try {
302 2605 tao
303 2076 jones
            parentNode = (DBSAXNode) nodeStack.peek();
304
        } catch (EmptyStackException e) {
305
            parentNode = null;
306
        }
307 1359 tao
308 2076 jones
        // If hit a text node, we need write this text for current's parent
309 4470 daigle
        // node This will happen if the element is mixed
310 2076 jones
        if (hitTextNode && parentNode != null) {
311
            // write the textbuffer into db for parent node.
312
            endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer, parentNode);
313
            // rest hitTextNode
314
            hitTextNode = false;
315
            // reset textbuffer
316
            textBuffer = null;
317
            textBuffer = new StringBuffer();
318 2605 tao
319 2076 jones
        }
320 2605 tao
321 2076 jones
        // Document representation that points to the root document node
322
        if (atFirstElement) {
323
            atFirstElement = false;
324
            // If no DOCTYPE declaration: docname = root element
325
            // doctype = root element name or name space
326
            if (docname == null) {
327
                docname = localName;
328
                // if uri isn't null doctype = uri(namespace)
329 4470 daigle
                // otherwise root element
330 2076 jones
                if (uri != null && !(uri.trim()).equals("")) {
331
                    doctype = uri;
332
                } else {
333
                    doctype = docname;
334
                }
335 5208 daigle
                logMetacat.debug("DBSaxHandler.startElement - DOCNAME-a: " + docname);
336
                logMetacat.debug("DBSaxHandler.startElement - DOCTYPE-a: " + doctype);
337 2076 jones
            } else if (doctype == null) {
338
                // because docname is not null and it is declared in dtd
339
                // so could not be in schema, no namespace
340
                doctype = docname;
341 5208 daigle
                logMetacat.debug("DBSaxHandler.startElement - DOCTYPE-b: " + doctype);
342 1217 tao
            }
343 2605 tao
344 2076 jones
            rootNode.writeNodename(docname);
345 2605 tao
346 2076 jones
            try {
347
                // for validated XML Documents store a reference to XML DB
348
                // Catalog
349
                // Because this is select statement and it needn't to roll back
350
                // if
351 4470 daigle
                // insert document action failed.
352 2076 jones
                // In order to decrease DBConnection usage count, we get a new
353
                // dbconnection from pool
354 2620 tao
355 2076 jones
                DBConnection dbConn = null;
356
                int serialNumber = -1;
357 2605 tao
358 2076 jones
                if (systemid != null) {
359
                    try {
360
                        // Get dbconnection
361
                        dbConn = DBConnectionPool
362
                                .getDBConnection("DBSAXHandler.startElement");
363
                        serialNumber = dbConn.getCheckOutSerialNumber();
364 1359 tao
365 6606 leinfelder
                        String sql = "SELECT catalog_id FROM xml_catalog "
366
                            + "WHERE entry_type = 'DTD' "
367
                            + "AND public_id = ?";
368
369
                        PreparedStatement pstmt = dbConn.prepareStatement(sql);
370
                        pstmt.setString(1, doctype);
371
                        ResultSet rs = pstmt.executeQuery();
372 2076 jones
                        boolean hasRow = rs.next();
373
                        if (hasRow) {
374
                            catalogid = rs.getString(1);
375
                        }
376 6606 leinfelder
                        pstmt.close();
377 2076 jones
                    }//try
378
                    finally {
379
                        // Return dbconnection
380 6606 leinfelder
                        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
381 2076 jones
                    }//finally
382
                }
383 1359 tao
384 2076 jones
                //create documentImpl object by the constructor which can
385
                // specify
386
                //the revision
387 2605 tao
388
                if (!isRevisionDoc)
389
                {
390
                  currentDocument = new DocumentImpl(connection, rootNode
391 2076 jones
                        .getNodeID(), docname, doctype, docid, revision,
392 2620 tao
                        action, user, this.pub, catalogid, this.serverCode,
393
                        createDate, updateDate);
394 3221 berkley
                }
395 2076 jones
            } catch (Exception ane) {
396 5454 berkley
                ane.printStackTrace(System.out);
397
                ane.printStackTrace(System.err);
398
                throw (new SAXException("Error in DBSaxHandler.startElement for action "
399
                        + action + " : " + ane.getMessage(), ane));
400 2076 jones
            }
401
        }
402 1359 tao
403 2076 jones
        // Create the current node representation
404 2627 tao
        currentNode = new DBSAXNode(connection, qName, localName,
405
                parentNode, rootNode.getNodeID(), docid, doctype);
406 821 bojilova
407 2076 jones
        // Add all of the namespaces
408
        String prefix;
409
        String nsuri;
410 4470 daigle
        Enumeration<String> prefixes = namespaces.keys();
411 2076 jones
        while (prefixes.hasMoreElements()) {
412
            prefix = (String) prefixes.nextElement();
413
            nsuri = (String) namespaces.get(prefix);
414
            currentNode.setNamespace(prefix, nsuri, docid);
415
        }
416
        namespaces = null;
417 4470 daigle
        namespaces = new Hashtable<String,String>();
418 17 jones
419 2076 jones
        // Add all of the attributes
420
        for (int i = 0; i < atts.getLength(); i++) {
421
            String attributeName = atts.getQName(i);
422
            String attributeValue = atts.getValue(i);
423
            endNodeId = currentNode.setAttribute(attributeName, attributeValue,
424
                    docid);
425 1359 tao
426 2076 jones
            // To handle name space and schema location if the attribute name
427 4425 daigle
            // is xsi:schemaLocation. If the name space is in not in catalog
428
            // table it will be registered.
429 2076 jones
            if (attributeName != null
430
                    && attributeName
431
                            .indexOf(MetaCatServlet.SCHEMALOCATIONKEYWORD) != -1) {
432 4425 daigle
            	// These schemas will be registered in the end endDocument() method
433
            	// assuming parsing is successful.
434
        		// each namespace could have several schema locations.  parsedUri will
435
        		// hold a list of uri and files.
436
            	attributeValue = StringUtil.replaceTabsNewLines(attributeValue);
437
            	attributeValue = StringUtil.replaceDuplicateSpaces(attributeValue);
438
        		Vector<String> parsedUri = StringUtil.toVector(attributeValue, ' ');
439
        		for (int j = 0; j < parsedUri.size(); j = j + 2 ) {
440
        			if (j + 1 >= parsedUri.size()) {
441
        				throw new SAXException("Odd number of elements found when parsing schema location: " +
442
        						attributeValue + ". There should be an even number of uri/files in location.");
443
        			}
444
        			XMLSchema xmlSchema =
445
        				new XMLSchema(parsedUri.get(j), parsedUri.get(j + 1));
446
        			schemaList.add(xmlSchema);
447
        		}
448 2076 jones
            }
449
        }
450
451
        // Add the node to the stack, so that any text data can be
452 4080 daigle
		// added as it is encountered
453
		nodeStack.push(currentNode);
454
		// Add the node to the vector used by thread for writing XML Index
455
		nodeIndex.addElement(currentNode);
456
		// start parsing triple
457
		try {
458
			if (doctype != null
459 4698 daigle
					&& MetacatUtil.getOptionList(
460 4213 daigle
							PropertyService.getProperty("xml.packagedoctype")).contains(doctype)
461 4080 daigle
					&& localName.equals("triple")) {
462
				startParseTriple = true;
463
				hasTriple = true;
464
				currentTriple = new Triple();
465
			}
466
		} catch (PropertyNotFoundException pnfe) {
467 5454 berkley
			pnfe.printStackTrace(System.out);
468
			pnfe.printStackTrace(System.err);
469
			throw (new SAXException("Error in DBSaxHandler.startElement for action " + action +
470
			        " : " + pnfe.getMessage(), pnfe));
471 4080 daigle
		}
472
	}
473
474 2076 jones
475
    /** SAX Handler that is called for each XML text node */
476
    public void characters(char[] cbuf, int start, int len) throws SAXException
477 1841 tao
    {
478 5208 daigle
        logMetacat.debug("DBSaxHandler.characters - starting characters");
479 4470 daigle
        // buffer all text nodes for same element. This is for if text was split
480 2076 jones
        // into different nodes
481
        textBuffer.append(new String(cbuf, start, len));
482
        // set hittextnode true
483
        hitTextNode = true;
484
        // if text buffer .size is greater than max, write it to db.
485
        // so we can save memory
486
        if (textBuffer.length() > MAXDATACHARS) {
487 5208 daigle
            logMetacat.debug("DBSaxHandler.characters - Write text into DB in charaters"
488 2663 sgarg
                    + " when text buffer size is greater than maxmum number");
489 2076 jones
            DBSAXNode currentNode = (DBSAXNode) nodeStack.peek();
490
            endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer,
491
                    currentNode);
492
            textBuffer = null;
493
            textBuffer = new StringBuffer();
494 899 berkley
        }
495 2076 jones
    }
496
497
    /**
498
     * SAX Handler that is called for each XML text node that is Ignorable
499
     * white space
500
     */
501
    public void ignorableWhitespace(char[] cbuf, int start, int len)
502
            throws SAXException
503 1841 tao
    {
504 2076 jones
        // When validation is turned "on", white spaces are reported here
505
        // When validation is turned "off" white spaces are not reported here,
506
        // but through characters() callback
507 5208 daigle
        logMetacat.debug("DBSaxHandler.ignorableWhitespace - in ignorableWhitespace");
508 2076 jones
509
        DBSAXNode currentNode = (DBSAXNode) nodeStack.peek();
510
511
            // Write the content of the node to the database
512 5208 daigle
            endNodeId = currentNode.writeChildNodeToDB("TEXT", null, new String(cbuf, start, len),
513 2076 jones
                    docid);
514 1217 tao
    }
515 2076 jones
516
    /**
517
     * SAX Handler called once for each processing instruction found: node that
518
     * PI may occur before or after the root element.
519
     */
520
    public void processingInstruction(String target, String data)
521
            throws SAXException
522 1217 tao
    {
523 5208 daigle
        logMetacat.debug("DBSaxHandler.processingInstruction - in processing instructions");
524 2076 jones
        DBSAXNode currentNode = (DBSAXNode) nodeStack.peek();
525
        endNodeId = currentNode.writeChildNodeToDB("PI", target, data, docid);
526
    }
527 1359 tao
528 2076 jones
    /** SAX Handler that is called at the end of each XML element */
529
    public void endElement(String uri, String localName, String qName)
530
            throws SAXException
531
    {
532 5208 daigle
        logMetacat.debug("DBSaxHandler.endElement - End element " + qName);
533 660 bojilova
534 2076 jones
        // write buffered text nodes into db (so no splited)
535
        DBSAXNode currentNode = (DBSAXNode) nodeStack.peek();
536 1359 tao
537 2076 jones
        // If before the end element, the parser hit text nodes and store them
538
        // into the buffer, write the buffer to data base. The reason we put
539
        // write database here is for xerces some time split text node
540
        if (hitTextNode) {
541 5208 daigle
            logMetacat.debug("DBSaxHandler.endElement - Write text into DB in End Element");
542 2076 jones
            endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer,
543
                    currentNode);
544 1359 tao
545 2076 jones
            //if it is triple parsing process
546
            if (startParseTriple) {
547 660 bojilova
548 2076 jones
                String content = textBuffer.toString().trim();
549
                if (localName.equals("subject")) { //get the subject content
550
                    currentTriple.setSubject(content);
551
                } else if (localName.equals("relationship")) { //get the
552
                                                               // relationship
553
                                                               // content
554
                    currentTriple.setRelationship(content);
555
                } else if (localName.equals("object")) { //get the object
556
                                                         // content
557
                    currentTriple.setObject(content);
558
                }
559
            }
560 17 jones
561 2076 jones
        }//if
562 72 bojilova
563 2076 jones
        //set hitText false
564
        hitTextNode = false;
565
        // reset textbuff
566
        textBuffer = null;
567
        textBuffer = new StringBuffer();
568 17 jones
569 2076 jones
        // Get the node from the stack
570
        currentNode = (DBSAXNode) nodeStack.pop();
571
        //finishing parsing single triple
572
        if (startParseTriple && localName.equals("triple")) {
573
            // add trip to triple collection
574
            tripleList.addTriple(currentTriple);
575
            //rest variable
576
            currentTriple = null;
577
            startParseTriple = false;
578
        }
579
    }
580 17 jones
581 2076 jones
    //
582
    // the next section implements the LexicalHandler interface
583
    //
584 185 jones
585 2076 jones
    /** SAX Handler that receives notification of DOCTYPE. Sets the DTD */
586
    public void startDTD(String name, String publicId, String systemId)
587
            throws SAXException
588
    {
589
        docname = name;
590
        doctype = publicId;
591
        systemid = systemId;
592 185 jones
593 2076 jones
        processingDTD = true;
594
        DBSAXNode currentNode = (DBSAXNode) nodeStack.peek();
595
        //create a DTD node and write docname,publicid and system id into db
596
        // we don't put the dtd node into node stack
597
        DBSAXNode dtdNode = new DBSAXNode(connection, name, publicId, systemId,
598
                currentNode, currentNode.getRootNodeID(), docid);
599 5208 daigle
        logMetacat.debug("DBSaxHandler.startDTD - Start DTD");
600
        logMetacat.debug("DBSaxHandler.startDTD - Setting processingDTD to true");
601
        logMetacat.debug("DBSaxHandler.startDTD - DOCNAME: " + docname);
602
        logMetacat.debug("DBSaxHandler.startDTD - DOCTYPE: " + doctype);
603
        logMetacat.debug("DBSaxHandler.startDTD - SYSID: " + systemid);
604 2076 jones
    }
605 185 jones
606 2076 jones
    /**
607
     * SAX Handler that receives notification of end of DTD
608
     */
609
    public void endDTD() throws SAXException
610
    {
611 1359 tao
612 2076 jones
        processingDTD = false;
613 5208 daigle
        logMetacat.debug("DBSaxHandler.endDTD - Setting processingDTD to false");
614
        logMetacat.debug("DBSaxHandler.endDTD - end DTD");
615 2076 jones
    }
616 185 jones
617 2076 jones
    /**
618
     * SAX Handler that receives notification of comments in the DTD
619
     */
620
    public void comment(char[] ch, int start, int length) throws SAXException
621
    {
622 5208 daigle
        logMetacat.debug("DBSaxHandler.comment - starting comment");
623 2076 jones
        if (!processingDTD) {
624
            DBSAXNode currentNode = (DBSAXNode) nodeStack.peek();
625
            endNodeId = currentNode.writeChildNodeToDB("COMMENT", null,
626
                    new String(ch, start, length), docid);
627
        }
628
    }
629 185 jones
630 2076 jones
    /**
631
     * SAX Handler that receives notification of the start of CDATA sections
632
     */
633
    public void startCDATA() throws SAXException
634
    {
635 5208 daigle
        logMetacat.debug("DBSaxHandler.startCDATA - starting CDATA");
636 2076 jones
    }
637 185 jones
638 2076 jones
    /**
639
     * SAX Handler that receives notification of the end of CDATA sections
640
     */
641
    public void endCDATA() throws SAXException
642
    {
643 5208 daigle
        logMetacat.debug("DBSaxHandler.endCDATA - end CDATA");
644 2076 jones
    }
645 185 jones
646 2076 jones
    /**
647
     * SAX Handler that receives notification of the start of entities
648
     */
649
    public void startEntity(String name) throws SAXException
650
    {
651 5208 daigle
        logMetacat.debug("DBSaxHandler.startEntity - starting entity: " + name);
652 2076 jones
        //System.out.println("start ENTITY: " + name);
653
        if (name.equals("[dtd]")) {
654
            processingDTD = true;
655
        }
656
    }
657 185 jones
658 2076 jones
    /**
659
     * SAX Handler that receives notification of the end of entities
660
     */
661
    public void endEntity(String name) throws SAXException
662
    {
663 5208 daigle
        logMetacat.debug("DBSaxHandler.endEntity - ending entity: " + name);
664 2076 jones
        //System.out.println("end ENTITY: " + name);
665
        if (name.equals("[dtd]")) {
666
            processingDTD = false;
667
        }
668
    }
669 186 jones
670 2076 jones
    /**
671
     * SAX Handler that receives notification of element declarations
672
     */
673
    public void elementDecl(String name, String model)
674
            throws org.xml.sax.SAXException
675
    {
676
        //System.out.println("ELEMENTDECL: " + name + " " + model);
677 5208 daigle
        logMetacat.debug("DBSaxHandler.elementDecl - element declaration: " + name + " " + model);
678 2076 jones
    }
679 186 jones
680 2076 jones
    /**
681
     * SAX Handler that receives notification of attribute declarations
682
     */
683
    public void attributeDecl(String eName, String aName, String type,
684
            String valueDefault, String value) throws org.xml.sax.SAXException
685
    {
686 821 bojilova
687 2076 jones
        //System.out.println("ATTRIBUTEDECL: " + eName + " "
688
        //                        + aName + " " + type + " " + valueDefault + " "
689
        //                        + value);
690 5208 daigle
        logMetacat.debug("DBSaxHandler.attributeDecl - attribute declaration: " + eName + " " + aName + " "
691 2663 sgarg
                + type + " " + valueDefault + " " + value);
692 2076 jones
    }
693 186 jones
694 2076 jones
    /**
695
     * SAX Handler that receives notification of internal entity declarations
696
     */
697
    public void internalEntityDecl(String name, String value)
698
            throws org.xml.sax.SAXException
699
    {
700
        //System.out.println("INTERNENTITYDECL: " + name + " " + value);
701 5208 daigle
        logMetacat.debug("DBSaxHandler.internalEntityDecl - internal entity declaration: " + name + " " + value);
702 2076 jones
    }
703 186 jones
704 2076 jones
    /**
705
     * SAX Handler that receives notification of external entity declarations
706
     */
707
    public void externalEntityDecl(String name, String publicId, String systemId)
708
            throws org.xml.sax.SAXException
709
    {
710
        //System.out.println("EXTERNENTITYDECL: " + name + " " + publicId
711
        //                              + " " + systemId);
712 5208 daigle
        logMetacat.debug("DBSaxHandler.externalEntityDecl - external entity declaration: " + name + " " + publicId
713 2663 sgarg
                + " " + systemId);
714 2076 jones
        // it processes other external entity, not the DTD;
715
        // it doesn't signal for the DTD here
716
        processingDTD = false;
717
    }
718 186 jones
719 2076 jones
    //
720
    // the next section implements the ErrorHandler interface
721
    //
722 186 jones
723 2076 jones
    /**
724
     * SAX Handler that receives notification of fatal parsing errors
725
     */
726
    public void fatalError(SAXParseException exception) throws SAXException
727
    {
728 5208 daigle
        logMetacat.fatal("DBSaxHandler.fatalError - " + exception.getMessage());
729 2076 jones
        throw (new SAXException("Fatal processing error.", exception));
730
    }
731 204 jones
732 2076 jones
    /**
733
     * SAX Handler that receives notification of recoverable parsing errors
734
     */
735
    public void error(SAXParseException exception) throws SAXException
736
    {
737 5208 daigle
        logMetacat.error("DBSaxHandler.error - " + exception.getMessage());
738 5888 leinfelder
        throw (new SAXException(exception.getMessage(), exception));
739 2076 jones
    }
740 204 jones
741 2076 jones
    /**
742
     * SAX Handler that receives notification of warnings
743
     */
744
    public void warning(SAXParseException exception) throws SAXException
745
    {
746 5208 daigle
        logMetacat.warn("DBSaxHandler.warning - " + exception.getMessage());
747 5888 leinfelder
        throw (new SAXException(exception.getMessage(), exception));
748 2076 jones
    }
749 204 jones
750 2076 jones
    //
751
    // Helper, getter and setter methods
752
    //
753 1359 tao
754 2076 jones
    /**
755
     * get the document name
756
     */
757
    public String getDocname()
758
    {
759
        return docname;
760
    }
761 204 jones
762 2076 jones
    /**
763
     * get the document processing state
764
     */
765
    public boolean processingDTD()
766
    {
767
        return processingDTD;
768
    }
769 2590 tao
770
771
    /**
772
     * get the the is revision doc
773
     * @return
774
     */
775
    public boolean getIsRevisionDoc()
776
    {
777
        return isRevisionDoc;
778
    }
779
780
    /**
781
     * Set the the handler is for revisionDoc
782
     * @param isRevisionDoc
783
     */
784
    public void setIsRevisionDoc(boolean isRevisionDoc)
785
    {
786
       this.isRevisionDoc = isRevisionDoc;
787
    }
788 2076 jones
789 5752 leinfelder
    public String getEncoding() {
790
		return encoding;
791
	}
792
793
	public void setEncoding(String encoding) {
794
		this.encoding = encoding;
795
	}
796
797
	/* Method to write a text buffer for DBSAXNode */
798 2076 jones
    protected long writeTextForDBSAXNode(long previousEndNodeId,
799
            StringBuffer strBuffer, DBSAXNode node) throws SAXException
800
    {
801
        long nodeId = previousEndNodeId;
802
        // Check parameter
803
        if (strBuffer == null || node == null) { return nodeId; }
804
        boolean moredata = true;
805 2352 sgarg
806
        String normalizedData = strBuffer.toString();
807 5208 daigle
        logMetacat.debug("DBSAXHandler.writeTextForDBSAXNode - Before normalize in write process: " + normalizedData);
808 4698 daigle
        String afterNormalize = MetacatUtil.normalize(normalizedData);
809 5208 daigle
        logMetacat.debug("DBSAXHandler.writeTextForDBSAXNode - After normalize in write process: " + afterNormalize);
810 3731 tao
        strBuffer = new StringBuffer(afterNormalize);;
811 2352 sgarg
812 2076 jones
        int bufferSize = strBuffer.length();
813
        int start = 0;
814
815
        // if there are some cotent in buffer, write it
816
        if (bufferSize > 0) {
817 5208 daigle
            logMetacat.debug("DBSAXHandler.writeTextForDBSAXNode - Write text into DB");
818 2076 jones
819
                // Write the content of the node to the database
820 5208 daigle
                nodeId = node.writeChildNodeToDB("TEXT", null, new String(strBuffer), docid);
821 2076 jones
        }//if
822
        return nodeId;
823
    }
824 2605 tao
825
    public long getRootNodeId()
826
    {
827
        return rootNode.getNodeID();
828
    }
829 2620 tao
830
    public String getDocumentType()
831
    {
832
        return doctype;
833
    }
834
835
    public String getDocumentName()
836
    {
837
        return docname;
838
    }
839
840
    public String getCatalogId()
841
    {
842
        return catalogid;
843
    }
844 17 jones
}