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/] [pipeline/] [DomConsumer.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* DomConsumer.java --
2
   Copyright (C) 1999,2000,2001 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
package gnu.xml.pipeline;
39
 
40
import gnu.xml.aelfred2.ContentHandler2;
41
import gnu.xml.util.DomParser;
42
 
43
import org.xml.sax.Attributes;
44
import org.xml.sax.ContentHandler;
45
import org.xml.sax.DTDHandler;
46
import org.xml.sax.ErrorHandler;
47
import org.xml.sax.Locator;
48
import org.xml.sax.SAXException;
49
import org.xml.sax.SAXNotRecognizedException;
50
import org.xml.sax.SAXParseException;
51
import org.xml.sax.ext.DeclHandler;
52
import org.xml.sax.ext.LexicalHandler;
53
import org.xml.sax.helpers.AttributesImpl;
54
import org.w3c.dom.Attr;
55
import org.w3c.dom.CDATASection;
56
import org.w3c.dom.CharacterData;
57
import org.w3c.dom.Document;
58
import org.w3c.dom.DOMImplementation;
59
import org.w3c.dom.Element;
60
import org.w3c.dom.EntityReference;
61
import org.w3c.dom.Node;
62
import org.w3c.dom.ProcessingInstruction;
63
import org.w3c.dom.Text;
64
 
65
/**
66
 * This consumer builds a DOM Document from its input, acting either as a
67
 * pipeline terminus or as an intermediate buffer.  When a document's worth
68
 * of events has been delivered to this consumer, that document is read with
69
 * a {@link DomParser} and sent to the next consumer.  It is also available
70
 * as a read-once property.
71
 *
72
 * <p>The DOM tree is constructed as faithfully as possible.  There are some
73
 * complications since a DOM should expose behaviors that can't be implemented
74
 * without API backdoors into that DOM, and because some SAX parsers don't
75
 * report all the information that DOM permits to be exposed.  The general
76
 * problem areas involve information from the Document Type Declaration (DTD).
77
 * DOM only represents a limited subset, but has some behaviors that depend
78
 * on much deeper knowledge of a document's DTD.  You shouldn't have much to
79
 * worry about unless you change handling of "noise" nodes from its default
80
 * setting (which ignores them all); note if you use JAXP to populate your
81
 * DOM trees, it wants to save "noise" nodes by default.  (Such nodes include
82
 * ignorable whitespace, comments, entity references and CDATA boundaries.)
83
 * Otherwise, your
84
 * main worry will be if you use a SAX parser that doesn't flag ignorable
85
 * whitespace unless it's validating (few don't).
86
 *
87
 * <p> The SAX2 events used as input must contain XML Names for elements
88
 * and attributes, with original prefixes.  In SAX2,
89
 * this is optional unless the "namespace-prefixes" parser feature is set.
90
 * Moreover, many application components won't provide completely correct
91
 * structures anyway.  <em>Before you convert a DOM to an output document,
92
 * you should plan to postprocess it to create or repair such namespace
93
 * information.</em> The {@link NSFilter} pipeline stage does such work.
94
 *
95
 * <p> <em>Note:  changes late in DOM L2 process made it impractical to
96
 * attempt to create the DocumentType node in any implementation-neutral way,
97
 * much less to populate it (L1 didn't support even creating such nodes).
98
 * To create and populate such a node, subclass the inner
99
 * {@link DomConsumer.Handler} class and teach it about the backdoors into
100
 * whatever DOM implementation you want.  It's possible that some revised
101
 * DOM API (L3?) will make this problem solvable again. </em>
102
 *
103
 * @see DomParser
104
 *
105
 * @author David Brownell
106
 */
107
public class DomConsumer implements EventConsumer
108
{
109
    private Class               domImpl;
110
 
111
    private boolean             hidingCDATA = true;
112
    private boolean             hidingComments = true;
113
    private boolean             hidingWhitespace = true;
114
    private boolean             hidingReferences = true;
115
 
116
    private Handler             handler;
117
    private ErrorHandler        errHandler;
118
 
119
    private EventConsumer       next;
120
 
121
    // FIXME:  this can't be a generic pipeline stage just now,
122
    // since its input became a Class not a String (to be turned
123
    // into a class, using the right class loader)
124
 
125
 
126
    /**
127
     * Configures this pipeline terminus to use the specified implementation
128
     * of DOM when constructing its result value.
129
     *
130
     * @param impl class implementing {@link org.w3c.dom.Document Document}
131
     *  which publicly exposes a default constructor
132
     *
133
     * @exception SAXException when there is a problem creating an
134
     *  empty DOM document using the specified implementation
135
     */
136
    public DomConsumer (Class impl)
137
    throws SAXException
138
    {
139
        domImpl = impl;
140
        handler = new Handler (this);
141
    }
142
 
143
    /**
144
     * This is the hook through which a subclass provides a handler
145
     * which knows how to access DOM extensions, specific to some
146
     * implementation, to record additional data in a DOM.
147
     * Treat this as part of construction; don't call it except
148
     * before (or between) parses.
149
     */
150
    protected void setHandler (Handler h)
151
    {
152
        handler = h;
153
    }
154
 
155
 
156
    private Document emptyDocument ()
157
    throws SAXException
158
    {
159
        try {
160
            return (Document) domImpl.newInstance ();
161
        } catch (IllegalAccessException e) {
162
            throw new SAXException ("can't access constructor: "
163
                    + e.getMessage ());
164
        } catch (InstantiationException e) {
165
            throw new SAXException ("can't instantiate Document: "
166
                    + e.getMessage ());
167
        }
168
    }
169
 
170
 
171
    /**
172
     * Configures this consumer as a buffer/filter, using the specified
173
     * DOM implementation when constructing its result value.
174
     *
175
     * <p> This event consumer acts as a buffer and filter, in that it
176
     * builds a DOM tree and then writes it out when <em>endDocument</em>
177
     * is invoked.  Because of the limitations of DOM, much information
178
     * will as a rule not be seen in that replay.  To get a full fidelity
179
     * copy of the input event stream, use a {@link TeeConsumer}.
180
     *
181
     * @param impl class implementing {@link org.w3c.dom.Document Document}
182
     *  which publicly exposes a default constructor
183
     * @param next receives a "replayed" sequence of parse events when
184
     *  the <em>endDocument</em> method is invoked.
185
     *
186
     * @exception SAXException when there is a problem creating an
187
     *  empty DOM document using the specified DOM implementation
188
     */
189
    public DomConsumer (Class impl, EventConsumer n)
190
    throws SAXException
191
    {
192
        this (impl);
193
        next = n;
194
    }
195
 
196
 
197
    /**
198
     * Returns the document constructed from the preceding
199
     * sequence of events.  This method should not be
200
     * used again until another sequence of events has been
201
     * given to this EventConsumer.
202
     */
203
    final public Document getDocument ()
204
    {
205
        return handler.clearDocument ();
206
    }
207
 
208
    public void setErrorHandler (ErrorHandler handler)
209
    {
210
        errHandler = handler;
211
    }
212
 
213
 
214
    /**
215
     * Returns true if the consumer is hiding entity references nodes
216
     * (the default), and false if EntityReference nodes should
217
     * instead be created.  Such EntityReference nodes will normally be
218
     * empty, unless an implementation arranges to populate them and then
219
     * turn them back into readonly objects.
220
     *
221
     * @see #setHidingReferences
222
     */
223
    final public boolean        isHidingReferences ()
224
        { return hidingReferences; }
225
 
226
    /**
227
     * Controls whether the consumer will hide entity expansions,
228
     * or will instead mark them with entity reference nodes.
229
     *
230
     * @see #isHidingReferences
231
     * @param flag False if entity reference nodes will appear
232
     */
233
    final public void           setHidingReferences (boolean flag)
234
        { hidingReferences = flag; }
235
 
236
 
237
    /**
238
     * Returns true if the consumer is hiding comments (the default),
239
     * and false if they should be placed into the output document.
240
     *
241
     * @see #setHidingComments
242
     */
243
    public final boolean isHidingComments ()
244
        { return hidingComments; }
245
 
246
    /**
247
     * Controls whether the consumer is hiding comments.
248
     *
249
     * @see #isHidingComments
250
     */
251
    public final void setHidingComments (boolean flag)
252
        { hidingComments = flag; }
253
 
254
 
255
    /**
256
     * Returns true if the consumer is hiding ignorable whitespace
257
     * (the default), and false if such whitespace should be placed
258
     * into the output document as children of element nodes.
259
     *
260
     * @see #setHidingWhitespace
261
     */
262
    public final boolean isHidingWhitespace ()
263
        { return hidingWhitespace; }
264
 
265
    /**
266
     * Controls whether the consumer hides ignorable whitespace
267
     *
268
     * @see #isHidingComments
269
     */
270
    public final void setHidingWhitespace (boolean flag)
271
        { hidingWhitespace = flag; }
272
 
273
 
274
    /**
275
     * Returns true if the consumer is saving CDATA boundaries, or
276
     * false (the default) otherwise.
277
     *
278
     * @see #setHidingCDATA
279
     */
280
    final public boolean        isHidingCDATA ()
281
        { return hidingCDATA; }
282
 
283
    /**
284
     * Controls whether the consumer will save CDATA boundaries.
285
     *
286
     * @see #isHidingCDATA
287
     * @param flag True to treat CDATA text differently from other
288
     *  text nodes
289
     */
290
    final public void           setHidingCDATA (boolean flag)
291
        { hidingCDATA = flag; }
292
 
293
 
294
 
295
    /** Returns the document handler being used. */
296
    final public ContentHandler getContentHandler ()
297
        { return handler; }
298
 
299
    /** Returns the DTD handler being used. */
300
    final public DTDHandler getDTDHandler ()
301
        { return handler; }
302
 
303
    /**
304
     * Returns the lexical handler being used.
305
     * (DOM construction can't really use declaration handlers.)
306
     */
307
    final public Object getProperty (String id)
308
    throws SAXNotRecognizedException
309
    {
310
        if ("http://xml.org/sax/properties/lexical-handler".equals (id))
311
            return handler;
312
        if ("http://xml.org/sax/properties/declaration-handler".equals (id))
313
            return handler;
314
        throw new SAXNotRecognizedException (id);
315
    }
316
 
317
    EventConsumer getNext () { return next; }
318
 
319
    ErrorHandler getErrorHandler () { return errHandler; }
320
 
321
    /**
322
     * Class used to intercept various parsing events and use them to
323
     * populate a DOM document.  Subclasses would typically know and use
324
     * backdoors into specific DOM implementations, used to implement
325
     * DTD-related functionality.
326
     *
327
     * <p> Note that if this ever throws a DOMException (runtime exception)
328
     * that will indicate a bug in the DOM (e.g. doesn't support something
329
     * per specification) or the parser (e.g. emitted an illegal name, or
330
     * accepted illegal input data). </p>
331
     */
332
    public static class Handler
333
        implements ContentHandler2, LexicalHandler,
334
            DTDHandler, DeclHandler
335
    {
336
        protected DomConsumer           consumer;
337
 
338
        private DOMImplementation       impl;
339
        private Document                document;
340
        private boolean         isL2;
341
 
342
        private Locator         locator;
343
        private Node            top;
344
        private boolean         inCDATA;
345
        private boolean         mergeCDATA;
346
        private boolean         inDTD;
347
        private String          currentEntity;
348
 
349
        private boolean         recreatedAttrs;
350
        private AttributesImpl  attributes = new AttributesImpl ();
351
 
352
        /**
353
         * Subclasses may use SAX2 events to provide additional
354
         * behaviors in the resulting DOM.
355
         */
356
        protected Handler (DomConsumer consumer)
357
        throws SAXException
358
        {
359
            this.consumer = consumer;
360
            document = consumer.emptyDocument ();
361
            impl = document.getImplementation ();
362
            isL2 = impl.hasFeature ("XML", "2.0");
363
        }
364
 
365
        private void fatal (String message, Exception x)
366
        throws SAXException
367
        {
368
            SAXParseException   e;
369
            ErrorHandler        errHandler = consumer.getErrorHandler ();;
370
 
371
            if (locator == null)
372
                e = new SAXParseException (message, null, null, -1, -1, x);
373
            else
374
                e = new SAXParseException (message, locator, x);
375
            if (errHandler != null)
376
                errHandler.fatalError (e);
377
            throw e;
378
        }
379
 
380
        /**
381
         * Returns and forgets the document produced.  If the handler is
382
         * reused, a new document may be created.
383
         */
384
        Document clearDocument ()
385
        {
386
            Document retval = document;
387
            document = null;
388
            locator = null;
389
            return retval;
390
        }
391
 
392
        /**
393
         * Returns the document under construction.
394
         */
395
        protected Document getDocument ()
396
            { return document; }
397
 
398
        /**
399
         * Returns the current node being populated.  This is usually
400
         * an Element or Document, but it might be an EntityReference
401
         * node if some implementation-specific code knows how to put
402
         * those into the result tree and later mark them as readonly.
403
         */
404
        protected Node getTop ()
405
            { return top; }
406
 
407
 
408
        // SAX1
409
        public void setDocumentLocator (Locator locator)
410
        {
411
            this.locator = locator;
412
        }
413
 
414
        // SAX1
415
        public void startDocument ()
416
        throws SAXException
417
        {
418
            if (document == null)
419
                try {
420
                    if (isL2) {
421
                        // couple to original implementation
422
                        document = impl.createDocument (null, "foo", null);
423
                        document.removeChild (document.getFirstChild ());
424
                    } else {
425
                        document = consumer.emptyDocument ();
426
                    }
427
                } catch (Exception e) {
428
                    fatal ("DOM create document", e);
429
                }
430
            top = document;
431
        }
432
 
433
        // ContentHandler2
434
        public void xmlDecl(String version,
435
                            String encoding,
436
                            boolean standalone,
437
                            String inputEncoding)
438
          throws SAXException
439
        {
440
          if (document != null)
441
            {
442
              document.setXmlVersion(version);
443
              document.setXmlStandalone(standalone);
444
            }
445
        }
446
 
447
        // SAX1
448
        public void endDocument ()
449
        throws SAXException
450
        {
451
            try {
452
                if (consumer.getNext () != null && document != null) {
453
                    DomParser   parser = new DomParser (document);
454
 
455
                    EventFilter.bind (parser, consumer.getNext ());
456
                    parser.parse ("ignored");
457
                }
458
            } finally {
459
                top = null;
460
            }
461
        }
462
 
463
        // SAX1
464
        public void processingInstruction (String target, String data)
465
        throws SAXException
466
        {
467
            // we can't create populated entity ref nodes using
468
            // only public DOM APIs (they've got to be readonly)
469
            if (currentEntity != null)
470
                return;
471
 
472
            ProcessingInstruction       pi;
473
 
474
            if (isL2
475
                    // && consumer.isUsingNamespaces ()
476
                    && target.indexOf (':') != -1)
477
                namespaceError (
478
                    "PI target name is namespace nonconformant: "
479
                        + target);
480
            if (inDTD)
481
                return;
482
            pi = document.createProcessingInstruction (target, data);
483
            top.appendChild (pi);
484
        }
485
 
486
        /**
487
         * Subclasses may overrride this method to provide a more efficient
488
         * way to construct text nodes.
489
         * Typically, copying the text into a single character array will
490
         * be more efficient than doing that as well as allocating other
491
         * needed for a String, including an internal StringBuffer.
492
         * Those additional memory and CPU costs can be incurred later,
493
         * if ever needed.
494
         * Unfortunately the standard DOM factory APIs encourage those costs
495
         * to be incurred early.
496
         */
497
        protected Text createText (
498
            boolean     isCDATA,
499
            char        ch [],
500
            int         start,
501
            int         length
502
        ) {
503
            String      value = new String (ch, start, length);
504
 
505
            if (isCDATA)
506
                return document.createCDATASection (value);
507
            else
508
                return document.createTextNode (value);
509
        }
510
 
511
        // SAX1
512
        public void characters (char ch [], int start, int length)
513
        throws SAXException
514
        {
515
            // we can't create populated entity ref nodes using
516
            // only public DOM APIs (they've got to be readonly
517
            // at creation time)
518
            if (currentEntity != null)
519
                return;
520
 
521
            Node        lastChild = top.getLastChild ();
522
 
523
            // merge consecutive text or CDATA nodes if appropriate.
524
            if (lastChild instanceof Text) {
525
                if (consumer.isHidingCDATA ()
526
                        // consecutive Text content ... always merge
527
                        || (!inCDATA
528
                            && !(lastChild instanceof CDATASection))
529
                        // consecutive CDATASection content ... don't
530
                        // merge between sections, only within them
531
                        || (inCDATA && mergeCDATA
532
                            && lastChild instanceof CDATASection)
533
                            ) {
534
                    CharacterData       last = (CharacterData) lastChild;
535
                    String              value = new String (ch, start, length);
536
 
537
                    last.appendData (value);
538
                    return;
539
                }
540
            }
541
            if (inCDATA && !consumer.isHidingCDATA ()) {
542
                top.appendChild (createText (true, ch, start, length));
543
                mergeCDATA = true;
544
            } else
545
                top.appendChild (createText (false, ch, start, length));
546
        }
547
 
548
        // SAX2
549
        public void skippedEntity (String name)
550
        throws SAXException
551
        {
552
            // this callback is useless except to report errors, since
553
            // we can't know if the ref was in content, within an
554
            // attribute, within a declaration ... only one of those
555
            // cases supports more intelligent action than a panic.
556
            fatal ("skipped entity: " + name, null);
557
        }
558
 
559
        // SAX2
560
        public void startPrefixMapping (String prefix, String uri)
561
        throws SAXException
562
        {
563
            // reconstruct "xmlns" attributes deleted by all
564
            // SAX2 parsers without "namespace-prefixes" = true
565
            if ("".equals (prefix))
566
                attributes.addAttribute ("", "", "xmlns",
567
                        "CDATA", uri);
568
            else
569
                attributes.addAttribute ("", "", "xmlns:" + prefix,
570
                        "CDATA", uri);
571
            recreatedAttrs = true;
572
        }
573
 
574
        // SAX2
575
        public void endPrefixMapping (String prefix)
576
        throws SAXException
577
            { }
578
 
579
        // SAX2
580
        public void startElement (
581
            String uri,
582
            String localName,
583
            String qName,
584
            Attributes atts
585
        ) throws SAXException
586
        {
587
            // we can't create populated entity ref nodes using
588
            // only public DOM APIs (they've got to be readonly)
589
            if (currentEntity != null)
590
                return;
591
 
592
            // parser discarded basic information; DOM tree isn't writable
593
            // without massaging to assign prefixes to all nodes.
594
            // the "NSFilter" class does that massaging.
595
            if (qName.length () == 0)
596
                qName = localName;
597
 
598
 
599
            Element     element;
600
            int         length = atts.getLength ();
601
 
602
            if (!isL2) {
603
                element = document.createElement (qName);
604
 
605
                // first the explicit attributes ...
606
                length = atts.getLength ();
607
                for (int i = 0; i < length; i++)
608
                    element.setAttribute (atts.getQName (i),
609
                                            atts.getValue (i));
610
                // ... then any recreated ones (DOM deletes duplicates)
611
                if (recreatedAttrs) {
612
                    recreatedAttrs = false;
613
                    length = attributes.getLength ();
614
                    for (int i = 0; i < length; i++)
615
                        element.setAttribute (attributes.getQName (i),
616
                                                attributes.getValue (i));
617
                    attributes.clear ();
618
                }
619
 
620
                top.appendChild (element);
621
                top = element;
622
                return;
623
            }
624
 
625
            // For an L2 DOM when namespace use is enabled, use
626
            // createElementNS/createAttributeNS except when
627
            // (a) it's an element in the default namespace, or
628
            // (b) it's an attribute with no prefix
629
            String      namespace;
630
 
631
            if (localName.length () != 0)
632
                namespace = (uri.length () == 0) ? null : uri;
633
            else
634
                namespace = getNamespace (getPrefix (qName), atts);
635
 
636
            if (namespace == null)
637
                element = document.createElement (qName);
638
            else
639
                element = document.createElementNS (namespace, qName);
640
 
641
            populateAttributes (element, atts);
642
            if (recreatedAttrs) {
643
                recreatedAttrs = false;
644
                // ... DOM deletes any duplicates
645
                populateAttributes (element, attributes);
646
                attributes.clear ();
647
            }
648
 
649
            top.appendChild (element);
650
            top = element;
651
        }
652
 
653
        final static String     xmlnsURI = "http://www.w3.org/2000/xmlns/";
654
 
655
        private void populateAttributes (Element element, Attributes attrs)
656
        throws SAXParseException
657
        {
658
            int         length = attrs.getLength ();
659
 
660
            for (int i = 0; i < length; i++) {
661
                String  type = attrs.getType (i);
662
                String  value = attrs.getValue (i);
663
                String  name = attrs.getQName (i);
664
                String  local = attrs.getLocalName (i);
665
                String  uri = attrs.getURI (i);
666
 
667
                // parser discarded basic information, DOM tree isn't writable
668
                if (name.length () == 0)
669
                    name = local;
670
 
671
                // all attribute types other than these three may not
672
                // contain scoped names... enumerated attributes get
673
                // reported as NMTOKEN, except for NOTATION values
674
                if (!("CDATA".equals (type)
675
                        || "NMTOKEN".equals (type)
676
                        || "NMTOKENS".equals (type))) {
677
                    if (value.indexOf (':') != -1) {
678
                        namespaceError (
679
                                "namespace nonconformant attribute value: "
680
                                    + "<" + element.getNodeName ()
681
                                    + " " + name + "='" + value + "' ...>");
682
                    }
683
                }
684
 
685
                // xmlns="" is legal (undoes default NS)
686
                // xmlns:foo="" is illegal
687
                String prefix = getPrefix (name);
688
                String namespace;
689
 
690
                if ("xmlns".equals (prefix)) {
691
                    if ("".equals (value))
692
                        namespaceError ("illegal null namespace decl, " + name);
693
                    namespace = xmlnsURI;
694
                } else if ("xmlns".equals (name))
695
                    namespace = xmlnsURI;
696
 
697
                else if (prefix == null)
698
                    namespace = null;
699
                else if (!"".equals(uri) && uri.length () != 0)
700
                    namespace = uri;
701
                else
702
                    namespace = getNamespace (prefix, attrs);
703
 
704
                if (namespace == null)
705
                    element.setAttribute (name, value);
706
                else
707
                    element.setAttributeNS (namespace, name, value);
708
            }
709
        }
710
 
711
        private String getPrefix (String name)
712
        {
713
            int         temp;
714
 
715
            if ((temp = name.indexOf (':')) > 0)
716
                return name.substring (0, temp);
717
            return null;
718
        }
719
 
720
        // used with SAX1-level parser output 
721
        private String getNamespace (String prefix, Attributes attrs)
722
        throws SAXParseException
723
        {
724
            String namespace;
725
            String decl;
726
 
727
            // defaulting 
728
            if (prefix == null) {
729
                decl = "xmlns";
730
                namespace = attrs.getValue (decl);
731
                if ("".equals (namespace))
732
                    return null;
733
                else if (namespace != null)
734
                    return namespace;
735
 
736
            // "xmlns" is like a keyword
737
            // ... according to the Namespace REC, but DOM L2 CR2+
738
            // and Infoset violate that by assigning a namespace.
739
            // that conflict is resolved elsewhere.
740
            } else if ("xmlns".equals (prefix))
741
                return null;
742
 
743
            // "xml" prefix is fixed
744
            else if ("xml".equals (prefix))
745
                return "http://www.w3.org/XML/1998/namespace";
746
 
747
            // otherwise, expect a declaration
748
            else {
749
                decl = "xmlns:" + prefix;
750
                namespace = attrs.getValue (decl);
751
            }
752
 
753
            // if we found a local declaration, great
754
            if (namespace != null)
755
                return namespace;
756
 
757
 
758
            // ELSE ... search up the tree we've been building
759
            for (Node n = top;
760
                    n != null && n.getNodeType () != Node.DOCUMENT_NODE;
761
                    n = (Node) n.getParentNode ()) {
762
                if (n.getNodeType () == Node.ENTITY_REFERENCE_NODE)
763
                    continue;
764
                Element e = (Element) n;
765
                Attr attr = e.getAttributeNode (decl);
766
                if (attr != null)
767
                    return attr.getNodeValue ();
768
            }
769
            // see above re "xmlns" as keyword
770
            if ("xmlns".equals (decl))
771
                return null;
772
 
773
            namespaceError ("Undeclared namespace prefix: " + prefix);
774
            return null;
775
        }
776
 
777
        // SAX2
778
        public void endElement (String uri, String localName, String qName)
779
        throws SAXException
780
        {
781
            // we can't create populated entity ref nodes using
782
            // only public DOM APIs (they've got to be readonly)
783
            if (currentEntity != null)
784
                return;
785
 
786
            top = top.getParentNode ();
787
        }
788
 
789
        // SAX1 (mandatory reporting if validating)
790
        public void ignorableWhitespace (char ch [], int start, int length)
791
        throws SAXException
792
        {
793
            if (consumer.isHidingWhitespace ())
794
                return;
795
            characters (ch, start, length);
796
        }
797
 
798
        // SAX2 lexical event
799
        public void startCDATA ()
800
        throws SAXException
801
        {
802
            inCDATA = true;
803
            // true except for the first fragment of a cdata section
804
            mergeCDATA = false;
805
        }
806
 
807
        // SAX2 lexical event
808
        public void endCDATA ()
809
        throws SAXException
810
        {
811
            inCDATA = false;
812
        }
813
 
814
        // SAX2 lexical event
815
        //
816
        // this SAX2 callback merges two unrelated things:
817
        //      - Declaration of the root element type ... belongs with
818
        //    the other DTD declaration methods, NOT HERE.
819
        //      - IDs for the optional external subset ... belongs here
820
        //    with other lexical information.
821
        //
822
        // ...and it doesn't include the internal DTD subset, desired
823
        // both to support DOM L2 and to enable "pass through" processing
824
        //
825
        public void startDTD (String name, String publicId, String SystemId)
826
        throws SAXException
827
        {
828
            // need to filter out comments and PIs within the DTD
829
            inDTD = true;
830
        }
831
 
832
        // SAX2 lexical event
833
        public void endDTD ()
834
        throws SAXException
835
        {
836
            inDTD = false;
837
        }
838
 
839
        // SAX2 lexical event
840
        public void comment (char ch [], int start, int length)
841
        throws SAXException
842
        {
843
            Node        comment;
844
 
845
            // we can't create populated entity ref nodes using
846
            // only public DOM APIs (they've got to be readonly)
847
            if (consumer.isHidingComments ()
848
                    || inDTD
849
                    || currentEntity != null)
850
                return;
851
            comment = document.createComment (new String (ch, start, length));
852
            top.appendChild (comment);
853
        }
854
 
855
        /**
856
         * May be overridden by subclasses to return true, indicating
857
         * that entity reference nodes can be populated and then made
858
         * read-only.
859
         */
860
        public boolean canPopulateEntityRefs ()
861
            { return false; }
862
 
863
        // SAX2 lexical event
864
        public void startEntity (String name)
865
        throws SAXException
866
        {
867
            // are we ignoring what would be contents of an
868
            // entity ref, since we can't populate it?
869
            if (currentEntity != null)
870
                return;
871
 
872
            // Are we hiding all entity boundaries?
873
            if (consumer.isHidingReferences ())
874
                return;
875
 
876
            // SAX2 shows parameter entities; DOM hides them
877
            if (name.charAt (0) == '%' || "[dtd]".equals (name))
878
                return;
879
 
880
            // Since we can't create a populated entity ref node in any
881
            // standard way, we create an unpopulated one.
882
            EntityReference ref = document.createEntityReference (name);
883
            top.appendChild (ref);
884
            top = ref;
885
 
886
            // ... allowing subclasses to populate them
887
            if (!canPopulateEntityRefs ())
888
                currentEntity = name;
889
        }
890
 
891
        // SAX2 lexical event
892
        public void endEntity (String name)
893
        throws SAXException
894
        {
895
            if (name.charAt (0) == '%' || "[dtd]".equals (name))
896
                return;
897
            if (name.equals (currentEntity))
898
                currentEntity = null;
899
            if (!consumer.isHidingReferences ())
900
                top = top.getParentNode ();
901
        }
902
 
903
 
904
        // SAX1 DTD event
905
        public void notationDecl (
906
            String name,
907
            String publicId, String SystemId
908
        ) throws SAXException
909
        {
910
            /* IGNORE -- no public DOM API lets us store these
911
             * into the doctype node
912
             */
913
        }
914
 
915
        // SAX1 DTD event
916
        public void unparsedEntityDecl (
917
            String name,
918
            String publicId, String SystemId,
919
            String notationName
920
        ) throws SAXException
921
        {
922
            /* IGNORE -- no public DOM API lets us store these
923
             * into the doctype node
924
             */
925
        }
926
 
927
        // SAX2 declaration event
928
        public void elementDecl (String name, String model)
929
        throws SAXException
930
        {
931
            /* IGNORE -- no content model support in DOM L2 */
932
        }
933
 
934
        // SAX2 declaration event
935
        public void attributeDecl (
936
            String eName,
937
            String aName,
938
            String type,
939
            String mode,
940
            String value
941
        ) throws SAXException
942
        {
943
            /* IGNORE -- no attribute model support in DOM L2 */
944
        }
945
 
946
        // SAX2 declaration event
947
        public void internalEntityDecl (String name, String value)
948
        throws SAXException
949
        {
950
            /* IGNORE -- no public DOM API lets us store these
951
             * into the doctype node
952
             */
953
        }
954
 
955
        // SAX2 declaration event
956
        public void externalEntityDecl (
957
            String name,
958
            String publicId,
959
            String SystemId
960
        ) throws SAXException
961
        {
962
            /* IGNORE -- no public DOM API lets us store these
963
             * into the doctype node
964
             */
965
        }
966
 
967
        //
968
        // These really should offer the option of nonfatal handling,
969
        // like other validity errors, though that would cause major
970
        // chaos in the DOM data structures.  DOM is already spec'd
971
        // to treat many of these as fatal, so this is consistent.
972
        //
973
        private void namespaceError (String description)
974
        throws SAXParseException
975
        {
976
            SAXParseException err;
977
 
978
            err = new SAXParseException (description, locator);
979
            throw err;
980
        }
981
    }
982
}

powered by: WebSVN 2.1.0

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