~ubuntu-branches/ubuntu/precise/classpath/precise

« back to all changes in this revision

Viewing changes to gnu/xml/transform/StreamSerializer.java

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2006-05-27 16:11:15 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20060527161115-h6e39eposdt5snb6
Tags: 2:0.91-3
* Install header files to /usr/include/classpath.
* debian/control: classpath: Conflict with jamvm < 1.4.3 and
  cacao < 0.96 (Closes: #368172).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* StreamSerializer.java -- 
2
 
   Copyright (C) 2004 Free Software Foundation, Inc.
 
2
   Copyright (C) 2004,2006 Free Software Foundation, Inc.
3
3
 
4
4
This file is part of GNU Classpath.
5
5
 
49
49
import java.util.Collections;
50
50
import java.util.HashMap;
51
51
import java.util.HashSet;
 
52
import java.util.Iterator;
 
53
import java.util.LinkedList;
52
54
import java.util.Map;
53
55
import javax.xml.XMLConstants;
54
56
import org.w3c.dom.Attr;
149
151
    HTML_BOOLEAN_ATTRIBUTES.put("script", set);
150
152
  }
151
153
 
 
154
  // HTML namespace URIs
 
155
  static final HashSet HTML_URIS = new HashSet();
 
156
  static {
 
157
    HTML_URIS.add("http://www.w3.org/1999/xhtml");
 
158
  }
 
159
 
152
160
  protected final String encoding;
153
161
  final Charset charset;
154
162
  final CharsetEncoder encoder;
155
163
  final int mode;
156
 
  final Map namespaces;
 
164
  final LinkedList namespaces;
157
165
  protected String eol;
158
166
  Collection cdataSectionElements = Collections.EMPTY_SET;
159
167
 
160
168
  protected boolean discardDefaultContent;
161
169
  protected boolean xmlDeclaration = true;
 
170
  
 
171
  // has a META element with the encoding been added?
 
172
  private boolean htmlEncoded;
162
173
 
163
174
  public StreamSerializer()
