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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [xml/] [pipeline/] [DomConsumer.java] - Blame information for rev 769

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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