OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [xml/] [aelfred2/] [SAXDriver.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* SAXDriver.java --
2
   Copyright (C) 1999,2000,2001,2004 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version.
37
 
38
Portions derived from code which carried the following notice:
39
 
40
  Copyright (c) 1997, 1998 by Microstar Software Ltd.
41
 
42
  AElfred is free for both commercial and non-commercial use and
43
  redistribution, provided that Microstar's copyright and disclaimer are
44
  retained intact.  You are free to modify AElfred for your own use and
45
  to redistribute AElfred with your modifications, provided that the
46
  modifications are clearly documented.
47
 
48
  This program is distributed in the hope that it will be useful, but
49
  WITHOUT ANY WARRANTY; without even the implied warranty of
50
  merchantability or fitness for a particular purpose.  Please use it AT
51
  YOUR OWN RISK.
52
*/
53
 
54
package gnu.xml.aelfred2;
55
 
56
import java.io.*;
57
 
58
import java.net.MalformedURLException;
59
import java.net.URL;
60
import java.util.Locale;
61
import java.util.Stack;
62
 
63
import java.util.ArrayList;
64
import java.util.Collections;
65
import java.util.Enumeration;
66
import java.util.Iterator;
67
import java.util.List;
68
 
69
import org.xml.sax.*;
70
import org.xml.sax.ext.*;
71
import org.xml.sax.helpers.NamespaceSupport;
72
 
73
 
74
/**
75
 * An enhanced SAX2 version of Microstar's Ælfred XML parser.
76
 * The enhancements primarily relate to significant improvements in
77
 * conformance to the XML specification, and SAX2 support.  Performance
78
 * has been improved.  See the package level documentation for more
79
 * information.
80
 *
81
 * <table border="1" width='100%' cellpadding='3' cellspacing='0'>
82
 * <tr bgcolor='#ccccff'>
83
 *      <th><font size='+1'>Name</font></th>
84
 *      <th><font size='+1'>Notes</font></th></tr>
85
 *
86
 * <tr><td colspan=2><center><em>Features ... URL prefix is
87
 * <b>http://xml.org/sax/features/</b></em></center></td></tr>
88
 *
89
 * <tr><td>(URL)/external-general-entities</td>
90
 *      <td>Value defaults to <em>true</em></td></tr>
91
 * <tr><td>(URL)/external-parameter-entities</td>
92
 *      <td>Value defaults to <em>true</em></td></tr>
93
 * <tr><td>(URL)/is-standalone</td>
94
 *      <td>(PRELIMINARY) Returns true iff the document's parsing
95
 *      has started (some non-error event after <em>startDocument()</em>
96
 *      was reported) and the document's standalone flag is set.</td></tr>
97
 * <tr><td>(URL)/namespace-prefixes</td>
98
 *      <td>Value defaults to <em>false</em> (but XML 1.0 names are
99
 *              always reported)</td></tr>
100
 * <tr><td>(URL)/lexical-handler/parameter-entities</td>
101
 *      <td>Value is fixed at <em>true</em></td></tr>
102
 * <tr><td>(URL)/namespaces</td>
103
 *      <td>Value defaults to <em>true</em></td></tr>
104
 * <tr><td>(URL)/resolve-dtd-uris</td>
105
 *      <td>(PRELIMINARY) Value defaults to <em>true</em></td></tr>
106
 * <tr><td>(URL)/string-interning</td>
107
 *      <td>Value is fixed at <em>true</em></td></tr>
108
 * <tr><td>(URL)/use-attributes2</td>
109
 *      <td>(PRELIMINARY) Value is fixed at <em>true</em></td></tr>
110
 * <tr><td>(URL)/use-entity-resolver2</td>
111
 *      <td>(PRELIMINARY) Value defaults to <em>true</em></td></tr>
112
 * <tr><td>(URL)/validation</td>
113
 *      <td>Value is fixed at <em>false</em></td></tr>
114
 *
115
 * <tr><td colspan=2><center><em>Handler Properties ... URL prefix is
116
 * <b>http://xml.org/sax/properties/</b></em></center></td></tr>
117
 *
118
 * <tr><td>(URL)/declaration-handler</td>
119
 *      <td>A declaration handler may be provided.  </td></tr>
120
 * <tr><td>(URL)/lexical-handler</td>
121
 *      <td>A lexical handler may be provided.  </td></tr>
122
 * </table>
123
 *
124
 * <p>This parser currently implements the SAX1 Parser API, but
125
 * it may not continue to do so in the future.
126
 *
127
 * @author Written by David Megginson (version 1.2a from Microstar)
128
 * @author Updated by David Brownell &lt;dbrownell@users.sourceforge.net&gt;
129
 * @see org.xml.sax.Parser
130
 */
131
final public class SAXDriver
132
  implements Locator, Attributes2, XMLReader, Parser, AttributeList
133
{
134
 
135
  private final DefaultHandler2 base = new DefaultHandler2();
136
  private XmlParser parser;
137
 
138
  private EntityResolver entityResolver = base;
139
  private EntityResolver2 resolver2 = null;
140
  private ContentHandler contentHandler = base;
141
  private DTDHandler dtdHandler = base;
142
  private ErrorHandler errorHandler = base;
143
  private DeclHandler declHandler = base;
144
  private LexicalHandler lexicalHandler = base;
145
 
146
  private String elementName;
147
  private Stack entityStack;
148
 
149
  // one vector (of object/struct): faster, smaller
150
  private List attributesList;
151
 
152
  private boolean namespaces = true;
153
  private boolean xmlNames = false;
154
  private boolean extGE = true;
155
  private boolean extPE = true;
156
  private boolean resolveAll = true;
157
  private boolean useResolver2 = true;
158
 
159
  // package private to allow (read-only) access in XmlParser
160
  boolean stringInterning = true;
161
 
162
  private int attributeCount;
163
  private boolean attributes;
164
  private String[] nsTemp;
165
  private NamespaceSupport prefixStack;
166
 
167
  //
168
  // Constructor.
169
  //
170
 
171
  /**
172
   * Constructs a SAX Parser.
173
   */
174
  public SAXDriver()
175
  {
176
    reset();
177
  }
178
 
179
  private void reset()
180
  {
181
    elementName = null;
182
    entityStack = new Stack();
183
    attributesList = Collections.synchronizedList(new ArrayList());
184
    attributeCount = 0;
185
    attributes = false;
186
    nsTemp = new String[3];
187
    prefixStack = null;
188
  }
189
 
190
 
191
  //
192
  // Implementation of org.xml.sax.Parser.
193
  //
194
 
195
  /**
196
   * <b>SAX1</b>: Sets the locale used for diagnostics; currently,
197
   * only locales using the English language are supported.
198
   * @param locale The locale for which diagnostics will be generated
199
   */
200
  public void setLocale(Locale locale)
201
    throws SAXException
202
  {
203
    if ("en".equals(locale.getLanguage()))
204
      {
205
        return;
206
      }
207
    throw new SAXException ("AElfred2 only supports English locales.");
208
  }
209
 
210
  /**
211
   * <b>SAX2</b>: Returns the object used when resolving external
212
   * entities during parsing (both general and parameter entities).
213
   */
214
  public EntityResolver getEntityResolver()
215
  {
216
    return (entityResolver == base) ? null : entityResolver;
217
  }
218
 
219
  /**
220
   * <b>SAX1, SAX2</b>: Set the entity resolver for this parser.
221
   * @param handler The object to receive entity events.
222
   */
223
  public void setEntityResolver(EntityResolver resolver)
224
  {
225
    if (resolver instanceof EntityResolver2)
226
      {
227
        resolver2 = (EntityResolver2) resolver;
228
      }
229
    else
230
      {
231
        resolver2 = null;
232
      }
233
    if (resolver == null)
234
      {
235
        resolver = base;
236
      }
237
    entityResolver = resolver;
238
  }
239
 
240
  /**
241
   * <b>SAX2</b>: Returns the object used to process declarations related
242
   * to notations and unparsed entities.
243
   */
244
  public DTDHandler getDTDHandler()
245
  {
246
    return (dtdHandler == base) ? null : dtdHandler;
247
  }
248
 
249
  /**
250
   * <b>SAX1, SAX2</b>: Set the DTD handler for this parser.
251
   * @param handler The object to receive DTD events.
252
   */
253
  public void setDTDHandler(DTDHandler handler)
254
  {
255
    if (handler == null)
256
      {
257
        handler = base;
258
      }
259
    this.dtdHandler = handler;
260
  }
261
 
262
 
263
  /**
264
   * <b>SAX1</b>: Set the document handler for this parser.  If a
265
   * content handler was set, this document handler will supplant it.
266
   * The parser is set to report all XML 1.0 names rather than to
267
   * filter out "xmlns" attributes (the "namespace-prefixes" feature
268
   * is set to true).
269
   *
270
   * @deprecated SAX2 programs should use the XMLReader interface
271
   *  and a ContentHandler.
272
   *
273
   * @param handler The object to receive document events.
274
   */
275
  public void setDocumentHandler(DocumentHandler handler)
276
  {
277
    contentHandler = new Adapter(handler);
278
    xmlNames = true;
279
  }
280
 
281
  /**
282
   * <b>SAX2</b>: Returns the object used to report the logical
283
   * content of an XML document.
284
   */
285
  public ContentHandler getContentHandler()
286
  {
287
    return (contentHandler == base) ? null : contentHandler;
288
  }
289
 
290
  /**
291
   * <b>SAX2</b>: Assigns the object used to report the logical
292
   * content of an XML document.  If a document handler was set,
293
   * this content handler will supplant it (but XML 1.0 style name
294
   * reporting may remain enabled).
295
   */
296
  public void setContentHandler(ContentHandler handler)
297
  {
298
    if (handler == null)
299
      {
300
        handler = base;
301
      }
302
    contentHandler = handler;
303
  }
304
 
305
  /**
306
   * <b>SAX1, SAX2</b>: Set the error handler for this parser.
307
   * @param handler The object to receive error events.
308
   */
309
  public void setErrorHandler(ErrorHandler handler)
310
  {
311
    if (handler == null)
312
      {
313
        handler = base;
314
      }
315
    this.errorHandler = handler;
316
  }
317
 
318
  /**
319
   * <b>SAX2</b>: Returns the object used to receive callbacks for XML
320
   * errors of all levels (fatal, nonfatal, warning); this is never null;
321
   */
322
  public ErrorHandler getErrorHandler()
323
  {
324
    return (errorHandler == base) ? null : errorHandler;
325
  }
326
 
327
  /**
328
   * <b>SAX1, SAX2</b>: Auxiliary API to parse an XML document, used mostly
329
   * when no URI is available.
330
   * If you want anything useful to happen, you should set
331
   * at least one type of handler.
332
   * @param source The XML input source.  Don't set 'encoding' unless
333
   *  you know for a fact that it's correct.
334
   * @see #setEntityResolver
335
   * @see #setDTDHandler
336
   * @see #setContentHandler
337
   * @see #setErrorHandler
338
   * @exception SAXException The handlers may throw any SAXException,
339
   *  and the parser normally throws SAXParseException objects.
340
   * @exception IOException IOExceptions are normally through through
341
   *  the parser if there are problems reading the source document.
342
   */
343
  public void parse(InputSource source)
344
    throws SAXException, IOException
345
  {
346
    synchronized (base)
347
      {
348
        parser = new XmlParser();
349
        if (namespaces)
350
          {
351
            prefixStack = new NamespaceSupport();
352
          }
353
        else if (!xmlNames)
354
          {
355
            throw new IllegalStateException();
356
          }
357
        parser.setHandler(this);
358
 
359
        try
360
          {
361
            Reader r = source.getCharacterStream();
362
            InputStream in = source.getByteStream();
363
 
364
            parser.doParse(source.getSystemId(),
365
                           source.getPublicId(),
366
                           r,
367
                           in,
368
                           source.getEncoding());
369
          }
370
        catch (SAXException e)
371
          {
372
            throw e;
373
          }
374
        catch (IOException e)
375
          {
376
            throw e;
377
          }
378
        catch (RuntimeException e)
379
          {
380
            throw e;
381
          }
382
        catch (Exception e)
383
          {
384
            throw new SAXParseException(e.getMessage(), this, e);
385
          }
386
        finally
387
          {
388
            contentHandler.endDocument();
389
            reset();
390
          }
391
      }
392
  }
393
 
394
  /**
395
   * <b>SAX1, SAX2</b>: Preferred API to parse an XML document, using a
396
   * system identifier (URI).
397
   */
398
  public void parse(String systemId)
399
    throws SAXException, IOException
400
  {
401
    parse(new InputSource(systemId));
402
  }
403
 
404
  //
405
  // Implementation of SAX2 "XMLReader" interface
406
  //
407
  static final String FEATURE = "http://xml.org/sax/features/";
408
  static final String PROPERTY = "http://xml.org/sax/properties/";
409
 
410
  /**
411
   * <b>SAX2</b>: Tells the value of the specified feature flag.
412
   *
413
   * @exception SAXNotRecognizedException thrown if the feature flag
414
   *  is neither built in, nor yet assigned.
415
   */
416
  public boolean getFeature(String featureId)
417
    throws SAXNotRecognizedException, SAXNotSupportedException
418
  {
419
    if ((FEATURE + "validation").equals(featureId))
420
      {
421
        return false;
422
      }
423
 
424
    // external entities (both types) are optionally included
425
    if ((FEATURE + "external-general-entities").equals(featureId))
426
      {
427
        return extGE;
428
      }
429
    if ((FEATURE + "external-parameter-entities").equals(featureId))
430
      {
431
        return extPE;
432
      }
433
 
434
    // element/attribute names are as written in document; no mangling
435
    if ((FEATURE + "namespace-prefixes").equals(featureId))
436
      {
437
        return xmlNames;
438
      }
439
 
440
    // report element/attribute namespaces?
441
    if ((FEATURE + "namespaces").equals(featureId))
442
      {
443
        return namespaces;
444
      }
445
 
446
    // all PEs and GEs are reported
447
    if ((FEATURE + "lexical-handler/parameter-entities").equals(featureId))
448
      {
449
        return true;
450
      }
451
 
452
    // default is true
453
    if ((FEATURE + "string-interning").equals(featureId))
454
      {
455
        return stringInterning;
456
      }
457
 
458
    // EXTENSIONS 1.1
459
 
460
    // always returns isSpecified info
461
    if ((FEATURE + "use-attributes2").equals(featureId))
462
      {
463
        return true;
464
      }
465
 
466
    // meaningful between startDocument/endDocument
467
    if ((FEATURE + "is-standalone").equals(featureId))
468
      {
469
        if (parser == null)
470
          {
471
            throw new SAXNotSupportedException(featureId);
472
          }
473
        return parser.isStandalone();
474
      }
475
 
476
    // optionally don't absolutize URIs in declarations
477
    if ((FEATURE + "resolve-dtd-uris").equals(featureId))
478
      {
479
        return resolveAll;
480
      }
481
 
482
    // optionally use resolver2 interface methods, if possible
483
    if ((FEATURE + "use-entity-resolver2").equals(featureId))
484
      {
485
        return useResolver2;
486
      }
487
 
488
    throw new SAXNotRecognizedException(featureId);
489
  }
490
 
491
  // package private
492
  DeclHandler getDeclHandler()
493
  {
494
    return declHandler;
495
  }
496
 
497
  // package private
498
  boolean resolveURIs()
499
  {
500
    return resolveAll;
501
  }
502
 
503
  /**
504
   * <b>SAX2</b>:  Returns the specified property.
505
   *
506
   * @exception SAXNotRecognizedException thrown if the property value
507
   *  is neither built in, nor yet stored.
508
   */
509
  public Object getProperty(String propertyId)
510
    throws SAXNotRecognizedException
511
  {
512
    if ((PROPERTY + "declaration-handler").equals(propertyId))
513
      {
514
        return (declHandler == base) ? null : declHandler;
515
      }
516
 
517
    if ((PROPERTY + "lexical-handler").equals(propertyId))
518
      {
519
        return (lexicalHandler == base) ? null : lexicalHandler;
520
      }
521
 
522
    // unknown properties
523
    throw new SAXNotRecognizedException(propertyId);
524
  }
525
 
526
  /**
527
   * <b>SAX2</b>:  Sets the state of feature flags in this parser.  Some
528
   * built-in feature flags are mutable.
529
   */
530
  public void setFeature(String featureId, boolean value)
531
    throws SAXNotRecognizedException, SAXNotSupportedException
532
  {
533
    boolean state;
534
 
535
    // Features with a defined value, we just change it if we can.
536
    state = getFeature (featureId);
537
 
538
    if (state == value)
539
      {
540
        return;
541
      }
542
    if (parser != null)
543
      {
544
        throw new SAXNotSupportedException("not while parsing");
545
      }
546
 
547
    if ((FEATURE + "namespace-prefixes").equals(featureId))
548
      {
549
        // in this implementation, this only affects xmlns reporting
550
        xmlNames = value;
551
        // forcibly prevent illegal parser state
552
        if (!xmlNames)
553
          {
554
            namespaces = true;
555
          }
556
        return;
557
      }
558
 
559
    if ((FEATURE + "namespaces").equals(featureId))
560
      {
561
        namespaces = value;
562
        // forcibly prevent illegal parser state
563
        if (!namespaces)
564
          {
565
            xmlNames = true;
566
          }
567
        return;
568
      }
569
 
570
    if ((FEATURE + "external-general-entities").equals(featureId))
571
      {
572
        extGE = value;
573
        return;
574
      }
575
    if ((FEATURE + "external-parameter-entities").equals(featureId))
576
      {
577
        extPE = value;
578
        return;
579
      }
580
    if ((FEATURE + "resolve-dtd-uris").equals(featureId))
581
      {
582
        resolveAll = value;
583
        return;
584
      }
585
 
586
    if ((FEATURE + "use-entity-resolver2").equals(featureId))
587
      {
588
        useResolver2 = value;
589
        return;
590
      }
591
 
592
    throw new SAXNotRecognizedException(featureId);
593
  }
594
 
595
  /**
596
   * <b>SAX2</b>:  Assigns the specified property.  Like SAX1 handlers,
597
   * these may be changed at any time.
598
   */
599
  public void setProperty(String propertyId, Object value)
600
    throws SAXNotRecognizedException, SAXNotSupportedException
601
  {
602
    // see if the property is recognized
603
    getProperty(propertyId);
604
 
605
    // Properties with a defined value, we just change it if we can.
606
 
607
    if ((PROPERTY + "declaration-handler").equals(propertyId))
608
      {
609
        if (value == null)
610
          {
611
            declHandler = base;
612
          }
613
        else if (!(value instanceof DeclHandler))
614
          {
615
            throw new SAXNotSupportedException(propertyId);
616
          }
617
        else
618
          {
619
            declHandler = (DeclHandler) value;
620
          }
621
        return ;
622
      }
623
 
624
    if ((PROPERTY + "lexical-handler").equals(propertyId))
625
      {
626
        if (value == null)
627
          {
628
            lexicalHandler = base;
629
          }
630
        else if (!(value instanceof LexicalHandler))
631
          {
632
            throw new SAXNotSupportedException(propertyId);
633
          }
634
        else
635
          {
636
            lexicalHandler = (LexicalHandler) value;
637
          }
638
        return;
639
      }
640
 
641
    throw new SAXNotSupportedException(propertyId);
642
  }
643
 
644
  //
645
  // This is where the driver receives XmlParser callbacks and translates
646
  // them into SAX callbacks.  Some more callbacks have been added for
647
  // SAX2 support.
648
  //
649
 
650
  void startDocument()
651
    throws SAXException
652
  {
653
    contentHandler.setDocumentLocator(this);
654
    contentHandler.startDocument();
655
    attributesList.clear();
656
  }
657
 
658
  void xmlDecl(String version,
659
               String encoding,
660
               boolean standalone,
661
               String inputEncoding)
662
    throws SAXException
663
  {
664
    if (contentHandler instanceof ContentHandler2)
665
      {
666
        ((ContentHandler2) contentHandler).xmlDecl(version,
667
                                                   encoding,
668
                                                   standalone,
669
                                                   inputEncoding);
670
      }
671
  }
672
 
673
  void skippedEntity(String name)
674
    throws SAXException
675
  {
676
    contentHandler.skippedEntity(name);
677
  }
678
 
679
  InputSource getExternalSubset(String name, String baseURI)
680
    throws SAXException, IOException
681
  {
682
    if (resolver2 == null || !useResolver2 || !extPE)
683
      {
684
        return null;
685
      }
686
    return resolver2.getExternalSubset(name, baseURI);
687
  }
688
 
689
  InputSource resolveEntity(boolean isPE, String name,
690
                            InputSource in, String baseURI)
691
    throws SAXException, IOException
692
  {
693
    InputSource  source;
694
 
695
    // external entities might be skipped
696
    if (isPE && !extPE)
697
      {
698
        return null;
699
      }
700
    if (!isPE && !extGE)
701
      {
702
        return null;
703
      }
704
 
705
    // ... or not
706
    lexicalHandler.startEntity(name);
707
    if (resolver2 != null && useResolver2)
708
      {
709
        source = resolver2.resolveEntity(name, in.getPublicId(),
710
                                         baseURI, in.getSystemId());
711
        if (source == null)
712
          {
713
            in.setSystemId(absolutize(baseURI,
714
                                      in.getSystemId(), false));
715
            source = in;
716
          }
717
      }
718
    else
719
      {
720
        in.setSystemId(absolutize(baseURI,
721
                                  in.getSystemId(),
722
                                  entityResolver != base));
723
        source = entityResolver.resolveEntity(in.getPublicId(),
724
                                              in.getSystemId());
725
        if (source == null)
726
          {
727
            source = in;
728
          }
729
      }
730
    startExternalEntity(name, source.getSystemId(), true);
731
    return source;
732
  }
733
 
734
  // absolutize a system ID relative to the specified base URI
735
  // (temporarily) package-visible for external entity decls
736
  String absolutize(String baseURI, String systemId, boolean nice)
737
    throws MalformedURLException, SAXException
738
  {
739
    // FIXME normalize system IDs -- when?
740
    // - Convert to UTF-8
741
    // - Map reserved and non-ASCII characters to %HH
742
 
743
    try
744
      {
745
        if (baseURI == null)
746
          {
747
            if (XmlParser.uriWarnings)
748
              {
749
                warn ("No base URI; hope this SYSTEM id is absolute: "
750
                      + systemId);
751
              }
752
            return new URL(systemId).toString();
753
          }
754
        else
755
          {
756
            return new URL(new URL(baseURI), systemId).toString();
757
          }
758
      }
759
    catch (MalformedURLException e)
760
      {
761
        // Let unknown URI schemes pass through unless we need
762
        // the JVM to map them to i/o streams for us...
763
        if (!nice)
764
          {
765
            throw e;
766
          }
767
 
768
        // sometimes sysids for notations or unparsed entities
769
        // aren't really URIs...
770
        warn("Can't absolutize SYSTEM id: " + e.getMessage());
771
        return systemId;
772
      }
773
  }
774
 
775
  void startExternalEntity(String name, String systemId, boolean stackOnly)
776
    throws SAXException
777
  {
778
    // The following warning was deleted because the application has the
779
    // option of not setting systemId. Sun's JAXP or Xerces seems to
780
    // ignore this case.
781
    /*
782
       if (systemId == null)
783
       warn ("URI was not reported to parser for entity " + name);
784
     */
785
    if (!stackOnly)  // spliced [dtd] needs startEntity
786
      {
787
        lexicalHandler.startEntity(name);
788
      }
789
    entityStack.push(systemId);
790
  }
791
 
792
  void endExternalEntity(String name)
793
    throws SAXException
794
  {
795
    if (!"[document]".equals(name))
796
      {
797
        lexicalHandler.endEntity(name);
798
      }
799
    entityStack.pop();
800
  }
801
 
802
  void startInternalEntity(String name)
803
    throws SAXException
804
  {
805
    lexicalHandler.startEntity(name);
806
  }
807
 
808
  void endInternalEntity(String name)
809
    throws SAXException
810
  {
811
    lexicalHandler.endEntity(name);
812
  }
813
 
814
  void doctypeDecl(String name, String publicId, String systemId)
815
    throws SAXException
816
  {
817
    lexicalHandler.startDTD(name, publicId, systemId);
818
 
819
    // ... the "name" is a declaration and should be given
820
    // to the DeclHandler (but sax2 doesn't).
821
 
822
    // the IDs for the external subset are lexical details,
823
    // as are the contents of the internal subset; but sax2
824
    // doesn't provide the internal subset "pre-parse"
825
  }
826
 
827
  void notationDecl(String name, String publicId, String systemId,
828
                    String baseUri)
829
    throws SAXException
830
  {
831
    try
832
      {
833
        dtdHandler.notationDecl(name, publicId,
834
                                (resolveAll && systemId != null)
835
                                ? absolutize(baseUri, systemId, true)
836
                                : systemId);
837
      }
838
    catch (IOException e)
839
      {
840
        // "can't happen"
841
        throw new SAXParseException(e.getMessage(), this, e);
842
      }
843
  }
844
 
845
  void unparsedEntityDecl(String name, String publicId, String systemId,
846
                          String baseUri, String notation)
847
    throws SAXException
848
  {
849
    try
850
      {
851
        dtdHandler.unparsedEntityDecl(name, publicId,
852
                                      resolveAll
853
                                      ? absolutize(baseUri, systemId, true)
854
                                      : systemId,
855
                                      notation);
856
      }
857
    catch (IOException e)
858
      {
859
        // "can't happen"
860
        throw new SAXParseException(e.getMessage(), this, e);
861
      }
862
  }
863
 
864
  void endDoctype()
865
    throws SAXException
866
  {
867
    lexicalHandler.endDTD();
868
  }
869
 
870
  private void declarePrefix(String prefix, String uri)
871
    throws SAXException
872
  {
873
    int index = uri.indexOf(':');
874
 
875
    // many versions of nwalsh docbook stylesheets 
876
    // have bogus URLs; so this can't be an error...
877
    if (index < 1 && uri.length() != 0)
878
      {
879
        warn("relative URI for namespace: " + uri);
880
      }
881
 
882
    // FIXME:  char [0] must be ascii alpha; chars [1..index]
883
    // must be ascii alphanumeric or in "+-." [RFC 2396]
884
 
885
    //Namespace Constraints
886
    //name for xml prefix must be http://www.w3.org/XML/1998/namespace
887
    boolean prefixEquality = prefix.equals("xml");
888
    boolean uriEquality = uri.equals("http://www.w3.org/XML/1998/namespace");
889
    if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality))
890
      {
891
        fatal("xml is by definition bound to the namespace name " +
892
              "http://www.w3.org/XML/1998/namespace");
893
      }
894
 
895
    //xmlns prefix declaration is illegal but xml prefix declaration is llegal...
896
    if (prefixEquality && uriEquality)
897
      {
898
        return;
899
      }
900
 
901
    //name for xmlns prefix must be http://www.w3.org/2000/xmlns/
902
    prefixEquality = prefix.equals("xmlns");
903
    uriEquality = uri.equals("http://www.w3.org/2000/xmlns/");
904
    if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality))
