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