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