905
      {
906
        fatal("http://www.w3.org/2000/xmlns/ is by definition bound" +
907
              " to prefix xmlns");
908
      }
909
 
910
    //even if the uri is http://www.w3.org/2000/xmlns/
911
    // it is illegal to declare it
912
    if (prefixEquality && uriEquality)
913
      {
914
        fatal ("declaring the xmlns prefix is illegal");
915
      }
916
 
917
    uri = uri.intern();
918
    prefixStack.declarePrefix(prefix, uri);
919
    contentHandler.startPrefixMapping(prefix, uri);
920
  }
921
 
922
  void attribute(String qname, String value, boolean isSpecified)
923
    throws SAXException
924
  {
925
    if (!attributes)
926
      {
927
        attributes = true;
928
        if (namespaces)
929
          {
930
            prefixStack.pushContext();
931
          }
932
      }
933
 
934
    // process namespace decls immediately;
935
    // then maybe forget this as an attribute
936
    if (namespaces)
937
      {
938
        int index;
939
 
940
        // default NS declaration?
941
        if (stringInterning)
942
          {
943
            if ("xmlns" == qname)
944
              {
945
                declarePrefix("", value);
946
                if (!xmlNames)
947
                  {
948
                    return;
949
                  }
950
              }
951
            // NS prefix declaration?
952
            else if ((index = qname.indexOf(':')) == 5
953
                     && qname.startsWith("xmlns"))
954
              {
955
                String prefix = qname.substring(6);
956
 
957
                if (prefix.equals(""))
958
                  {
959
                    fatal("missing prefix " +
960
                          "in namespace declaration attribute");
961
                  }
962
                if (value.length() == 0)
963
                  {
964
                    verror("missing URI in namespace declaration attribute: "
965
                           + qname);
966
                  }
967
                else
968
                  {
969
                    declarePrefix(prefix, value);
970
                  }
971
                if (!xmlNames)
972
                  {
973
                    return;
974
                  }
975
              }
976
          }
977
        else
978
          {
979
            if ("xmlns".equals(qname))
980
              {
981
                declarePrefix("", value);
982
                if (!xmlNames)
983
                  {
984
                    return;
985
                  }
986
              }
987
            // NS prefix declaration?
988
            else if ((index = qname.indexOf(':')) == 5
989
                     && qname.startsWith("xmlns"))
990
              {
991
                String prefix = qname.substring(6);
992
 
993
                if (value.length() == 0)
994
                  {
995
                    verror("missing URI in namespace decl attribute: "
996
                           + qname);
997
                  }
998
                else
999
                  {
1000
                    declarePrefix(prefix, value);
1001
                  }
1002
                if (!xmlNames)
1003
                  {
1004
                    return;
1005
                  }
1006
              }
1007
          }
1008
      }
1009
    // remember this attribute ...
1010
    attributeCount++;
1011
 
1012
    // attribute type comes from querying parser's DTD records
1013
    attributesList.add(new Attribute(qname, value, isSpecified));
1014
 
1015
  }
