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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* NSFilter.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 java.util.Enumeration;
41
import java.util.Stack;
42
 
43
import org.xml.sax.Attributes;
44
import org.xml.sax.ErrorHandler;
45
import org.xml.sax.Locator;
46
import org.xml.sax.SAXException;
47
import org.xml.sax.SAXParseException;
48
import org.xml.sax.helpers.AttributesImpl;
49
import org.xml.sax.helpers.NamespaceSupport;
50
 
51
/**
52
 * This filter ensures that element and attribute names are properly prefixed,
53
 * and that such prefixes are declared.  Such data is critical for operations
54
 * like writing XML text, and validating against DTDs:  names or their prefixes
55
 * may have been discarded, although they are essential to the exchange of
56
 * information using XML.  There are various common ways that such data
57
 * gets discarded: <ul>
58
 *
59
 *      <li> By default, SAX2 parsers must discard the "xmlns*"
60
 *      attributes, and may also choose not to report properly prefixed
61
 *      names for elements or attributes.  (Some parsers may support
62
 *      changing the <em>namespace-prefixes</em> value from the default
63
 *      to <em>true</em>, effectively eliminating the need to use this
64
 *      filter on their output.)
65
 *
66
 *      <li> When event streams are generated from a DOM tree, they may
67
 *      have never have had prefixes or declarations for namespaces; or
68
 *      the existing prefixes or declarations may have been invalidated
69
 *      by structural modifications to that DOM tree.
70
 *
71
 *      <li> Other software writing SAX event streams won't necessarily
72
 *      be worrying about prefix management, and so they will need to
73
 *      have a transparent solution for managing them.
74
 *
75
 *      </ul>
76
 *
77
 * <p> This filter uses a heuristic to choose the prefix to assign to any
78
 * particular name which wasn't already corectly prefixed.  The associated
79
 * namespace will be correct, and the prefix will be declared.  Original
80
 * structures facilitating text editing, such as conventions about use of
81
 * mnemonic prefix names or the scoping of prefixes, can't always be
82
 * reconstructed after they are discarded, as strongly encouraged by the
83
 * current SAX2 defaults.
84
 *
85
 * <p> Note that this can't possibly know whether values inside attribute
86
 * value or document content involve prefixed names.  If your application
87
 * requires using prefixed names in such locations you'll need to add some
88
 * appropriate logic (perhaps adding additional heuristics in a subclass).
89
 *
90
 * @author David Brownell
91
 */