164
175
  {
174
185
  {
175
186
    this.mode = mode;
176
187
    if (encoding == null)
177
 
      {
178
 
        encoding = "UTF-8";
179
 
      }
 
188
      encoding = (mode == Stylesheet.OUTPUT_HTML) ? "ISO-8859-1" : "UTF-8";
180
189
    this.encoding = encoding.intern();
181
190
    charset = Charset.forName(this.encoding);
182
191
    encoder = charset.newEncoder();
183
192
    this.eol = (eol != null) ? eol : System.getProperty("line.separator");
184
 
    namespaces = new HashMap();
 
193
    namespaces = new LinkedList();
185
194
  }
186
195
 
187
196
  void setCdataSectionElements(Collection c)
212
221
    throws IOException
213
222
  {
214
223
    if (out == null)
215
 
      {
216
 
        throw new NullPointerException("no output stream");
217
 
      }
 
224
      throw new NullPointerException("no output stream");
 
225
    htmlEncoded = false;
218
226
    String value, prefix;
219
227
    Node children;
220
228
    String uri = node.getNamespaceURI();
221
 
    boolean defined = false;
222
229
    short nt = node.getNodeType();
223
230
    if (convertToCdata && nt == Node.TEXT_NODE)
224
 
      {
225
 
        nt = Node.CDATA_SECTION_NODE;
226
 
      }
 
231
      nt = Node.CDATA_SECTION_NODE;
227
232
    switch (nt)
228
233
      {
229
234
      case Node.ATTRIBUTE_NODE:
233
238
            (prefix != null && prefix.startsWith("xmlns:")))
234
239
          {
235
240
            String nsuri = node.getNodeValue();
236
 
            if (isDefined(nsuri))
237
 
              {
238
 
                break;
239
 
              }
 
241
            if (isDefined(nsuri, prefix))
 
242
              break;
240
243
            String name = node.getLocalName();
241
244
            if (name == null)
242
245
              {
 
246
                // Namespace-unaware
243
247
                name = node.getNodeName();
 
248
                int ci = name.indexOf(':');
 
249
                if (ci != -1)
 
250
                  name = name.substring(ci + 1);
244
251
              }
245
252
            define(nsuri, name);
246
253
          }
247
 
        else if (uri != null && !isDefined(uri))
 
254
        else if (uri != null && !isDefined(uri, prefix))
248
255
          {
249
256
            prefix = define(uri, prefix);
250
257
            String nsname = (prefix == null) ? "xmlns" : "xmlns:" + prefix;
251
258
            out.write(SPACE);
252
259
            out.write(encodeText(nsname));
253
260
            out.write(EQ);
254
 
            String nsvalue = "'" + encode(uri, true, true) + "'";
 
261
            String nsvalue = "\"" + encode(uri, true, true) + "\"";
255
262
            out.write(nsvalue.getBytes(encoding));
256
 
            defined = true;
257
263
          }
258
264
        out.write(SPACE);
259
265
        String a_nodeName = node.getNodeName();
262
268
        if (mode == Stylesheet.OUTPUT_HTML &&
263
269
            a_nodeName.equals(a_nodeValue) &&
264
270
            isHTMLBoolean((Attr) node, a_nodeName))
265
 
          {
266
 
            break;
267
 
          }
 
271
          break;
268
272
        out.write(EQ);
269
 
        value = "'" + encode(a_nodeValue, true, true) + "'";
 
273
        value = "\"" + encode(a_nodeValue, true, true) + "\"";
270
274
        out.write(encodeText(value));
271
275
        break;
272
276
      case Node.ELEMENT_NODE:
 
277
        pushNamespaceContext();
273
278
        value = node.getNodeName();
274
279
        out.write(BRA);
275
280
        out.write(encodeText(value));
276
 
        if (uri != null && !isDefined(uri))
 
281
        prefix = node.getPrefix();
 
282
        if (uri != null && !isDefined(uri, prefix))
277
283
          {
278
 
            prefix = define(uri, node.getPrefix());
 
284
            prefix = define(uri, prefix);
279
285
            String nsname = (prefix == null) ? "xmlns" : "xmlns:" + prefix;
280
286
            out.write(SPACE);
281
287
            out.write(encodeText(nsname));
282
288
            out.write(EQ);
283
 
            String nsvalue = "'" + encode(uri, true, true) + "'";
 
289
            String nsvalue = "\"" + encode(uri, true, true) + "\"";
284
290
            out.write(encodeText(nsvalue));
285
 
            defined = true;
286
291
          }
287
292
        NamedNodeMap attrs = node.getAttributes();
288
293
        if (attrs != null)
296
301
                    // NOOP
297
302
                  }
298
303
                else
299
 
                  {
300
 
                    serialize(attr, out, false);
301
 
                  }
 
304
                  serialize(attr, out, false);
302
305
              }
303
306
          }
304
307
        convertToCdata = cdataSectionElements.contains(value);
317
320
            out.write(encodeText(value));
318
321
            out.write(KET);
319
322
          }
 
323
        popNamespaceContext();
320
324
        break;
321
325
      case Node.TEXT_NODE:
322
326
        value = node.getNodeValue();
323
327
        if (!"yes".equals(node.getUserData("disable-output-escaping")))
324
 
          {
325
 
            value = encode(value, false, false);
326
 
          }
 
328
          value = encode(value, false, false);
327
329
        out.write(encodeText(value));
328
330
        break;
329
331
      case Node.CDATA_SECTION_NODE:
330
 
        value = "<![CDATA[" + node.getNodeValue() + "]]>";
331
 
        out.write(encodeText(value));
 
332
        value = node.getNodeValue();
 
333
        // Where any instanceof of ]]> occur, split into multiple CDATA
 
334
        // sections
 
335
        int bbk = value.indexOf("]]>");
 
336
        while (bbk != -1)
 
337
          {
 
338
            String head = value.substring(0, bbk + 2);
 
339
            out.write(encodeText("<![CDATA[" + head + "]]>"));
 
340
            value = value.substring(bbk + 2);
 
341
            bbk = value.indexOf("]]>");
 
342
          }
 
343
        // Write final tail value
 
344
        out.write(encodeText("<![CDATA[" + value + "]]>"));
332
345
        break;
333
346
      case Node.COMMENT_NODE:
334
347
        value = "<!--" + node.getNodeValue() + "-->";
335
348
        out.write(encodeText(value));
336
349
        Node cp = node.getParentNode();
337
350
        if (cp != null && cp.getNodeType() == Node.DOCUMENT_NODE)
338
 
          {
339
 
            out.write(encodeText(eol));
340
 
          }
 