1016
 
1017
  void startElement(String elname)
1018
    throws SAXException
1019
  {
1020
    ContentHandler handler = contentHandler;
1021
 
1022
    //
1023
    // NOTE:  this implementation of namespace support adds something
1024
    // like six percent to parsing CPU time, in a large (~50 MB)
1025
    // document that doesn't use namespaces at all.  (Measured by PC
1026
    // sampling, with a bug where endElement processing was omitted.)
1027
    // [Measurement referred to older implementation, older JVM ...]
1028
    //
1029
    // It ought to become notably faster in such cases.  Most
1030
    // costs are the prefix stack calling Hashtable.get() (2%),
1031
    // String.hashCode() (1.5%) and about 1.3% each for pushing
1032
    // the context, and two chunks of name processing.
1033
    //
1034
 
1035
    if (!attributes)
1036
      {
1037
        if (namespaces)
1038
          {
1039
            prefixStack.pushContext();
1040
          }
1041
      }
1042
    else if (namespaces)
1043
      {
1044
 
1045
        // now we can patch up namespace refs; we saw all the
1046
        // declarations, so now we'll do the Right Thing
1047
        Iterator itt = attributesList.iterator();
1048
        while (itt.hasNext())
1049
          {
1050
            Attribute attribute = (Attribute) itt.next();
1051
            String qname = attribute.name;
1052
            int index;
1053
 
1054
            // default NS declaration?
1055
            if (stringInterning)
1056
              {
1057
                if ("xmlns" == qname)
1058
                  {
1059
                    continue;
1060
                  }
1061
              }
1062
            else
1063
              {
1064
                if ("xmlns".equals(qname))
1065
                  {
1066
                    continue;
1067
                  }
1068
              }
1069
            //Illegal in the new Namespaces Draft
1070
            //should it be only in 1.1 docs??
1071
            if (qname.equals (":"))
1072
              {
1073
                fatal("namespace names consisting of a single colon " +
1074
                      "character are invalid");
1075
              }
1076
            index = qname.indexOf(':');
1077
 
1078
            // NS prefix declaration?
1079
            if (index == 5 && qname.startsWith("xmlns"))
1080
              {
1081
                continue;
1082
              }
1083
 
1084
            // it's not a NS decl; patch namespace info items
1085
            if (prefixStack.processName(qname, nsTemp, true) == null)
1086
              {
1087
                fatal("undeclared attribute prefix in: " + qname);
1088
              }
1089
            else
1090
              {
1091
                attribute.nameSpace = nsTemp[0];
1092
                attribute.localName = nsTemp[1];
1093
              }
1094
          }
1095
      }
1096
 
1097
    // save element name so attribute callbacks work
1098
    elementName = elname;
1099
    if (namespaces)
1100
      {
1101
        if (prefixStack.processName(elname, nsTemp, false) == null)
1102
          {
1103
            fatal("undeclared element prefix in: " + elname);
1104
            nsTemp[0] = nsTemp[1] = "";
1105
          }
1106
        handler.startElement(nsTemp[0], nsTemp[1], elname, this);
1107
      }
1108
    else
1109
      {
1110
        handler.startElement("", "", elname, this);
1111
      }
1112
    // elementName = null;
1113
 
1114
    // elements with no attributes are pretty common!
1115
    if (attributes)
1116
      {
1117
        attributesList.clear();
1118
        attributeCount = 0;
1119
        attributes = false;
1120
      }
1121
  }
