1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xerces" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, International
  53. * Business Machines, Inc., http://www.apache.org. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package com.sun.org.apache.xerces.internal.util;
  58. import com.sun.org.apache.xerces.internal.impl.xs.util.SimpleLocator;
  59. import com.sun.org.apache.xerces.internal.jaxp.validation.WrappedSAXException;
  60. import com.sun.org.apache.xerces.internal.xni.QName;
  61. import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
  62. import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
  63. import com.sun.org.apache.xerces.internal.xni.XMLLocator;
  64. import com.sun.org.apache.xerces.internal.xni.XMLString;
  65. import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
  66. import org.xml.sax.Attributes;
  67. import org.xml.sax.ContentHandler;
  68. import org.xml.sax.Locator;
  69. import org.xml.sax.SAXException;
  70. /**
  71. * Receves SAX {@link ContentHandler} events
  72. * and produces the equivalent {@link XMLDocumentHandler} events.
  73. *
  74. * @author
  75. * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
  76. */
  77. public class SAX2XNI implements ContentHandler, XMLDocumentSource {
  78. public SAX2XNI( XMLDocumentHandler core ) {
  79. this.fCore = core;
  80. }
  81. private XMLDocumentHandler fCore;
  82. private final NamespaceSupport nsContext = new NamespaceSupport();
  83. private final SymbolTable symbolTable = new SymbolTable();
  84. public void setDocumentHandler(XMLDocumentHandler handler) {
  85. fCore = handler;
  86. }
  87. public XMLDocumentHandler getDocumentHandler() {
  88. return fCore;
  89. }
  90. //
  91. //
  92. // ContentHandler implementation
  93. //
  94. //
  95. public void startDocument() throws SAXException {
  96. try {
  97. nsContext.reset();
  98. XMLLocator xmlLocator;
  99. if(locator==null)
  100. // some SAX source doesn't provide a locator,
  101. // in which case we assume no line information is available
  102. // and use a dummy locator. With this, downstream components
  103. // can always assume that they will get a non-null Locator.
  104. xmlLocator=new SimpleLocator(null,null,-1,-1);
  105. else
  106. xmlLocator=new LocatorWrapper(locator);
  107. fCore.startDocument(
  108. xmlLocator,
  109. null,
  110. nsContext,
  111. null);
  112. } catch( WrappedSAXException e ) {
  113. throw e.exception;
  114. }
  115. }
  116. public void endDocument() throws SAXException {
  117. try {
  118. fCore.endDocument(null);
  119. } catch( WrappedSAXException e ) {
  120. throw e.exception;
  121. }
  122. }
  123. public void startElement( String uri, String local, String qname, Attributes att ) throws SAXException {
  124. try {
  125. fCore.startElement(createQName(uri,local,qname),createAttributes(att),null);
  126. } catch( WrappedSAXException e ) {
  127. throw e.exception;
  128. }
  129. }
  130. public void endElement( String uri, String local, String qname ) throws SAXException {
  131. try {
  132. fCore.endElement(createQName(uri,local,qname),null);
  133. } catch( WrappedSAXException e ) {
  134. throw e.exception;
  135. }
  136. }
  137. public void characters( char[] buf, int offset, int len ) throws SAXException {
  138. try {
  139. fCore.characters(new XMLString(buf,offset,len),null);
  140. } catch( WrappedSAXException e ) {
  141. throw e.exception;
  142. }
  143. }
  144. public void ignorableWhitespace( char[] buf, int offset, int len ) throws SAXException {
  145. try {
  146. fCore.ignorableWhitespace(new XMLString(buf,offset,len),null);
  147. } catch( WrappedSAXException e ) {
  148. throw e.exception;
  149. }
  150. }
  151. public void startPrefixMapping( String prefix, String uri ) {
  152. nsContext.pushContext();
  153. nsContext.declarePrefix(prefix,uri);
  154. }
  155. public void endPrefixMapping( String prefix ) {
  156. nsContext.popContext();
  157. }
  158. public void processingInstruction( String target, String data ) throws SAXException {
  159. try {
  160. fCore.processingInstruction(
  161. symbolize(target),createXMLString(data),null);
  162. } catch( WrappedSAXException e ) {
  163. throw e.exception;
  164. }
  165. }
  166. public void skippedEntity( String name ) {
  167. }
  168. private Locator locator;
  169. public void setDocumentLocator( Locator _loc ) {
  170. this.locator = _loc;
  171. }
  172. /** Creates a QName object. */
  173. private QName createQName(String uri, String local, String raw) {
  174. int idx = raw.indexOf(':');
  175. if( local.length()==0 ) {
  176. // if naemspace processing is turned off, local could be "".
  177. // in that case, treat everything to be in the no namespace.
  178. uri = "";
  179. if(idx<0)
  180. local = raw;
  181. else
  182. local = raw.substring(idx+1);
  183. }
  184. String prefix;
  185. if (idx < 0)
  186. prefix = null;
  187. else
  188. prefix = raw.substring(0, idx);
  189. if (uri != null && uri.length() == 0)
  190. uri = null; // XNI uses null whereas SAX uses the empty string
  191. return new QName(symbolize(prefix), symbolize(local), symbolize(raw), symbolize(uri));
  192. }
  193. /** Symbolizes the specified string. */
  194. private String symbolize(String s) {
  195. if (s == null)
  196. return null;
  197. else
  198. return symbolTable.addSymbol(s);
  199. }
  200. private XMLString createXMLString(String str) {
  201. // with my patch
  202. // return new XMLString(str);
  203. // for now
  204. return new XMLString(str.toCharArray(), 0, str.length());
  205. }
  206. /** only one instance of XMLAttributes is used. */
  207. private final XMLAttributes xa = new XMLAttributesImpl();
  208. /** Creates an XMLAttributes object. */
  209. private XMLAttributes createAttributes(Attributes att) {
  210. xa.removeAllAttributes();
  211. int len = att.getLength();
  212. for (int i = 0; i < len; i++)
  213. xa.addAttribute(
  214. createQName(att.getURI(i), att.getLocalName(i), att.getQName(i)),
  215. att.getType(i),
  216. att.getValue(i));
  217. return xa;
  218. }
  219. }