351
          out.write(encodeText(eol));
341
352
        break;
342
353
      case Node.DOCUMENT_NODE:
343
354
      case Node.DOCUMENT_FRAGMENT_NODE:
355
366
                  (Document) node : null;
356
367
                String version = (doc != null) ? doc.getXmlVersion() : null;
357
368
                if (version == null)
358
 
                  {
359
 
                    version = (String) node.getUserData("version");
360
 
                  }
 
369
                  version = (String) node.getUserData("version");
361
370
                if (version == null)
362
 
                  {
363
 
                    version = "1.0";
364
 
                  }
 
371
                  version = "1.0";
365
372
                out.write(BRA);
366
373
                out.write(0x3f);
367
 
                out.write("xml version='".getBytes("US-ASCII"));
 
374
                out.write("xml version=\"".getBytes("US-ASCII"));
368
375
                out.write(version.getBytes("US-ASCII"));
369
 
                out.write(APOS);
 
376
                out.write(0x22);
370
377
                if (!("UTF-8".equalsIgnoreCase(encoding)))
371
378
                  {
372
 
                    out.write(" encoding='".getBytes("US-ASCII"));
 
379
                    out.write(" encoding=\"".getBytes("US-ASCII"));
373
380
                    out.write(encoding.getBytes("US-ASCII"));
374
 
                    out.write(APOS);
 
381
                    out.write(0x22);
375
382
                  }
376
383
                if ((doc != null && doc.getXmlStandalone()) ||
377
384
                    "yes".equals(node.getUserData("standalone")))
378
 
                  {
379
 
                    out.write(" standalone='yes'".getBytes("US-ASCII"));
380
 
                  }
 
385
                  out.write(" standalone=\"yes\"".getBytes("US-ASCII"));
381
386
                out.write(0x3f);
382
387
                out.write(KET);
383
388
                out.write(encodeText(eol));
387
392
          }
388
393
        else if (mode == Stylesheet.OUTPUT_HTML)