1122
 
1123
  void endElement(String elname)
1124
    throws SAXException
1125
  {
1126
    ContentHandler handler = contentHandler;
1127
 
1128
    if (!namespaces)
1129
      {
1130
        handler.endElement("", "", elname);
1131
        return;
1132
      }
1133
    prefixStack.processName(elname, nsTemp, false);
1134
    handler.endElement(nsTemp[0], nsTemp[1], elname);
1135
 
1136
    Enumeration prefixes = prefixStack.getDeclaredPrefixes();
1137
 
1138
    while (prefixes.hasMoreElements())
1139
      {
1140
        handler.endPrefixMapping((String) prefixes.nextElement());
1141
      }
1142
    prefixStack.popContext();
1143
  }
1144
 
1145
  void startCDATA()
1146
    throws SAXException
1147
  {
1148
    lexicalHandler.startCDATA();
1149
  }
1150
 
1151
  void charData(char[] ch, int start, int length)
1152
    throws SAXException
1153
  {
1154
    contentHandler.characters(ch, start, length);
1155
  }
1156
 
1157
  void endCDATA()
1158
    throws SAXException
1159
  {
1160
    lexicalHandler.endCDATA();
1161
  }
1162
 
1163
  void ignorableWhitespace(char[] ch, int start, int length)
