1 16 19 package org.apache.xml.serializer; 20 21 import java.io.IOException ; 22 import java.util.Hashtable ; 23 import java.util.Stack ; 24 import java.util.Vector ; 25 26 import javax.xml.transform.SourceLocator ; 27 import javax.xml.transform.Transformer ; 28 29 import org.apache.xml.res.XMLErrorResources; 30 import org.apache.xml.res.XMLMessages; 31 import org.apache.xml.utils.BoolStack; 32 import org.xml.sax.Attributes ; 33 import org.xml.sax.ContentHandler ; 34 import org.xml.sax.Locator ; 35 import org.xml.sax.SAXException ; 36 import org.xml.sax.SAXParseException ; 37 38 39 46 abstract public class SerializerBase 47 implements SerializationHandler, SerializerConstants, org.apache.xml.dtm.ref.dom2dtm.DOM2DTM.CharacterNodeHandler 48 { 49 50 51 55 protected void fireEndElem(String name) 56 throws org.xml.sax.SAXException 57 { 58 if (m_tracer != null) 59 { 60 flushMyWriter(); 61 m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_ENDELEMENT,name, (Attributes )null); 62 } 63 } 64 65 71 protected void fireCharEvent(char[] chars, int start, int length) 72 throws org.xml.sax.SAXException 73 { 74 if (m_tracer != null) 75 { 76 flushMyWriter(); 77 m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_CHARACTERS, chars, start,length); 78 } 79 } 80 81 84 protected boolean m_needToCallStartDocument = true; 85 86 89 protected boolean m_cdataTagOpen = false; 90 91 96 protected AttributesImplSerializer m_attributes = new AttributesImplSerializer(); 97 98 101 protected boolean m_inEntityRef = false; 102 103 104 protected boolean m_inExternalDTD = false; 105 106 109 private String m_doctypeSystem; 110 111 114 private String m_doctypePublic; 115 116 120 boolean m_needToOutputDocTypeDecl = true; 121 122 126 private String m_encoding = null; 127 128 131 private boolean m_shouldNotWriteXMLHeader = false; 132 133 136 private String m_standalone; 137 138 141 protected boolean m_standaloneWasSpecified = false; 142 143 146 protected boolean m_doIndent = false; 147 150 protected int m_indentAmount = 0; 151 152 155 private String m_version = null; 156 157 160 private String m_mediatype; 161 162 166 private Transformer m_transformer; 167 168 173 protected Vector m_cdataSectionElements = null; 174 175 180 protected NamespaceMappings m_prefixMap; 181 182 186 protected SerializerTrace m_tracer; 187 188 protected SourceLocator m_sourceLocator; 189 190 191 196 protected java.io.Writer m_writer = null; 197 198 204 protected ElemContext m_elemContext = new ElemContext(); 205 206 212 protected char[] m_charsBuff = new char[60]; 213 214 220 protected char[] m_attrBuff = new char[30]; 221 222 227 public void comment(String data) throws SAXException 228 { 229 final int length = data.length(); 230 if (length > m_charsBuff.length) 231 { 232 m_charsBuff = new char[length * 2 + 1]; 233 } 234 data.getChars(0, length, m_charsBuff, 0); 235 comment(m_charsBuff, 0, length); 236 } 237 238 246 protected String patchName(String qname) 247 { 248 249 250 final int lastColon = qname.lastIndexOf(':'); 251 252 if (lastColon > 0) { 253 final int firstColon = qname.indexOf(':'); 254 final String prefix = qname.substring(0, firstColon); 255 final String localName = qname.substring(lastColon + 1); 256 257 final String uri = m_prefixMap.lookupNamespace(prefix); 259 if (uri != null && uri.length() == 0) { 260 return localName; 261 } 262 else if (firstColon != lastColon) { 263 return prefix + ':' + localName; 264 } 265 } 266 return qname; 267 } 268 269 275 protected static String getLocalName(String qname) 276 { 277 final int col = qname.lastIndexOf(':'); 278 return (col > 0) ? qname.substring(col + 1) : qname; 279 } 280 281 307 public void setDocumentLocator(Locator locator) 308 { 309 return; 310 311 } 313 314 331 public void addAttribute( 332 String uri, 333 String localName, 334 String rawName, 335 String type, 336 String value) 337 throws SAXException 338 { 339 if (m_elemContext.m_startTagOpen) 340 { 341 addAttributeAlways(uri, localName, rawName, type, value); 342 } 343 344 } 345 346 357 public void addAttributeAlways( 358 String uri, 359 String localName, 360 String rawName, 361 String type, 362 String value) 363 { 364 int index; 368 index = m_attributes.getIndex(rawName); 375 if (index >= 0) 376 { 377 381 m_attributes.setValue(index,value); 382 } 383 else 384 { 385 m_attributes.addAttribute(uri, localName, rawName, type, value); 387 } 388 389 } 390 391 392 400 public void addAttribute(String name, final String value) 401 { 402 if (m_elemContext.m_startTagOpen) 403 { 404 final String patchedName = patchName(name); 405 final String localName = getLocalName(patchedName); 406 final String uri = getNamespaceURI(patchedName, false); 407 408 addAttributeAlways(uri,localName, patchedName, "CDATA", value); 409 } 410 } 411 412 413 419 public void addAttributes(Attributes atts) throws SAXException 420 { 421 422 int nAtts = atts.getLength(); 423 424 for (int i = 0; i < nAtts; i++) 425 { 426 String uri = atts.getURI(i); 427 428 if (null == uri) 429 uri = ""; 430 431 addAttributeAlways( 432 uri, 433 atts.getLocalName(i), 434 atts.getQName(i), 435 atts.getType(i), 436 atts.getValue(i)); 437 438 } 439 } 440 441 450 public ContentHandler asContentHandler() throws IOException 451 { 452 return this; 453 } 454 455 462 public void endEntity(String name) throws org.xml.sax.SAXException 463 { 464 if (name.equals("[dtd]")) 465 m_inExternalDTD = false; 466 m_inEntityRef = false; 467 468 if (m_tracer != null) 469 this.fireEndEntity(name); 470 } 471 472 477 public void close() 478 { 479 } 481 482 485 protected void initCDATA() 486 { 487 } 491 492 496 public String getEncoding() 497 { 498 return m_encoding; 499 } 500 501 505 public void setEncoding(String m_encoding) 506 { 507 this.m_encoding = m_encoding; 508 } 509 510 515 public void setOmitXMLDeclaration(boolean b) 516 { 517 this.m_shouldNotWriteXMLHeader = b; 518 } 519 520 521 525 public boolean getOmitXMLDeclaration() 526 { 527 return m_shouldNotWriteXMLHeader; 528 } 529 530 537 public String getDoctypePublic() 538 { 539 return m_doctypePublic; 540 } 541 542 546 public void setDoctypePublic(String doctypePublic) 547 { 548 this.m_doctypePublic = doctypePublic; 549 } 550 551 552 559 public String getDoctypeSystem() 560 { 561 return m_doctypeSystem; 562 } 563 564 568 public void setDoctypeSystem(String doctypeSystem) 569 { 570 this.m_doctypeSystem = doctypeSystem; 571 } 572 573 579 public void setDoctype(String doctypeSystem, String doctypePublic) 580 { 581 this.m_doctypeSystem = doctypeSystem; 582 this.m_doctypePublic = doctypePublic; 583 } 584 585 592 public void setStandalone(String standalone) 593 { 594 if (standalone != null) 595 { 596 m_standaloneWasSpecified = true; 597 setStandaloneInternal(standalone); 598 } 599 } 600 605 protected void setStandaloneInternal(String standalone) 606 { 607 if ("yes".equals(standalone)) 608 m_standalone = "yes"; 609 else 610 m_standalone = "no"; 611 612 } 613 614 620 public String getStandalone() 621 { 622 return m_standalone; 623 } 624 625 629 public boolean getIndent() 630 { 631 return m_doIndent; 632 } 633 639 public String getMediaType() 640 { 641 return m_mediatype; 642 } 643 644 648 public String getVersion() 649 { 650 return m_version; 651 } 652 653 658 public void setVersion(String version) 659 { 660 m_version = version; 661 } 662 663 670 public void setMediaType(String mediaType) 671 { 672 m_mediatype = mediaType; 673 } 674 675 678 public int getIndentAmount() 679 { 680 return m_indentAmount; 681 } 682 683 687 public void setIndentAmount(int m_indentAmount) 688 { 689 this.m_indentAmount = m_indentAmount; 690 } 691 692 699 public void setIndent(boolean doIndent) 700 { 701 m_doIndent = doIndent; 702 } 703 704 715 public void namespaceAfterStartElement(String uri, String prefix) 716 throws SAXException 717 { 718 } 720 721 731 public DOMSerializer asDOMSerializer() throws IOException 732 { 733 return this; 734 } 735 736 752 protected boolean isCdataSection() 753 { 754 755 boolean b = false; 756 757 if (null != m_cdataSectionElements) 758 { 759 if (m_elemContext.m_elementLocalName == null) 760 m_elemContext.m_elementLocalName = 761 getLocalName(m_elemContext.m_elementName); 762 if (m_elemContext.m_elementURI == null) 763 { 764 String prefix = getPrefixPart(m_elemContext.m_elementName); 765 if (prefix != null) 766 m_elemContext.m_elementURI = 767 m_prefixMap.lookupNamespace(prefix); 768 769 } 770 771 if ((null != m_elemContext.m_elementURI) 772 && m_elemContext.m_elementURI.length() == 0) 773 m_elemContext.m_elementURI = null; 774 775 int nElems = m_cdataSectionElements.size(); 776 777 for (int i = 0; i < nElems; i += 2) 779 { 780 String uri = (String ) m_cdataSectionElements.elementAt(i); 781 String loc = (String ) m_cdataSectionElements.elementAt(i + 1); 782 if (loc.equals(m_elemContext.m_elementLocalName) 783 && subPartMatch(m_elemContext.m_elementURI, uri)) 784 { 785 b = true; 786 787 break; 788 } 789 } 790 } 791 return b; 792 } 793 794 802 private static final boolean subPartMatch(String p, String t) 803 { 804 return (p == t) || ((null != p) && (p.equals(t))); 805 } 806 807 816 protected static final String getPrefixPart(String qname) 817 { 818 final int col = qname.indexOf(':'); 819 return (col > 0) ? qname.substring(0, col) : null; 820 } 822 823 828 public NamespaceMappings getNamespaceMappings() 829 { 830 return m_prefixMap; 831 } 832 833 839 public String getPrefix(String namespaceURI) 840 { 841 String prefix = m_prefixMap.lookupPrefix(namespaceURI); 842 return prefix; 843 } 844 845 853 public String getNamespaceURI(String qname, boolean isElement) 854 { 855 String uri = EMPTYSTRING; 856 int col = qname.lastIndexOf(':'); 857 final String prefix = (col > 0) ? qname.substring(0, col) : EMPTYSTRING; 858 859 if (!EMPTYSTRING.equals(prefix) || isElement) 860 { 861 if (m_prefixMap != null) 862 { 863 uri = m_prefixMap.lookupNamespace(prefix); 864 if (uri == null && !prefix.equals(XMLNS_PREFIX)) 865 { 866 throw new RuntimeException ( 867 XMLMessages.createXMLMessage( 868 XMLErrorResources.ER_NAMESPACE_PREFIX, 869 new Object [] { qname.substring(0, col) } )); 870 } 871 } 872 } 873 return uri; 874 } 875 876 883 public String getNamespaceURIFromPrefix(String prefix) 884 { 885 String uri = null; 886 if (m_prefixMap != null) 887 uri = m_prefixMap.lookupNamespace(prefix); 888 return uri; 889 } 890 891 898 public void entityReference(String name) throws org.xml.sax.SAXException 899 { 900 901 flushPending(); 902 903 startEntity(name); 904 endEntity(name); 905 906 if (m_tracer != null) 907 fireEntityReference(name); 908 } 909 910 915 public void setTransformer(Transformer t) 916 { 917 m_transformer = t; 918 919 if ((m_transformer instanceof SerializerTrace) && 923 (((SerializerTrace) m_transformer).hasTraceListeners())) { 924 m_tracer = (SerializerTrace) m_transformer; 925 } else { 926 m_tracer = null; 927 } 928 } 929 934 public Transformer getTransformer() 935 { 936 return m_transformer; 937 } 938 939 945 public void characters(org.w3c.dom.Node node) 946 throws org.xml.sax.SAXException 947 { 948 flushPending(); 949 String data = node.getNodeValue(); 950 if (data != null) 951 { 952 final int length = data.length(); 953 if (length > m_charsBuff.length) 954 { 955 m_charsBuff = new char[length * 2 + 1]; 956 } 957 data.getChars(0, length, m_charsBuff, 0); 958 characters(m_charsBuff, 0, length); 959 } 960 } 961 962 963 966 public void error(SAXParseException exc) throws SAXException { 967 } 968 969 972 public void fatalError(SAXParseException exc) throws SAXException { 973 974 m_elemContext.m_startTagOpen = false; 975 976 } 977 978 981 public void warning(SAXParseException exc) throws SAXException 982 { 983 } 984 985 989 protected void fireStartEntity(String name) 990 throws org.xml.sax.SAXException 991 { 992 if (m_tracer != null) 993 { 994 flushMyWriter(); 995 m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_ENTITYREF, name); 996 } 997 } 998 999 1005 1013 1022 private void flushMyWriter() 1023 { 1024 if (m_writer != null) 1025 { 1026 try 1027 { 1028 m_writer.flush(); 1029 } 1030 catch(IOException ioe) 1031 { 1032 1033 } 1034 } 1035 } 1036 1042 protected void fireCDATAEvent(char[] chars, int start, int length) 1043 throws org.xml.sax.SAXException 1044 { 1045 if (m_tracer != null) 1046 { 1047 flushMyWriter(); 1048 m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_CDATA, chars, start,length); 1049 } 1050 } 1051 1052 1058 protected void fireCommentEvent(char[] chars, int start, int length) 1059 throws org.xml.sax.SAXException 1060 { 1061 if (m_tracer != null) 1062 { 1063 flushMyWriter(); 1064 m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_COMMENT, new String (chars, start, length)); 1065 } 1066 } 1067 1068 1069 1073 public void fireEndEntity(String name) 1074 throws org.xml.sax.SAXException 1075 { 1076 if (m_tracer != null) 1077 flushMyWriter(); 1078 } 1080 1081 1084 protected void fireStartDoc() 1085 throws org.xml.sax.SAXException 1086 { 1087 if (m_tracer != null) 1088 { 1089 flushMyWriter(); 1090 m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_STARTDOCUMENT); 1091 } 1092 } 1093 1094 1095 1098 protected void fireEndDoc() 1099 throws org.xml.sax.SAXException 1100 { 1101 if (m_tracer != null) 1102 { 1103 flushMyWriter(); 1104 m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_ENDDOCUMENT); 1105 } 1106 } 1107 1108 1115 protected void fireStartElem(String elemName) 1116 throws org.xml.sax.SAXException 1117 { 1118 if (m_tracer != null) 1119 { 1120 flushMyWriter(); 1121 m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_STARTELEMENT, 1122 elemName, m_attributes); 1123 } 1124 } 1125 1126 1127 1131 1138 1139 1143 protected void fireEscapingEvent(String name, String data) 1144 throws org.xml.sax.SAXException 1145 { 1146 1147 if (m_tracer != null) 1148 { 1149 flushMyWriter(); 1150 m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_PI,name, data); 1151 } 1152 } 1153 1154 1155 1159 protected void fireEntityReference(String name) 1160 throws org.xml.sax.SAXException 1161 { 1162 if (m_tracer != null) 1163 { 1164 flushMyWriter(); 1165 m_tracer.fireGenerateEvent(SerializerTrace.EVENTTYPE_ENTITYREF,name, (Attributes )null); 1166 } 1167 } 1168 1169 1183 public void startDocument() throws org.xml.sax.SAXException 1184 { 1185 1186 startDocumentInternal(); 1188 m_needToCallStartDocument = false; 1189 return; 1190 } 1191 1192 1208 protected void startDocumentInternal() throws org.xml.sax.SAXException 1209 { 1210 if (m_tracer != null) 1211 this.fireStartDoc(); 1212 } 1213 1220 public void setSourceLocator(SourceLocator locator) 1221 { 1222 m_sourceLocator = locator; 1223 } 1224 1225 1226 1232 public void setNamespaceMappings(NamespaceMappings mappings) { 1233 m_prefixMap = mappings; 1234 } 1235 1236 public boolean reset() 1237 { 1238 resetSerializerBase(); 1239 return true; 1240 } 1241 1242 1246 private void resetSerializerBase() 1247 { 1248 this.m_attributes.clear(); 1249 this.m_cdataSectionElements = null; 1250 this.m_elemContext = new ElemContext(); 1251 this.m_doctypePublic = null; 1252 this.m_doctypeSystem = null; 1253 this.m_doIndent = false; 1254 this.m_encoding = null; 1255 this.m_indentAmount = 0; 1256 this.m_inEntityRef = false; 1257 this.m_inExternalDTD = false; 1258 this.m_mediatype = null; 1259 this.m_needToCallStartDocument = true; 1260 this.m_needToOutputDocTypeDecl = false; 1261 if (this.m_prefixMap != null) 1262 this.m_prefixMap.reset(); 1263 this.m_shouldNotWriteXMLHeader = false; 1264 this.m_sourceLocator = null; 1265 this.m_standalone = null; 1266 this.m_standaloneWasSpecified = false; 1267 this.m_tracer = null; 1268 this.m_transformer = null; 1269 this.m_version = null; 1270 } 1273 1274} 1275 | Popular Tags |