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