1164
    throws SAXException
1165
  {
1166
    contentHandler.ignorableWhitespace(ch, start, length);
1167
  }
1168
 
1169
  void processingInstruction(String target, String data)
1170
    throws SAXException
1171
  {
1172
    contentHandler.processingInstruction(target, data);
1173
  }
1174
 
1175
  void comment(char[] ch, int start, int length)
1176
    throws SAXException
1177
  {
1178
    if (lexicalHandler != base)
1179
      {
1180
        lexicalHandler.comment(ch, start, length);
1181
      }
1182
  }
1183
 
1184
  void fatal(String message)
1185
    throws SAXException
1186
  {
1187
    SAXParseException fatal;
1188
 
1189
    fatal = new SAXParseException(message, this);
1190
    errorHandler.fatalError(fatal);
1191
 
1192
    // Even if the application can continue ... we can't!
1193
    throw fatal;
1194
  }
1195
 
1196
  // We can safely report a few validity errors that
1197
  // make layered SAX2 DTD validation more conformant
1198
  void verror(String message)
1199
    throws SAXException
1200
  {
1201
    SAXParseException err;
1202
 
1203
    err = new SAXParseException(message, this);
1204
    errorHandler.error(err);
1205
  }
1206
 
1207
  void warn(String message)
1208
    throws SAXException
