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