92
public class NSFilter extends EventFilter
93
{
94
    private NamespaceSupport    nsStack = new NamespaceSupport ();
95
    private Stack               elementStack = new Stack ();
96
 
97
    private boolean             pushedContext;
98
    private String              nsTemp [] = new String [3];
99
    private AttributesImpl      attributes = new AttributesImpl ();
100
    private boolean             usedDefault;
101
 
102
    // gensymmed prefixes use this root name
103
    private static final String prefixRoot = "prefix-";
104
 
105
 
106
    /**
107
     * Passes events through to the specified consumer, after first
108
     * processing them.
109
     *
110
     * @param next the next event consumer to receive events.
111
     */
112
        // constructor used by PipelineFactory
113
    public NSFilter (EventConsumer next)
114
    {
115
        super (next);
116
 
117
        setContentHandler (this);
118
    }
119
 
120
    private void fatalError (String message)
121
    throws SAXException
122
    {
123
        SAXParseException       e;
124
        ErrorHandler            handler = getErrorHandler ();
125
        Locator                 locator = getDocumentLocator ();
126
 
127
        if (locator == null)
128
            e = new SAXParseException (message, null, null, -1, -1);
129
        else
130
            e = new SAXParseException (message, locator);
131
        if (handler != null)
132
            handler.fatalError (e);
133
        throw e;
134
    }
135
 
136
 
137
    public void startDocument () throws SAXException
138
    {
139
        elementStack.removeAllElements ();
140
        nsStack.reset ();
141
        pushedContext = false;
142
        super.startDocument ();
143
    }
144
 
145
    /**
146
     * This call is not passed to the next consumer in the chain.
147
     * Prefix declarations and scopes are only exposed in the form
148
     * of attributes; this callback just records a declaration that
149
     * will be exposed as an attribute.
150
     */
151
    public void startPrefixMapping (String prefix, String uri)
152
    throws SAXException
153
    {
154
        if (pushedContext == false) {
155
            nsStack.pushContext ();
156
            pushedContext = true;
157
        }
158
 
159
        // this check is awkward, but the paranoia prevents big trouble
160
        for (Enumeration e = nsStack.getDeclaredPrefixes ();
161
                e.hasMoreElements ();
162
                /* NOP */ ) {
163
            String      declared = (String) e.nextElement ();
164
 
165
            if (!declared.equals (prefix))
166
                continue;
167
            if (uri.equals (nsStack.getURI (prefix)))
168
                return;
169
            fatalError ("inconsistent binding for prefix '" + prefix
170
                + "' ... " + uri + " (was " + nsStack.getURI (prefix) + ")");
171
        }
172
 
173
        if (!nsStack.declarePrefix (prefix, uri))
174
            fatalError ("illegal prefix declared: " + prefix);
175
    }
176
 
177
    private String fixName (String ns, String l, String name, boolean isAttr)
178
    throws SAXException
179
    {
180
        if ("".equals (name) || name == null) {
181
            name = l;
182
            if ("".equals (name) || name == null)
183
                fatalError ("empty/null name");
184
        }
185
 
186
        // can we correctly process the name as-is?
187
        // handles "element scope" attribute names here.
188
        if (nsStack.processName (name, nsTemp, isAttr) != null
189
                && nsTemp [0].equals (ns)
190
                ) {
191
            return nsTemp [2];
192
        }
193
 
194
        // nope, gotta modify the name or declare a default mapping
195
        int     temp;
196
 
197
        // get rid of any current prefix
198
        if ((temp = name.indexOf (':')) >= 0) {
199
            name = name.substring (temp + 1);
200
 
201
            // ... maybe that's enough (use/prefer default namespace) ...
202
            if (!isAttr && nsStack.processName (name, nsTemp, false) != null
203
                    && nsTemp [0].equals (ns)
204
                    ) {
205
                return nsTemp [2];
206
            }
207
        }
208
 
209
        // must we define and use the default/undefined prefix?
210
        if ("".equals (ns)) {
211
            if (isAttr)
212
                fatalError ("processName bug");
213
            if (attributes.getIndex ("xmlns") != -1)
214
                fatalError ("need to undefine default NS, but it's bound: "
215
                        + attributes.getValue ("xmlns"));
216
 
217
            nsStack.declarePrefix ("", "");
218
            attributes.addAttribute ("", "", "xmlns", "CDATA", "");
219
            return name;
220
        }
221
 
222
        // is there at least one non-null prefix we can use?
223
        for (Enumeration e = nsStack.getDeclaredPrefixes ();
224
                e.hasMoreElements ();
225
                /* NOP */) {
226
            String prefix = (String) e.nextElement ();
227
            String uri = nsStack.getURI (prefix);
228
 
229
            if (uri == null || !uri.equals (ns))
230
                continue;
231
            return prefix + ":" + name;
232
        }
233
 
234
        // no such luck.  create a prefix name, declare it, use it.
235
        for (temp = 0; temp >= 0; temp++) {
236
            String      prefix = prefixRoot + temp;
237
 
238
            if (nsStack.getURI (prefix) == null) {
239
                nsStack.declarePrefix (prefix, ns);
240
                attributes.addAttribute ("", "", "xmlns:" + prefix,
241
                        "CDATA", ns);
242
                return prefix + ":" + name;
243
            }
244
        }
245
        fatalError ("too many prefixes genned");
246
        // NOTREACHED
247
        return null;
248
    }
249
 
250
    public void startElement (
251
        String uri, String localName,
252
        String qName, Attributes atts
253
    ) throws SAXException
254
    {
255
        if (!pushedContext)
256
            nsStack.pushContext ();
257
        pushedContext = false;
258
 
259
        // make sure we have all NS declarations handy before we start
260
        int     length = atts.getLength ();
261
 
262
        for (int i = 0; i < length; i++) {
263
            String      aName = atts.getQName (i);
264
 
265
            if (!aName.startsWith ("xmlns"))
266
                continue;
267
 
268
            String      prefix;
269
 
270
            if ("xmlns".equals (aName))
271
                prefix = "";
272
            else if (aName.indexOf (':') == 5)
273
                prefix = aName.substring (6);
274
            else        // "xmlnsfoo" etc.
275
                continue;
276
            startPrefixMapping (prefix, atts.getValue (i));
277
        }
278
 
279
        // put namespace decls at the start of our regenned attlist
280
        attributes.clear ();
281
        for (Enumeration e = nsStack.getDeclaredPrefixes ();
282
                e.hasMoreElements ();
283
                /* NOP */) {
284
            String prefix = (String) e.nextElement ();
285
 
286
            attributes.addAttribute ("", "",
287
                    ("".equals (prefix)
288
                        ? "xmlns"
289
                        : "xmlns:" + prefix),
290
                    "CDATA",
291
                    nsStack.getURI (prefix));
292
        }
293
 
294
        // name fixups:  element, then attributes.
295
        // fixName may declare a new prefix or, for the element,
296
        // redeclare the default (if element name needs it).
297
        qName = fixName (uri, localName, qName, false);
298
 
299
        for (int i = 0; i < length; i++) {
300
            String      aName = atts.getQName (i);
301
            String      aNS = atts.getURI (i);
302
            String      aLocal = atts.getLocalName (i);
303
            String      aType = atts.getType (i);
304
            String      aValue = atts.getValue (i);
305
 
306
            if (aName.startsWith ("xmlns"))
307
                continue;
308
            aName = fixName (aNS, aLocal, aName, true);
309
            attributes.addAttribute (aNS, aLocal, aName, aType, aValue);
310
        }
311
 
312
        elementStack.push (qName);
313
 
314
        // pass event along, with cleaned-up names and decls.
315
        super.startElement (uri, localName, qName, attributes);
316
    }
317
 
318
    public void endElement (String uri, String localName, String qName)
319
    throws SAXException
320
    {
321
        nsStack.popContext ();
322
        qName = (String) elementStack.pop ();
323
        super.endElement (uri, localName, qName);
324
    }
325
 
326
    /**
327
     * This call is not passed to the next consumer in the chain.
328
     * Prefix declarations and scopes are only exposed in their
329
     * attribute form.
330
     */
331
    public void endPrefixMapping (String prefix)
332
    throws SAXException
333
        { }
334
 
335
    public void endDocument () throws SAXException
336
    {
337
        elementStack.removeAllElements ();
338
        nsStack.reset ();
339
        super.endDocument ();
340
    }
341
}

powered by: WebSVN 2.1.0

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