1209
  {
1210
    SAXParseException err;
1211
 
1212
    err = new SAXParseException(message, this);
1213
    errorHandler.warning(err);
1214
  }
1215
 
1216
  //
1217
  // Implementation of org.xml.sax.Attributes.
1218
  //
1219
 
1220
  /**
1221
   * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1222
   * (don't invoke on parser);
1223
   */
1224
  public int getLength()
1225
  {
1226
    return attributesList.size();
1227
  }
1228
 
1229
  /**
1230
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
1231
   */
1232
  public String getURI(int index)
1233
  {
1234
    if (index < 0 || index >= attributesList.size())
1235
      {
1236
        return null;
1237
      }
1238
    return ((Attribute) attributesList.get(index)).nameSpace;
1239
  }
1240
 
1241
  /**
1242
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
1243
   */
1244
  public String getLocalName(int index)
1245
  {
1246
    if (index < 0 || index >= attributesList.size())
1247
      {
1248
        return null;
1249
      }
1250
    Attribute attr = (Attribute) attributesList.get(index);
1251
    // FIXME attr.localName is sometimes null, why?
1252
    if (namespaces && attr.localName == null)
1253
      {
1254
        // XXX fix this here for now
1255
        int ci = attr.name.indexOf(':');
1256
        attr.localName = (ci == -1) ? attr.name :
1257
          attr.name.substring(ci + 1);
1258
      }
1259
    return (attr.localName == null) ? "" : attr.localName;
1260
  }