389
394
          {
390
 
            // Ensure that encoding is accessible
 
395
            // Ensure that encoding is accessible if head element is present
391
396
            String mediaType = (String) node.getUserData("media-type");
392
397
            if (mediaType == null)
393
 
              {
394
 
                mediaType = "text/html";
395
 
              }
 
398
              mediaType = "text/html";
396
399
            String contentType = mediaType + "; charset=" +
397
400
              ((encoding.indexOf(' ') != -1) ?
398
401
                "\"" + encoding + "\"" :
403
406
            for (Node ctx = node.getFirstChild(); ctx != null;
404
407
                 ctx = ctx.getNextSibling())
405
408
              {
406
 
                if (ctx.getNodeType() == Node.ELEMENT_NODE)
 
409
                if (ctx.getNodeType() == Node.ELEMENT_NODE &&
 
410
                    isHTMLElement(ctx, "html"))
407
411
                  {
408
412
                    html = ctx;
409
413
                    break;
410
414
                  }
411
415
              }
412
 
            if (html == null)
413
 
              {
414
 
                html = doc.createElement("html");
415
 
                node.appendChild(html);
416
 
              }
417
 
            Node head = null;
418
 
            for (Node ctx = html.getFirstChild(); ctx != null;
419
 
                 ctx = ctx.getNextSibling())
420
 
              {
421
 
                if (ctx.getNodeType() == Node.ELEMENT_NODE)
422
 
                  {
423
 
                    String name = ctx.getLocalName();
424
 
                    if (name == null)
425
 
                      {
426
 
                        name = ctx.getNodeName();
427
 
                      }
428
 
                    if ("head".equalsIgnoreCase(name))
429
 
                      {
430
 
                        head = ctx;
431
 
                        break;
432
 
                      }
433
 
                  }
434
 
              }
435
 
            if (head == null)
436
 
              {
437
 
                head = doc.createElement("head");
438
 
                Node c1 = null;
 
416
            if (html != null)
 
417
              {
 
418
                Node head = null;
439
419
                for (Node ctx = html.getFirstChild(); ctx != null;
440
420
                     ctx = ctx.getNextSibling())
441
421
                  {
442
 
                    if (ctx.getNodeType() == Node.ELEMENT_NODE)
 
422
                    if (isHTMLElement(ctx, "head"))
443
423
                      {
444
 
                        c1 = ctx;
 
424
                        head = ctx;
445
425
                        break;
446
426
                      }
447
427
                  }
448
 
                if (c1 != null)
449
 
                  {
450
 
                    html.insertBefore(head, c1);
451
 
                  }
452
 
                else
453
 
                  {
454
 
                    html.appendChild(head);
455
 
                  }
456
 
              }
457
 
            Node meta = null;
458
 
            Node metaContent = null;
459
 
            for (Node ctx = head.getFirstChild(); ctx != null;
460
 
                 ctx = ctx.getNextSibling())
461
 
              {
462
 
                if (ctx.getNodeType() == Node.ELEMENT_NODE)
463
 
                  {
464
 
                    String name = ctx.getLocalName();
465
 
                    if (name == null)
466
 
                      {
467
 
                        name = ctx.getNodeName();
468
 
                      }
469
 
                    if ("meta".equalsIgnoreCase(name))
470
 
                      {
471
 
                        NamedNodeMap metaAttrs = ctx.getAttributes();
472
 
                        int len = metaAttrs.getLength();
473
 
                        String httpEquiv = null;
474
 
                        Node content = null;
475
 
                        for (int i = 0; i < len; i++)
476
 
                          {
477
 
                            Node attr = metaAttrs.item(i);
478
 
                            String attrName = attr.getNodeName();
479
 
                            if ("http-equiv".equalsIgnoreCase(attrName))
480
 
                              {
481
 
                                httpEquiv = attr.getNodeValue();
482
 
                              }
483
 
                            else if ("content".equalsIgnoreCase(attrName))
484
 
                              {
485
 
                                content = attr;
486
 
                              }
487
 
                          }
488
 
                        if ("Content-Type".equalsIgnoreCase(httpEquiv))
489
 
                          {
490
 
                            meta = ctx;
491
 
                            metaContent = content;
492
 
                            break;
493
 
                          }
494
 
                      }
495
 
                  }
496
 
              }
497
 
            if (meta == null)
498
 
              {
499
 
                meta = doc.createElement("meta");
500
 
                // Insert first
501
 
                Node first = head.getFirstChild();
502
 
                if (first == null)
503
 
                  {
504
 
                    head.appendChild(meta);
505
 
                  }
506
 
                else
507
 
                  {
508
 
                    head.insertBefore(meta, first);
509
 
                  }
510
 
                Node metaHttpEquiv = doc.createAttribute("http-equiv");
511
 
                meta.getAttributes().setNamedItem(metaHttpEquiv);
512
 
                metaHttpEquiv.setNodeValue("Content-Type");
513
 
              }
514
 
            if (metaContent == null)
515
 
              {
516
 
                metaContent = doc.createAttribute("content");
517
 
                meta.getAttributes().setNamedItem(metaContent);
518
 
              }
519
 
            metaContent.setNodeValue(contentType);
520
 
            // phew
 
428
                if (head != null)
 
429
                  {
 
430
                    Node meta = null;
 
431
                    Node metaContent = null;
 
432
                    for (Node ctx = head.getFirstChild(); ctx != null;
 
433
                         ctx = ctx.getNextSibling())
 
434
                      {
 
435
                        if (isHTMLElement(ctx, "meta"))
 
436
                          {
 
437
                            NamedNodeMap metaAttrs = ctx.getAttributes();
 
438
                            int len = metaAttrs.getLength();
 
439
                            String httpEquiv = null;
 
440
                            Node content = null;
 
441
                            for (int i = 0; i < len; i++)
 
442
                              {
 
443
                                Node attr = metaAttrs.item(i);
 
444
                                String attrName = attr.getNodeName();
 
445
                                if ("http-equiv".equalsIgnoreCase(attrName))
 
446
                                  httpEquiv = attr.getNodeValue();
 
447
                                else if ("content".equalsIgnoreCase(attrName))
 
448
                                  content = attr;
 
449
                              }
 
450
                            if ("Content-Type".equalsIgnoreCase(httpEquiv))
 
451
                              {
 
452
                                meta = ctx;
 
453
                                metaContent = content;
 
454
                                break;
 
455
                              }
 
456
                          }
 
457
                      }
 
458
                    if (meta == null)
 
459
                      {
 
460
                        meta = doc.createElement("meta");
 
461
                        // Insert first
 
462
                        Node first = head.getFirstChild();
 
463
                        if (first == null)
 
464
                          head.appendChild(meta);
 
465
                        else
 
466
                          head.insertBefore(meta, first);
 
467
                        Node metaHttpEquiv = doc.createAttribute("http-equiv");
 
468
                        meta.getAttributes().setNamedItem(metaHttpEquiv);
 
469
                        metaHttpEquiv.setNodeValue("Content-Type");
 
470
                      }
 
471
                    if (metaContent == null)
 
472
                      {
 
473
                        metaContent = doc.createAttribute("content");
 
474
                        meta.getAttributes().setNamedItem(metaContent);
 
475
                      }
 
476
                    metaContent.setNodeValue(contentType);
 
477
                    htmlEncoded = true;
 
478
                  }
 
479
              }
521
480
          }
522
481
        children = node.getFirstChild();
523
482
        if (children != null)
524
 
          {
525
 
            serialize(children, out, convertToCdata);
526
 
          }
 
483
          serialize(children, out, convertToCdata);
527
484
        break;
528
485
      case Node.DOCUMENT_TYPE_NODE:
529
486
        DocumentType doctype = (DocumentType) node;
530
487
        out.write(BRA);
531
488
        out.write(BANG);
532
 
        out.write(encodeText("DOCTYPE "));
 
489
        out.write(encodeText("DOCTYPE "));
533
490
        value = doctype.getNodeName();
534
491
        out.write(encodeText(value));
535
492
        String publicId = doctype.getPublicId();
569
526
            out.write(encodeText(eol));
570
527
          }
