Project

General

Profile

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