1261
 
1262
  /**
1263
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
1264
   */
1265
  public String getQName(int index)
1266
  {
1267
    if (index < 0 || index >= attributesList.size())
1268
      {
1269
      return null;
1270
      }
1271
    Attribute attr = (Attribute) attributesList.get(index);
1272
    return (attr.name == null) ? "" : attr.name;
1273
  }
1274
 
1275
  /**
1276
   * <b>SAX1 AttributeList</b> method (don't invoke on parser);
1277
   */
1278
  public String getName(int index)
1279
  {
1280
    return getQName(index);
1281
  }
1282
 
1283
  /**
1284
   * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1285
   * (don't invoke on parser);
1286
   */
1287
  public String getType(int index)
1288
  {
1289
    if (index < 0 || index >= attributesList.size())
1290
      {
1291
        return null;
1292
      }
1293
    String type = parser.getAttributeType(elementName, getQName(index));
1294
    if (type == null)
1295
      {
1296
        return "CDATA";
1297
      }
1298
    // ... use DeclHandler.attributeDecl to see enumerations
1299
    if (type == "ENUMERATION")
1300
      {
1301
        return "NMTOKEN";
1302
      }
1303
    return type;
1304
  }
1305
 
1306
  /**
1307
   * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1308
   * (don't invoke on parser);
1309
   */
1310
  public String getValue(int index)
1311
  {
1312
    if (index < 0 || index >= attributesList.size())
1313
      {
1314
        return null;
1315
      }
1316
    return ((Attribute) attributesList.get(index)).value;
1317
  }
1318
 
1319
  /**
1320
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
1321
   */
1322
  public int getIndex(String uri, String local)
1323
    {
1324
      int length = getLength();
1325
 
1326
      for (int i = 0; i < length; i++)
1327
        {
1328
          if (!getURI(i).equals(uri))
1329
            {
1330
              continue;
1331
            }
1332
          if (getLocalName(i).equals(local))
1333
            {
1334
              return i;
1335
            }
1336
        }
1337
      return -1;
1338
  }
1339
 
1340
  /**
1341
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
1342
   */
1343
  public int getIndex(String xmlName)
1344
  {
1345
    int length = getLength();
1346
 
1347
    for (int i = 0; i < length; i++)
1348
      {
1349
        if (getQName(i).equals(xmlName))
1350
          {
1351
            return i;
1352
          }
1353
      }
1354
    return -1;
1355
  }
1356
 
1357
  /**
1358
   * <b>SAX2 Attributes</b> method (don't invoke on parser);
1359
   */
1360
  public String getType(String uri, String local)
1361
  {
1362
    int index = getIndex(uri, local);
1363
 
1364
    if (index < 0)
1365
      {
1366
        return null;
1367
      }
1368
    return getType(index);
1369
  }
1370
 
1371
  /**
1372
   * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1373
   * (don't invoke on parser);
1374
   */
1375
  public String getType(String xmlName)
1376
  {
1377
    int index = getIndex(xmlName);
1378
 
1379
    if (index < 0)
1380
      {
1381
        return null;
1382
      }
1383
    return getType(index);
1384
  }
1385
 
1386
  /**
1387
   * <b>SAX Attributes</b> method (don't invoke on parser);
1388
   */
1389
  public String getValue(String uri, String local)
1390
  {
1391
    int index = getIndex(uri, local);
1392
 
1393
    if (index < 0)
1394
      {
1395
        return null;
1396
      }
1397
    return getValue(index);
1398
  }
1399
 
1400
  /**
1401
   * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1402
   * (don't invoke on parser);
1403
   */
1404
  public String getValue(String xmlName)
1405
  {
1406
    int index = getIndex(xmlName);
1407
 
1408
    if (index < 0)
1409
      {
1410
        return null;
1411
      }
1412
    return getValue(index);
1413
  }