571
528
        break;
 
529
      default:
 
530
        System.err.println("Unhandled node type: "+nt);
572
531
      }
573
 
    if (defined)
 
532
  }
 
533
 
 
534
  boolean isHTMLElement(Node node, String name)
 
535
  {
 
536
    if (node.getNodeType() != Node.ELEMENT_NODE)
 
537
      return false;
 
538
    String localName = node.getLocalName();
 
539
    if (localName == null)
 
540
      localName = node.getNodeName();
 
541
    if (!name.equalsIgnoreCase(localName))
 
542
      return false;
 
543
    String uri = node.getNamespaceURI();
 
544
    return (uri == null || HTML_URIS.contains(uri));
 
545
  }
 
546
 
 
547
  boolean isDefined(String uri, String prefix)
 
548
  {
 
549
    if (XMLConstants.XML_NS_URI.equals(uri))
 
550
      return "xml".equals(prefix);
 
551
    if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(uri))
 
552
      return "xmlns".equals(prefix);
 
553
    if (prefix == null)
 
554
      prefix = "";
 
555
    for (Iterator i = namespaces.iterator(); i.hasNext(); )
574
556
      {
575
 
        undefine(uri);
 
557
        Map ctx = (Map) i.next();
 
558
        String val = (String) ctx.get(uri);
 
559
        if (val != null && val.equals(prefix))
 
560
          return true;
576
561
      }
 
562
    return false;
577
563
  }
578
564
 
579
 
  boolean isDefined(String uri)
 
565
  void pushNamespaceContext()
580
566
  {
581
 
    return XMLConstants.XML_NS_URI.equals(uri) ||
582
 
      XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(uri) ||
583
 
      namespaces.containsKey(uri);
 
567
    namespaces.addFirst(new HashMap());
584
568
  }
585
569
 
586
570
  String define(String uri, String prefix)
587
571
  {
588
 
    while (namespaces.containsValue(prefix))
 
572
    if (namespaces.isEmpty())
 
573
      return prefix;
 
574
    HashMap ctx = (HashMap) namespaces.getFirst();
 
575
    while (ctx.containsValue(prefix))
589
576
      {
590
577
        // Fabricate new prefix
591
578
        prefix = prefix + "_";
592
579
      }
593
 
    namespaces.put(uri, prefix);
 
580
    ctx.put(uri, prefix);
594
581
    return prefix;
595
582
  }
596
583
 
597
 
  void undefine(String uri)
 
584
  void popNamespaceContext()
598
585
  {
599
 
    namespaces.remove(uri);
 
586
    namespaces.removeFirst();
600
587
  }
601
588
 
602
589
  final byte[] encodeText(String text)
603
590
    throws IOException
