1 22 package org.jboss.xb.util; 23 24 import java.util.List ; 25 import java.util.Collections ; 26 import java.util.ArrayList ; 27 import org.jboss.xb.binding.Constants; 28 import org.jboss.xb.binding.NamespaceRegistry; 29 import org.w3c.dom.Attr ; 30 import org.w3c.dom.Element ; 31 import org.w3c.dom.NamedNodeMap ; 32 import org.w3c.dom.NodeList ; 33 import org.w3c.dom.Node ; 34 import org.xml.sax.ContentHandler ; 35 import org.xml.sax.SAXException ; 36 import org.xml.sax.helpers.AttributesImpl ; 37 38 42 public class Dom2Sax 43 { 44 public static void dom2sax(Element e, ContentHandler ch) throws SAXException 45 { 46 if(e == null) 47 { 48 throw new IllegalArgumentException ("The element argument must not be null!"); 49 } 50 51 ch.startDocument(); 52 53 process(e, ch, new NamespaceRegistry()); 54 55 ch.endDocument(); 56 } 57 58 private static void process(Element e, ContentHandler ch, NamespaceRegistry nsReg) throws SAXException 59 { 60 AttributesImpl attrs = new AttributesImpl (); 61 62 List startedPrefixes = Collections.EMPTY_LIST; 63 64 NamedNodeMap domAttrs = e.getAttributes(); 65 if(domAttrs != null && domAttrs.getLength() > 0) 66 { 67 for(int i = 0; i < domAttrs.getLength(); ++i) 69 { 70 Attr attr = (Attr )domAttrs.item(i); 71 String attrNs = attr.getNamespaceURI(); 72 String attrLocal = attr.getLocalName(); 73 if(attrLocal == null) 74 { 75 attrLocal = attr.getNodeName(); 76 } 77 78 if(attrNs != null && isXmlns(attrNs)) 79 { 80 String prefix; 81 String attrPrefix; 82 if("xmlns".equals(attrLocal)) 83 { 84 prefix = ""; 85 attrPrefix = ""; 86 } 87 else 88 { 89 prefix = attrLocal; 90 attrPrefix = "xmlns"; 91 } 92 93 String attrVal = attr.getValue(); 94 nsReg.addPrefixMapping(prefix, attrVal); 95 ch.startPrefixMapping(prefix, attrVal); 96 startedPrefixes = add(startedPrefixes, prefix); 97 98 attrs.addAttribute(attrNs, attrLocal, buildQName(attrPrefix, attrLocal), null, attrVal); 99 } 100 } 101 102 for(int i = 0; i < domAttrs.getLength(); ++i) 103 { 104 Attr attr = (Attr )domAttrs.item(i); 105 String attrNs = attr.getNamespaceURI(); 106 String attrLocal = attr.getLocalName(); 107 if(attrLocal == null) 108 { 109 attrLocal = attr.getNodeName(); 110 } 111 112 if(attrNs == null) 113 { 114 attrNs = ""; 115 } 116 117 if(!isXmlns(attrNs)) 118 { 119 String prefix = nsReg.getPrefix(attrNs); 120 if(prefix == null && attrNs.length() > 0) 121 { 122 prefix = attrLocal + "_ns"; 123 nsReg.addPrefixMapping(prefix, attrNs); 124 ch.startPrefixMapping(prefix, attrNs); 125 startedPrefixes = add(startedPrefixes, prefix); 126 attrs.addAttribute(Constants.NS_XML_SCHEMA, prefix, "xmlns:" + prefix, null, attrNs); 127 } 128 129 attrs.addAttribute(attrNs, attrLocal, buildQName(prefix, attrLocal), null, attr.getValue()); 130 } 131 } 132 } 133 134 String localName = e.getLocalName(); 135 if(localName == null) 136 { 137 localName = e.getNodeName(); 138 } 139 140 String ns = e.getNamespaceURI(); 141 if(ns == null) 142 { 143 ns = ""; 144 } 145 146 String prefix = nsReg.getPrefix(ns); 147 if(prefix == null && ns.length() > 0) 148 { 149 prefix = localName + "_ns"; 150 nsReg.addPrefixMapping(prefix, ns); 151 ch.startPrefixMapping(prefix, ns); 152 startedPrefixes = add(startedPrefixes, prefix); 153 attrs.addAttribute(Constants.NS_XML_SCHEMA, prefix, "xmlns:" + prefix, null, ns); 154 } 155 156 String qName = buildQName(prefix, localName); 157 ch.startElement(ns, localName, qName, attrs); 158 159 NodeList childNodes = e.getChildNodes(); 160 if(childNodes != null && childNodes.getLength() > 0) 161 { 162 for(int i = 0; i < childNodes.getLength(); ++i) 163 { 164 Node node = childNodes.item(i); 165 switch(node.getNodeType()) 166 { 167 case Node.ELEMENT_NODE: 168 process((Element )node, ch, nsReg); 169 break; 170 case Node.CDATA_SECTION_NODE: 171 case Node.TEXT_NODE: 172 String value = node.getNodeValue(); 173 ch.characters(value.toCharArray(), 0, value.length()); 174 break; 175 case Node.ENTITY_REFERENCE_NODE: 176 String ref = '&' + node.getNodeName() + ';'; 177 ch.characters(ref.toCharArray(), 0, ref.length()); 178 break; 179 case Node.ENTITY_NODE: 180 ch.skippedEntity(node.getNodeName()); 181 break; 182 } 183 } 184 } 185 186 ch.endElement(ns, localName, qName); 187 188 if(startedPrefixes.size() > 0) 189 { 190 for(int i = startedPrefixes.size() - 1; i >= 0; --i) 191 { 192 String pref = (String )startedPrefixes.get(i); 193 nsReg.removePrefixMapping(pref); 194 ch.endPrefixMapping(pref); 195 } 196 } 197 } 198 199 private static boolean isXmlns(String ns) 200 { 201 return ns.startsWith("http://www.w3.org/2000/xmlns"); 202 } 203 204 private static String buildQName(String prefix, String localName) 205 { 206 return prefix == null || prefix.length() == 0 ? 207 localName : 208 prefix + ':' + localName; 209 } 210 211 private static List add(List list, Object o) 212 { 213 switch(list.size()) 214 { 215 case 0: 216 list = Collections.singletonList(o); 217 break; 218 case 1: 219 list = new ArrayList (list); 220 default: 221 list.add(o); 222 } 223 return list; 224 } 225 } 226 | Popular Tags |