Project

General

Profile

1
/**
2
 *  '$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
 *    Release: @release@
9
 *
10
 *   '$Author: tao $'
11
 *     '$Date: 2003-02-11 15:08:46 -0800 (Tue, 11 Feb 2003) $'
12
 * '$Revision: 1396 $'
13
 *
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
 */
28

    
29
package edu.ucsb.nceas.metacat;
30

    
31
import java.sql.*;
32
import java.io.StringReader;
33
import java.util.Stack;
34
import java.util.Vector;
35
import java.util.Hashtable;
36
import java.util.Enumeration;
37
import java.util.EmptyStackException;
38

    
39
import org.xml.sax.Attributes;
40
import org.xml.sax.SAXException;
41
import org.xml.sax.SAXParseException;
42
import org.xml.sax.ext.DeclHandler;
43
import org.xml.sax.ext.LexicalHandler;
44
import org.xml.sax.helpers.DefaultHandler;
45

    
46
/**
47
 * A database aware Class implementing callback bethods for the SAX parser to
48
 * call when processing the XML stream and generating events
49
 */
50
public class DBSAXHandler extends DefaultHandler
51
                          implements LexicalHandler, DeclHandler, Runnable {
52

    
53
   protected boolean	atFirstElement;
54
   private boolean	processingDTD;
55
   protected String 	docname = null;
56
   protected String 	doctype;
57
   protected String 	systemid;
58
   private boolean 	stackCreated = false;
59
   protected Stack 	  nodeStack;
60
   protected Vector   nodeIndex;
61
   protected DBConnection	  connection = null;
62
   protected DocumentImpl currentDocument;
63
   protected DBSAXNode    rootNode;
64
   protected String   action = null;
65
   protected String   docid = null;
66
   protected String   revision = null;
67
   protected String   user = null;
68
   protected String[] groups = null;
69
   protected String   pub = null;
70
   protected Thread   xmlIndex;
71
   private boolean endDocument = false;
72
   protected int serverCode = 1;
73
   protected Hashtable namespaces = new Hashtable();
74

    
75
   private static final int MAXDATACHARS = 4000;
76
   protected static final long INDEXDELAY = 10000;
77
// DOCTITLE attr cleared from the db
78
//   private static final int MAXTITLELEN = 1000;
79

    
80
   /** Construct an instance of the handler class
81
    *
82
    * @param conn the JDBC connection to which information is written
83
    */
84
   public DBSAXHandler(DBConnection conn) {
85
     this.connection = conn;
86
     this.atFirstElement = true;
87
     this.processingDTD = false;
88

    
89
     // Create the stack for keeping track of node context
90
     // if it doesn't already exist
91
     if (!stackCreated) {
92
       nodeStack = new Stack();
93
       nodeIndex = new Vector();
94
       stackCreated = true;
95
     }
96
   }
97

    
98
  /** Construct an instance of the handler class
99
    *
100
    * @param conn the JDBC connection to which information is written
101
    * @param action - "INSERT" or "UPDATE"
102
    * @param docid to be inserted or updated into JDBC connection
103
    * @param user the user connected to MetaCat servlet and owns the document
104
    * @param groups the groups to which user belongs
105
    * @param pub flag for public "read" access on document
106
    * @param serverCode the serverid from xml_replication on which this document
107
    *        resides.
108
    *
109
    */
110
   public DBSAXHandler(DBConnection conn, String action, String docid,
111
                      String user, String[] groups, String pub, int serverCode)
112
   {
113
     this(conn);
114
     this.action = action;
115
     this.docid = docid;
116
     this.user = user;
117
     this.groups = groups;
118
     this.pub = pub;
119
     this.serverCode = serverCode;
120
     this.xmlIndex = new Thread(this);
121
   }
122

    
123
  /** Construct an instance of the handler class
124
    * In this constructor, user can specify the version need to upadate
125
    *
126
    * @param conn the JDBC connection to which information is written
127
    * @param action - "INSERT" or "UPDATE"
128
    * @param docid to be inserted or updated into JDBC connection
129
    * @param revision, the user specified the revision need to be update
130
    * @param user the user connected to MetaCat servlet and owns the document
131
    * @param groups the groups to which user belongs
132
    * @param pub flag for public "read" access on document
133
    * @param serverCode the serverid from xml_replication on which this document
134
    *        resides.
135
    *
136
    */
137
   public DBSAXHandler(DBConnection conn, String action, String docid,
138
     String revision, String user, String[] groups, String pub, int serverCode)
139
   {
140
     this(conn);
141
     this.action = action;
142
     this.docid = docid;
143
     this.revision = revision;
144
     this.user = user;
145
     this.groups = groups;
146
     this.pub = pub;
147
     this.serverCode = serverCode;
148
     this.xmlIndex = new Thread(this);
149
   }
150

    
151
   /** SAX Handler that receives notification of beginning of the document */
152
   public void startDocument() throws SAXException {
153
     MetaCatUtil.debugMessage("start Document", 50);
154

    
155
     // Create the document node representation as root
156
     rootNode = new DBSAXNode(connection, this.docid);
157
     // Add the node to the stack, so that any text data can be
158
     // added as it is encountered
159
     nodeStack.push(rootNode);
160
   }
161

    
162
   /** SAX Handler that receives notification of end of the document */
163
   public void endDocument() throws SAXException {
164
     MetaCatUtil.debugMessage("end Document", 50);
165
     // Starting new thread for writing XML Index.
166
     // It calls the run method of the thread.
167
     try {
168
       xmlIndex.start();
169
     } catch (NullPointerException e) {
170
       xmlIndex = null;
171
       throw new
172
       SAXException("Problem with starting thread for writing XML Index. " +
173
                    e.getMessage());
174
     }
175
   }
176

    
177
   /** SAX Handler that is called at the start of Namespace */
178
   public void startPrefixMapping(String prefix, String uri)
179
                                          throws SAXException
180
   {
181
    MetaCatUtil.debugMessage("NAMESPACE", 50);
182

    
183
    namespaces.put(prefix, uri);
184
   }
185

    
186
   /** SAX Handler that is called at the start of each XML element */
187
   public void startElement(String uri, String localName,
188
                            String qName, Attributes atts)
189
               throws SAXException {
190
     // for element <eml:eml...> qname is "eml:eml", local name is "eml"            
191
     // for element <acl....> both qname and local name is "eml"
192
     // uri is namesapce
193
     MetaCatUtil.debugMessage("Start ELEMENT(qName) " + qName, 50);
194
     MetaCatUtil.debugMessage("Start ELEMENT(localName) " + localName, 50);
195
     MetaCatUtil.debugMessage("Start ELEMENT(uri) " + uri, 50);
196
     
197
     
198
     DBSAXNode parentNode = null;
199
     DBSAXNode currentNode = null;
200

    
201
     // Get a reference to the parent node for the id
202
     try {
203
       parentNode = (DBSAXNode)nodeStack.peek();
204
     } catch (EmptyStackException e) {
205
       parentNode = null;
206
     }
207

    
208
     // Document representation that points to the root document node
209
     if (atFirstElement) 
210
     {
211
       atFirstElement = false;
212
       // If no DOCTYPE declaration: docname = root element
213
       // doctype = root element name or name space
214
       if (docname == null) 
215
       {
216
         docname = localName;
217
         // if uri isn't null doctype = uri(namespace)
218
         // othewise root element
219
         if (uri != null && !(uri.trim()).equals(""))
220
         {
221
           doctype = uri;
222
         }
223
         else
224
         {
225
           doctype = docname;
226
         }
227
         MetaCatUtil.debugMessage("DOCNAME-a: " + docname, 30);
228
         MetaCatUtil.debugMessage("DOCTYPE-a: " + doctype, 30);
229
       } 
230
       else if (doctype == null) 
231
       {
232
         // because docname is not null and it is declared in dtd
233
         // so could not be in schema, no namespace
234
         doctype = docname;
235
         MetaCatUtil.debugMessage("DOCTYPE-b: " + doctype, 30);
236
       }
237
       rootNode.writeNodename(docname);
238
       try {
239
         // for validated XML Documents store a reference to XML DB Catalog
240
         // Because this is select statement and it needn't to roll back if
241
         // insert document action fialed.
242
         // In order to decrease DBConnection usage count, we get a new
243
         // dbconnection from pool
244
         String catalogid = null;
245
         DBConnection dbConn = null;
246
         int serialNumber = -1;
247

    
248
         if ( systemid != null ) {
249
           try
250
           {
251
            // Get dbconnection
252
            dbConn=DBConnectionPool.getDBConnection
253
                                          ("DBSAXHandler.startElement");
254
            serialNumber=dbConn.getCheckOutSerialNumber();
255

    
256
            Statement stmt = dbConn.createStatement();
257
            ResultSet rs = stmt.executeQuery(
258
                          "SELECT catalog_id FROM xml_catalog " +
259
                          "WHERE entry_type = 'DTD' " +
260
                          "AND public_id = '" + doctype + "'");
261
            boolean hasRow = rs.next();
262
            if ( hasRow ) {
263
              catalogid = rs.getString(1);
264
            }
265
            stmt.close();
266
           }//try
267
           finally
268
           {
269
             // Return dbconnection
270
             DBConnectionPool.returnDBConnection(dbConn, serialNumber);
271
           }//finally
272
         }
273

    
274
         //create documentImpl object by the constructor which can specify
275
         //the revision
276
         currentDocument = new DocumentImpl(connection, rootNode.getNodeID(),
277
                               docname, doctype, docid, revision, action, user,
278
                               this.pub, catalogid, this.serverCode);
279

    
280

    
281
       } catch (Exception ane) {
282
         throw (new SAXException("Error in DBSaxHandler.startElement " +
283
                                 action, ane));
284
       }
285
     }
286

    
287
     // Create the current node representation
288
     currentNode = new DBSAXNode(connection, qName, localName, parentNode,
289
                                 currentDocument.getRootNodeID(),docid,
290
                                 currentDocument.getDoctype());
291

    
292
     // Add all of the namespaces
293
     String prefix;
294
     String nsuri;
295
     Enumeration prefixes = namespaces.keys();
296
     while ( prefixes.hasMoreElements() ) {
297
       prefix = (String)prefixes.nextElement();
298
       nsuri = (String)namespaces.get(prefix);
299
       currentNode.setNamespace(prefix, nsuri, docid);
300
     }
301
     namespaces = null;
302
     namespaces = new Hashtable();
303

    
304
     // Add all of the attributes
305
     for (int i=0; i<atts.getLength(); i++) 
306
     {
307
       String attributeName = atts.getQName(i);
308
       String attributeValue = atts.getValue(i);
309
       currentNode.setAttribute(attributeName, attributeValue, docid);
310
       
311
       // To handle name space and schema location if the attribute name is
312
       // xsi:schemaLocation. If the name space is in not in catalog table
313
       // it will be regeistered.
314
       if (attributeName != null && 
315
           attributeName.indexOf(MetaCatServlet.SCHEMALOCATIONKEYWORD) != -1)
316
       {
317
         SchemaLocationResolver resolver = 
318
                                  new SchemaLocationResolver(attributeValue);
319
         resolver.resolveNameSpace();
320
         
321
       }
322
     }
323

    
324
     // Add the node to the stack, so that any text data can be
325
     // added as it is encountered
326
     nodeStack.push(currentNode);
327
     // Add the node to the vector used by thread for writing XML Index
328
     nodeIndex.addElement(currentNode);
329

    
330
  }
331

    
332
  /* The run method of xmlIndex thread. It writes XML Index for the document. */
333
  public void run () {
334
    DBSAXNode currNode = null;
335
    DBSAXNode prevNode = null;
336
    DBConnection dbConn = null;
337
    int serialNumber = -1;
338
    String doctype = currentDocument.getDoctype();
339
    int step = 0;
340
    int counter = 0;
341

    
342
    try {
343

    
344
      // Opening separate db connection for writing XML Index
345
      dbConn=DBConnectionPool.getDBConnection("DBSAXHandler.run");
346
      serialNumber=dbConn.getCheckOutSerialNumber();
347
      dbConn.setAutoCommit(false);
348

    
349
      //the following while loop construct checks to make sure that the docid
350
      //of the document that we are trying to index is already
351
      //in the xml_documents table.  if this is not the case, the foreign
352
      //key relationship between xml_documents and xml_index is temporarily
353
      //broken causing multiple problems.
354
      boolean inxmldoc = false;
355
      long startTime = System.currentTimeMillis();
356
      while(!inxmldoc)
357
      {
358
        String xmlDocumentsCheck = "select distinct docid from xml_documents";
359
        PreparedStatement xmlDocCheck =
360
                                 dbConn.prepareStatement(xmlDocumentsCheck);
361
        // Increase usage count
362
        dbConn.increaseUsageCount(1);
363
        xmlDocCheck.execute();
364
        ResultSet doccheckRS = xmlDocCheck.getResultSet();
365
        boolean tableHasRows = doccheckRS.next();
366
        Vector docids = new Vector();
367
        while(tableHasRows)
368
        {
369
          docids.add(doccheckRS.getString(1).trim());
370
          tableHasRows = doccheckRS.next();
371
        }
372

    
373
        for(int i=0; i<docids.size(); i++)
374
        {
375
          String d = ((String)docids.elementAt(i)).trim();
376
          if(docid.trim().equals(d))
377
          {
378
            inxmldoc = true;
379
          }
380
        }
381
        doccheckRS.close();
382
        xmlDocCheck.close();
383
        // make sure the while loop will be ended in reseaonable time
384
        long stopTime = System.currentTimeMillis();
385
        if ((stopTime - startTime) > INDEXDELAY)
386
        {
387
          throw new Exception("Couldn't find the docid for index build in" +
388
                              "reseaonable time!");
389
        }
390
      }
391

    
392
      // Going through the elements of the document and writing its Index
393
      Enumeration nodes = nodeIndex.elements();
394
      while ( nodes.hasMoreElements() ) {
395
        currNode = (DBSAXNode)nodes.nextElement();
396
        currNode.updateNodeIndex(dbConn, docid, doctype);
397
      }
398

    
399

    
400
      dbConn.commit();
401

    
402
      //if this is a package file
403
      String packagedoctype = MetaCatUtil.getOption("packagedoctype");
404
      Vector packagedoctypes = new Vector();
405

    
406
      packagedoctypes = MetaCatUtil.getOptionList(packagedoctype);
407

    
408
      if ( packagedoctypes.contains(doctype) )
409
      {
410
        // write the package info to xml_relation table
411
        RelationHandler rth = new RelationHandler(docid, dbConn);
412
        // from the relations get the access file id for that package
413
        String aclid = rth.getAccessFileID(docid);
414
        // if there are access file, write ACL for that package
415
        if ( aclid != null ) {
416
          runAccessControlList(dbConn, aclid);
417
        }
418

    
419
      }
420

    
421
   
422

    
423
    } catch (Exception e) {
424
      try {
425
        dbConn.rollback();
426
        //dbconn.close();
427
      } catch (SQLException sqle) {}
428
      MetaCatUtil.debugMessage("Error in DBSAXHandler.run " + 
429
                                e.getMessage(), 30);
430
      
431
    }
432
    finally
433
    {
434
      DBConnectionPool.returnDBConnection(dbConn, serialNumber);
435
    }//finally
436
  }
437

    
438
  // It runs in xmlIndex thread. It writes ACL for a package.
439
  private void runAccessControlList (DBConnection conn, String aclid)
440
                                                throws Exception
441
  {
442
    // read the access file from xml_nodes
443
    // parse the access file and store the access info into xml_access
444
    AccessControlList aclobj =
445
    new AccessControlList(conn, aclid, //new StringReader(xml),
446
                          user, groups, serverCode);
447
    conn.commit();
448
  }
449

    
450

    
451
  /** SAX Handler that is called for each XML text node */
452
  public void characters(char[] cbuf, int start, int len) throws SAXException {
453
     MetaCatUtil.debugMessage("CHARACTERS", 50);
454
     DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
455
     String data = null;
456
     int leftover = len;
457
     int offset = start;
458
     boolean moredata = true;
459

    
460
     // This loop deals with the case where there are more characters
461
     // than can fit in a single database text field (limit is
462
     // MAXDATACHARS).  If the text to be inserted exceeds MAXDATACHARS,
463
     // write a series of nodes that are MAXDATACHARS long, and then the
464
     // final node contains the remainder
465
     while (moredata) {
466
       if (leftover > MAXDATACHARS) {
467
         data = new String(cbuf, offset, MAXDATACHARS);
468
         leftover -= MAXDATACHARS;
469
         offset += MAXDATACHARS;
470
       } else {
471
         data = new String(cbuf, offset, leftover);
472
         moredata = false;
473
       }
474

    
475
       // Write the content of the node to the database
476
       currentNode.writeChildNodeToDB("TEXT", null, data, docid);
477
     }
478
   }
479

    
480
   /**
481
    * SAX Handler that is called for each XML text node that is
482
    * Ignorable white space
483
    */
484
   public void ignorableWhitespace(char[] cbuf, int start, int len)
485
               throws SAXException {
486
     // When validation is turned "on", white spaces are reported here
487
     // When validation is turned "off" white spaces are not reported here,
488
     // but through characters() callback
489
     MetaCatUtil.debugMessage("IGNORABLEWHITESPACE", 50);
490

    
491

    
492
     DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
493
     String data = null;
494
     int leftover = len;
495
     int offset = start;
496
     boolean moredata = true;
497

    
498
     // This loop deals with the case where there are more characters
499
     // than can fit in a single database text field (limit is
500
     // MAXDATACHARS).  If the text to be inserted exceeds MAXDATACHARS,
501
     // write a series of nodes that are MAXDATACHARS long, and then the
502
     // final node contains the remainder
503
     while (moredata) {
504
       if (leftover > MAXDATACHARS) {
505
         data = new String(cbuf, offset, MAXDATACHARS);
506
         leftover -= MAXDATACHARS;
507
         offset += MAXDATACHARS;
508
       } else {
509
         data = new String(cbuf, offset, leftover);
510
         moredata = false;
511
       }
512

    
513
       // Write the content of the node to the database
514
       currentNode.writeChildNodeToDB("TEXT", null, data, docid);
515
     }
516
   }
517

    
518
   /**
519
    * SAX Handler called once for each processing instruction found:
520
    * node that PI may occur before or after the root element.
521
    */
522
   public void processingInstruction(String target, String data)
523
          throws SAXException {
524
     MetaCatUtil.debugMessage("PI", 50);
525
     DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
526
     currentNode.writeChildNodeToDB("PI", target, data, docid);
527
   }
528

    
529
   /** SAX Handler that is called at the end of each XML element */
530
   public void endElement(String uri, String localName,
531
                          String qName) throws SAXException {
532
     MetaCatUtil.debugMessage("End ELEMENT " + qName, 50);
533

    
534
     // Get the node from the stack
535
     DBSAXNode currentNode = (DBSAXNode)nodeStack.pop();
536
   }
537

    
538
   //
539
   // the next section implements the LexicalHandler interface
540
   //
541

    
542
   /** SAX Handler that receives notification of DOCTYPE. Sets the DTD */
543
   public void startDTD(String name, String publicId, String systemId)
544
               throws SAXException {
545
     docname = name;
546
     doctype = publicId;
547
     systemid = systemId;
548

    
549
     processingDTD = true;
550

    
551
     MetaCatUtil.debugMessage("Start DTD", 50);
552
     MetaCatUtil.debugMessage("Setting processingDTD to true", 50);
553
     MetaCatUtil.debugMessage("DOCNAME: " + docname, 50);
554
     MetaCatUtil.debugMessage("DOCTYPE: " + doctype, 50);
555
     MetaCatUtil.debugMessage("  SYSID: " + systemid, 50);
556
   }
557

    
558
   /**
559
    * SAX Handler that receives notification of end of DTD
560
    */
561
   public void endDTD() throws SAXException {
562

    
563
     processingDTD = false;
564
     MetaCatUtil.debugMessage("Setting processingDTD to false", 50);
565
     MetaCatUtil.debugMessage("end DTD", 50);
566
   }
567

    
568
   /**
569
    * SAX Handler that receives notification of comments in the DTD
570
    */
571
   public void comment(char[] ch, int start, int length) throws SAXException {
572
     MetaCatUtil.debugMessage("COMMENT", 50);
573
     if ( !processingDTD ) {
574
       DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
575
       currentNode.writeChildNodeToDB("COMMENT", null, new String(ch), docid);
576
     }
577
   }
578

    
579
   /**
580
    * SAX Handler that receives notification of the start of CDATA sections
581
    */
582
   public void startCDATA() throws SAXException {
583
     MetaCatUtil.debugMessage("start CDATA", 50);
584
   }
585

    
586
   /**
587
    * SAX Handler that receives notification of the end of CDATA sections
588
    */
589
   public void endCDATA() throws SAXException {
590
     MetaCatUtil.debugMessage("end CDATA", 50);
591
   }
592

    
593
   /**
594
    * SAX Handler that receives notification of the start of entities
595
    */
596
   public void startEntity(String name) throws SAXException {
597
     MetaCatUtil.debugMessage("start ENTITY: " + name, 50);
598
//System.out.println("start ENTITY: " + name);
599
     if (name.equals("[dtd]")) {
600
       processingDTD = true;
601
     }
602
   }
603

    
604
   /**
605
    * SAX Handler that receives notification of the end of entities
606
    */
607
   public void endEntity(String name) throws SAXException {
608
     MetaCatUtil.debugMessage("end ENTITY: " + name, 50);
609
//System.out.println("end ENTITY: " + name);
610
     if (name.equals("[dtd]")) {
611
       processingDTD = false;
612
     }
613
   }
614

    
615
   /**
616
    * SAX Handler that receives notification of element declarations
617
    */
618
   public void elementDecl(String name, String model)
619
                        throws org.xml.sax.SAXException {
620
//System.out.println("ELEMENTDECL: " + name + " " + model);
621
     MetaCatUtil.debugMessage("ELEMENTDECL: " + name + " " + model, 50);
622
   }
623

    
624
   /**
625
    * SAX Handler that receives notification of attribute declarations
626
    */
627
   public void attributeDecl(String eName, String aName,
628
                        String type, String valueDefault, String value)
629
                        throws org.xml.sax.SAXException {
630

    
631
//System.out.println("ATTRIBUTEDECL: " + eName + " "
632
//                        + aName + " " + type + " " + valueDefault + " "
633
//                        + value);
634
     MetaCatUtil.debugMessage("ATTRIBUTEDECL: " + eName + " "
635
                        + aName + " " + type + " " + valueDefault + " "
636
                        + value, 50);
637
   }
638

    
639
   /**
640
    * SAX Handler that receives notification of internal entity declarations
641
    */
642
   public void internalEntityDecl(String name, String value)
643
                        throws org.xml.sax.SAXException {
644
//System.out.println("INTERNENTITYDECL: " + name + " " + value);
645
     MetaCatUtil.debugMessage("INTERNENTITYDECL: " + name + " " + value, 50);
646
   }
647

    
648
   /**
649
    * SAX Handler that receives notification of external entity declarations
650
    */
651
   public void externalEntityDecl(String name, String publicId,
652
                        String systemId)
653
                        throws org.xml.sax.SAXException {
654
//System.out.println("EXTERNENTITYDECL: " + name + " " + publicId
655
//                              + " " + systemId);
656
     MetaCatUtil.debugMessage("EXTERNENTITYDECL: " + name + " " + publicId
657
                              + " " + systemId, 50);
658
     // it processes other external entity, not the DTD;
659
     // it doesn't signal for the DTD here
660
     processingDTD = false;
661
   }
662

    
663
   //
664
   // the next section implements the ErrorHandler interface
665
   //
666

    
667
   /**
668
    * SAX Handler that receives notification of fatal parsing errors
669
    */
670
   public void fatalError(SAXParseException exception) throws SAXException {
671
     MetaCatUtil.debugMessage("FATALERROR", 50);
672
     throw (new SAXException("Fatal processing error.", exception));
673
   }
674

    
675
   /**
676
    * SAX Handler that receives notification of recoverable parsing errors
677
    */
678
   public void error(SAXParseException exception) throws SAXException {
679
     MetaCatUtil.debugMessage("ERROR", 50);
680
     throw (new SAXException("Processing error.", exception));
681
   }
682

    
683
   /**
684
    * SAX Handler that receives notification of warnings
685
    */
686
   public void warning(SAXParseException exception) throws SAXException {
687
     MetaCatUtil.debugMessage("WARNING", 50);
688
     throw (new SAXException("Warning.", exception));
689
   }
690

    
691
   //
692
   // Helper, getter and setter methods
693
   //
694

    
695
   /**
696
    * get the document name
697
    */
698
   public String getDocname() {
699
     return docname;
700
   }
701

    
702
   /**
703
    * get the document processing state
704
    */
705
   public boolean processingDTD() {
706
     return processingDTD;
707
   }
708
}
(21-21/52)