604
591
  {
605
592
    encoder.reset();
606
 
    if (!encoder.canEncode(text))
 
593
    boolean htmlNeedingEncoding =
 
594
      (mode == Stylesheet.OUTPUT_HTML && !htmlEncoded);
 
595
    if (!encoder.canEncode(text) || htmlNeedingEncoding)
607
596
      {
608
597
        // Check each character
609
598
        StringBuffer buf = new StringBuffer();
611
600
        for (int i = 0; i < len; i++)
612
601
          {
613
602
            char c = text.charAt(i);
614
 
            if (encoder.canEncode(c))
615
 
              {
616
 
                buf.append(c);
617
 
              }
618
 
            else
 
603
            if (!encoder.canEncode(c))
619
604
              {
620
605
                // Replace with character entity reference
621
606
                String hex = Integer.toHexString((int) c);
623
608
                buf.append(hex);
624
609
                buf.append(';');
625
610
              }
 
611
            else if (htmlNeedingEncoding)
 
612
              {
 
613
                String entityName = getHTMLCharacterEntity(c);
 
614
                if (entityName != null)
 
615
                  {
 
616
                    buf.append('&');
 
617
                    buf.append(entityName);
 
618
                    buf.append(';');
 
619
                  }
 
620
                else
 
621
                  buf.append(c);
 
622
              }
 
623
            else
 
624
              buf.append(c);
626
625
          }
627
626
        text = buf.toString();
628
627
      }
656
655
        if (c == '<')
657
656
          {
658
657
            if (buf == null)
659
 
              {
660
 
                buf = new StringBuffer(text.substring(0, i));
661
 
              }
 
658
              buf = new StringBuffer(text.substring(0, i));
662
659
            buf.append("&lt;");
663
660
          }
664
661
        else if (c == '>')
665
662
          {
666
663
            if (buf == null)
667
 
              {
668
 
                buf = new StringBuffer(text.substring(0, i));
669
 
              }
 
664
              buf = new StringBuffer(text.substring(0, i));
670
665
            buf.append("&gt;");
671
666
          }
672
667
        else if (c == '&')
675
670
                text.charAt(i + 1) == '{')
676
671
              {
677
672
                if (buf != null)
678
 
                  {
679
 
                    buf.append(c);
680
 
                  }
 
673
                  buf.append(c);
681
674
              }
682
675
            else
683
676
              {
684
677
                if (buf == null)
685
 
                  {
686
 
                    buf = new StringBuffer(text.substring(0, i));
687
 
                  }
 
678
                  buf = new StringBuffer(text.substring(0, i));
688
679
                buf.append("&amp;");
689
680
              }
690
681
          }
691
682
        else if (c == '\'' && inAttr)
692
683
          {
693
684
            if (buf == null)
694
 
              {
695
 
                buf = new StringBuffer(text.substring(0, i));
696
 
              }
697
 
            buf.append("&apos;");
 
685
              buf = new StringBuffer(text.substring(0, i));
 
686
            if (mode == Stylesheet.OUTPUT_HTML)
 
687
              // HTML does not define &apos;, use character entity ref
 
688
              buf.append("&#x27;");
 
689
            else
 
690
              buf.append("&apos;");
698
691
          }
699
692
        else if (c == '"' && inAttr)
700
693
          {
701
694
            if (buf == null)
702
 
              {
703
 
                buf = new StringBuffer(text.substring(0, i));
704
 
              }
 
695
              buf = new StringBuffer(text.substring(0, i));
705
696
            buf.append("&quot;");
706
697
          }
707
698
        else if (encodeCtl)
709
700
            if (c < 0x20)
710
701
              {
711
702
                if (buf == null)
712
 
                  {
713
 
                    buf = new StringBuffer(text.substring(0, i));
714
 
                  }
 
703
                  buf = new StringBuffer(text.substring(0, i));
715
704
                buf.append('&');
716
705
                buf.append('#');
717
706
                buf.append((int) c);
718
707
                buf.append(';');
719
708
              }
720
709
            else if (buf != null)
721
 
              {
722
 
                buf.append(c);
723
 
              }
 
710
              buf.append(c);
724
711
          }
725
712
        else if (buf != null)
726
 
          {
727
 
            buf.append(c);
728
 
          }
 
713
          buf.append(c);
729
714
      }
730
715
    return (buf == null) ? text : buf.toString();