1414
 
1415
  //
1416
  // Implementation of org.xml.sax.ext.Attributes2
1417
  //
1418
 
1419
  /** @return false unless the attribute was declared in the DTD.
1420
   * @throws java.lang.ArrayIndexOutOfBoundsException
1421
   *   When the supplied index does not identify an attribute.
1422
   */
1423
  public boolean isDeclared(int index)
1424
  {
1425
    if (index < 0 || index >= attributeCount)
1426
      {
1427
        throw new ArrayIndexOutOfBoundsException();
1428
      }
1429
    String type = parser.getAttributeType(elementName, getQName(index));
1430
    return (type != null);
1431
  }
1432
 
1433
  /** @return false unless the attribute was declared in the DTD.
1434
   * @throws java.lang.IllegalArgumentException
1435
   *   When the supplied names do not identify an attribute.
1436
   */
1437
  public boolean isDeclared(String qName)
1438
  {
1439
    int index = getIndex(qName);
1440
    if (index < 0)
1441
      {
1442
        throw new IllegalArgumentException();
1443
      }
1444
    String type = parser.getAttributeType(elementName, qName);
1445
    return (type != null);
1446
  }
1447
 
1448
  /** @return false unless the attribute was declared in the DTD.
1449
   * @throws java.lang.IllegalArgumentException
1450
   *   When the supplied names do not identify an attribute.
1451
   */
1452
  public boolean isDeclared(String uri, String localName)
1453
  {
1454
    int index = getIndex(uri, localName);
1455
    return isDeclared(index);
1456
  }
1457
 
1458
  /**
1459
   * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
1460
   */
1461
  public boolean isSpecified(int index)
1462
  {
1463
    return ((Attribute) attributesList.get(index)).specified;
1464
  }
1465
 
1466
  /**
1467
   * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
1468
   */
1469
  public boolean isSpecified(String uri, String local)
1470
  {
1471
    int index = getIndex (uri, local);
1472
    return isSpecified(index);
1473
  }
1474
 
1475
  /**
1476
   * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
1477
   */
1478
  public boolean isSpecified(String xmlName)
1479
  {
1480
    int index = getIndex (xmlName);
1481
    return isSpecified(index);
1482
  }
1483
 
1484
  //
1485
  // Implementation of org.xml.sax.Locator.
1486
  //
1487
 
1488
  /**
1489
   * <b>SAX Locator</b> method (don't invoke on parser);
1490
   */
1491
  public String getPublicId()
1492
  {
1493
    return null;   // FIXME track public IDs too
1494
  }
1495
 
1496
  /**
1497
   * <b>SAX Locator</b> method (don't invoke on parser);
1498
   */
1499
  public String getSystemId()
1500
  {
1501
    if (entityStack.empty())
1502
      {
1503
        return null;
1504
      }
1505
    else
1506
      {
1507
        return (String) entityStack.peek();
1508
      }
1509
  }
1510
 
1511
  /**
1512
   * <b>SAX Locator</b> method (don't invoke on parser);
1513
   */
1514
  public int getLineNumber()
1515
  {
1516
    return parser.getLineNumber();
1517
  }
1518
 
1519
  /**
1520
   * <b>SAX Locator</b> method (don't invoke on parser);
1521
   */
1522
  public int getColumnNumber()
1523
  {
1524
    return parser.getColumnNumber();
1525
  }
1526
 
1527
  // adapter between SAX2 content handler and SAX1 document handler callbacks
1528
  private static class Adapter
1529
    implements ContentHandler
1530
  {
1531
 
1532
    private DocumentHandler docHandler;
1533
 
1534
    Adapter(DocumentHandler dh)
1535
    {
1536
      docHandler = dh;
1537
    }
1538
 
1539
    public void setDocumentLocator(Locator l)
1540
    {
1541
      docHandler.setDocumentLocator(l);
1542
    }
1543
 
1544
    public void startDocument()
1545
      throws SAXException
1546
    {
1547
      docHandler.startDocument();
1548
    }
1549
 
1550
    public void processingInstruction(String target, String data)
1551
      throws SAXException
1552
    {
1553
      docHandler.processingInstruction(target, data);
1554
    }
1555
 
1556
    public void startPrefixMapping(String prefix, String uri)
1557
    {
1558
      /* ignored */
1559
    }
1560
 
1561
    public void startElement(String namespace,
1562
                             String local,
1563
                             String name,
1564
                             Attributes attrs)
1565
      throws SAXException
1566
    {
1567
      docHandler.startElement(name, (AttributeList) attrs);
1568
    }
1569
 
1570
    public void characters(char[] buf, int offset, int len)
1571
      throws SAXException
1572
    {
1573
      docHandler.characters(buf, offset, len);
1574
    }
1575
 
1576
    public void ignorableWhitespace(char[] buf, int offset, int len)
1577
      throws SAXException
1578
    {
1579
      docHandler.ignorableWhitespace(buf, offset, len);
1580
    }
1581
 
1582
    public void skippedEntity(String name)
1583
    {
1584
      /* ignored */
1585
    }
1586
 
1587
    public void endElement(String u, String l, String name)
1588
      throws SAXException
1589
    {
1590
      docHandler.endElement(name);
1591
    }
1592
 
1593
    public void endPrefixMapping(String prefix)
1594
    {
1595
      /* ignored */
1596
    }
1597
 
1598
    public void endDocument()
1599
      throws SAXException
1600
    {
1601
      docHandler.endDocument();
1602
    }
1603
  }
1604
 
1605
  private static class Attribute
1606
  {
1607
 
1608
    String name;
1609
    String value;
1610
    String nameSpace;
1611
    String localName;
1612
    boolean specified;
1613
 
1614
    Attribute(String name, String value, boolean specified)
1615
    {
1616
      this.name = name;
1617
      this.value = value;
1618
      this.nameSpace = "";
1619
      this.specified = specified;
1620
    }
1621
 
1622
  }
1623
 
1624
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.