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