731
716
  }
759
744
    return (attributes != null && attributes.contains(attrName));
760
745
  }
761
746
 
 
747
  static String getHTMLCharacterEntity(char c)
 
748
  {
 
749
    // Hardcode these here to avoid loading the HTML DTD
 
750
    switch (c)
 
751
      {
 
752
      case 160: return "nbsp";
 
753
      case 161: return "iexcl";
 
754
      case 162: return "cent";
 
755
      case 163: return "pound";
 
756
      case 164: return "curren";
 
757
      case 165: return "yen";
 
758
      case 166: return "brvbar";
 
759
      case 167: return "sect";
 
760
      case 168: return "uml";
 
761
      case 169: return "copy";
 
762
      case 170: return "ordf";
 
763
      case 171: return "laquo";
 
764
      case 172: return "not";
 
765
      case 173: return "shy";
 
766
      case 174: return "reg";
 
767
      case 175: return "macr";
 
768
      case 176: return "deg";
 
769
      case 177: return "plusmn";
 
770
      case 178: return "sup2";
 
771
      case 179: return "sup3";
 
772
      case 180: return "acute";
 
773
      case 181: return "micro";
 
774
      case 182: return "para";
 
775
      case 183: return "middot";
 
776
      case 184: return "cedil";
 
777
      case 185: return "sup1";
 
778
      case 186: return "ordm";
 
779
      case 187: return "raquo";
 
780
      case 188: return "frac14";
 
781
      case 189: return "frac12";
 
782
      case 190: return "frac34";
 
783
      case 191: return "iquest";
 
784
      case 192: return "Agrave";
 
785
      case 193: return "Aacute";
 
786
      case 194: return "Acirc";
 
787
      case 195: return "Atilde";
 
788
      case 196: return "Auml";
 
789
      case 197: return "Aring";
 
790
      case 198: return "AElig";
 
791
      case 199: return "Ccedil";
 
792
      case 200: return "Egrave";
 
793
      case 201: return "Eacute";
 
794
      case 202: return "Ecirc";
 
795
      case 203: return "Euml";
 
796
      case 204: return "Igrave";
 
797
      case 205: return "Iacute";
 
798
      case 206: return "Icirc";
 
799
      case 207: return "Iuml";
 
800
      case 208: return "ETH";
 
801
      case 209: return "Ntilde";
 
802
      case 210: return "Ograve";
 
803
      case 211: return "Oacute";
 
804
      case 212: return "Ocirc";
 
805
      case 213: return "Otilde";
 
806
      case 214: return "Ouml";
 
807
      case 215: return "times";
 
808
      case 216: return "Oslash";
 
809
      case 217: return "Ugrave";
 
810
      case 218: return "Uacute";
 
811
      case 219: return "Ucirc";
 
812
      case 220: return "Uuml";
 
813
      case 221: return "Yacute";
 
814
      case 222: return "THORN";
 
815
      case 223: return "szlig";
 
816
      case 224: return "agrave";
 
817
      case 225: return "aacute";
 
818
      case 226: return "acirc";
 
819
      case 227: return "atilde";
 
820
      case 228: return "auml";
 
821
      case 229: return "aring";
 
822
      case 230: return "aelig";
 
823
      case 231: return "ccedil";
 
824
      case 232: return "egrave";
 
825
      case 233: return "eacute";
 
826
      case 234: return "ecirc";
 
827
      case 235: return "euml";
 
828
      case 236: return "igrave";
 
829
      case 237: return "iacute";
 
830
      case 238: return "icirc";
 
831
      case 239: return "iuml";
 
832
      case 240: return "eth";
 
833
      case 241: return "ntilde";
 
834
      case 242: return "ograve";
 
835
      case 243: return "oacute";
 
836
      case 244: return "ocirc";
 
837
      case 245: return "otilde";
 
838
      case 246: return "ouml";
 
839
      case 247: return "divide";
 
840
      case 248: return "oslash";
 
841
      case 249: return "ugrave";
 
842
      case 250: return "uacute";
 
843
      case 251: return "ucirc";
 
844
      case 252: return "uuml";
 
845
      case 253: return "yacute";
 
846
      case 254: return "thorn";
 
847
      case 255: return "yuml";
 
848
      default: return null;
 
849
      }
 
850
  }
 
851
 
762
852
}